Subversion Repositories Kolibri OS

Rev

Rev 1161 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. ;driver sceletone
  9.  
  10. format MS COFF
  11.  
  12. API_VERSION     equ 0  ;debug
  13.  
  14. include '../proc32.inc'
  15. include '../imports.inc'
  16. include 'urb.inc'
  17.  
  18. struc UHCI
  19. {
  20.    .bus                dd ?
  21.    .devfn              dd ?
  22.    .io_base            dd ?
  23.    .mm_base            dd ?
  24.    .irq                dd ?
  25.    .flags              dd ?
  26.    .reset              dd ?
  27.    .start              dd ?
  28.    .stop               dd ?
  29.  
  30.    .port_c_suspend     dd ?
  31.    .resuming_ports     dd ?
  32.    .rh_state           dd ?
  33.    .rh_numports        dd ?
  34.    .is_stopped         dd ?
  35.    .dead               dd ?
  36.  
  37.    .sizeof:
  38. }
  39.  
  40. virtual at 0
  41.   UHCI UHCI
  42. end virtual
  43.  
  44. struc IOCTL
  45. {  .handle      dd ?
  46.    .io_code     dd ?
  47.    .input       dd ?
  48.    .inp_size    dd ?
  49.    .output      dd ?
  50.    .out_size    dd ?
  51. }
  52.  
  53. virtual at 0
  54.   IOCTL IOCTL
  55. end virtual
  56.  
  57. struc TD   ;transfer descriptor
  58. {
  59.    .link        dd ?
  60.    .status      dd ?
  61.    .token       dd ?
  62.    .buffer      dd ?
  63.  
  64.    .addr        dd ?
  65.    .frame       dd ?
  66.    .fd          dd ?
  67.    .bk          dd ?
  68.    .sizeof:
  69. }
  70.  
  71. virtual at 0
  72.   TD TD
  73. end virtual
  74.  
  75. public START
  76. public service_proc
  77. public version
  78.  
  79. DEBUG        equ 1
  80.  
  81. DRV_ENTRY    equ 1
  82. DRV_EXIT     equ -1
  83. STRIDE       equ 4      ;size of row in devices table
  84.  
  85. SRV_GETVERSION  equ 0
  86.  
  87. section '.flat' code readable align 16
  88.  
  89. proc START stdcall, state:dword
  90.  
  91.            cmp [state], 1
  92.            jne .exit
  93. .entry:
  94.  
  95.      if DEBUG
  96.            mov esi, msgInit
  97.            call SysMsgBoardStr
  98.      end if
  99.  
  100.            call init
  101.  
  102.            stdcall RegService, my_service, service_proc
  103.            ret
  104. .fail:
  105. .exit:
  106.            xor eax, eax
  107.            ret
  108. endp
  109.  
  110. handle     equ  IOCTL.handle
  111. io_code    equ  IOCTL.io_code
  112. input      equ  IOCTL.input
  113. inp_size   equ  IOCTL.inp_size
  114. output     equ  IOCTL.output
  115. out_size   equ  IOCTL.out_size
  116.  
  117. align 4
  118. proc service_proc stdcall, ioctl:dword
  119.  
  120.            mov ebx, [ioctl]
  121.            mov eax, [ebx+io_code]
  122.            cmp eax, SRV_GETVERSION
  123.            jne @F
  124.  
  125.            mov eax, [ebx+output]
  126.            cmp [ebx+out_size], 4
  127.            jne .fail
  128.            mov [eax], dword API_VERSION
  129.            xor eax, eax
  130.            ret
  131. @@:
  132. .fail:
  133.            or eax, -1
  134.            ret
  135. endp
  136.  
  137. restore   handle
  138. restore   io_code
  139. restore   input
  140. restore   inp_size
  141. restore   output
  142. restore   out_size
  143.  
  144. align 4
  145. proc detect
  146.            locals
  147.             last_bus   dd ?
  148.             bus        dd ?
  149.             devfn      dd ?
  150.            endl
  151.  
  152.            xor eax, eax
  153.            mov [bus], eax
  154.            inc eax
  155.            call PciApi
  156.            cmp eax, -1
  157.            je .err
  158.  
  159.            mov [last_bus], eax
  160.  
  161. .next_bus:
  162.            and [devfn], 0
  163. .next_dev:
  164.            stdcall PciRead32, [bus], [devfn], dword 0
  165.            test eax, eax
  166.            jz .next
  167.            cmp eax, -1
  168.            je .next
  169.  
  170.            mov edi, devices
  171. @@:
  172.            mov ebx, [edi]
  173.            test ebx, ebx
  174.            jz .next
  175.  
  176.            cmp eax, ebx
  177.            je .found
  178.  
  179.            add edi, STRIDE
  180.            jmp @B
  181. .next:
  182.            inc [devfn]
  183.            cmp [devfn], 256
  184.            jb  .next_dev
  185.            mov eax, [bus]
  186.            inc eax
  187.            mov [bus], eax
  188.            cmp eax, [last_bus]
  189.            jna .next_bus
  190.            xor eax, eax
  191.            ret
  192. .found:
  193.            mov eax, UHCI.sizeof
  194.            call Kmalloc
  195.            test eax, eax
  196.            jz .mem_fail
  197.  
  198.            mov ebx, [bus]
  199.            mov [eax+UHCI.bus], ebx
  200.  
  201.            mov ecx, [devfn]
  202.            mov [eax+UHCI.devfn], ecx
  203.            ret
  204. .mem_fail:
  205.      if DEBUG
  206.            mov esi, msgMemFail
  207.            call SysMsgBoardStr
  208.      end if
  209. .err:
  210.            xor eax, eax
  211.            ret
  212. endp
  213.  
  214. PCI_BASE    equ 0x20
  215. USB_LEGKEY  equ 0xC0
  216.  
  217. align 4
  218. proc init
  219.            locals
  220.             uhci       dd ?
  221.            endl
  222.  
  223.            call detect
  224.            test eax, eax
  225.            jz .fail
  226.  
  227.            mov [uhci], eax
  228.  
  229.            stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE
  230.            and eax, 0xFFC0
  231.            mov esi, [uhci]
  232.            mov [esi+UHCI.io_base], eax
  233.  
  234.            stdcall uhci_reset, esi
  235.  
  236.            stdcall finish_reset, [uhci]
  237.  
  238. .fail:
  239.      if DEBUG
  240.            mov esi, msgDevNotFound
  241.            call SysMsgBoardStr
  242.      end if
  243.            ret
  244. endp
  245.  
  246. UHCI_USBINTR            equ  4             ; interrupt register
  247.  
  248. UHCI_USBLEGSUP_RWC      equ  0x8f00        ; the R/WC bits
  249. UHCI_USBLEGSUP_RO       equ  0x5040        ; R/O and reserved bits
  250.  
  251. UHCI_USBCMD_RUN         equ  0x0001        ; RUN/STOP bit
  252. UHCI_USBCMD_HCRESET     equ  0x0002        ; Host Controller reset
  253. UHCI_USBCMD_EGSM        equ  0x0008        ; Global Suspend Mode
  254. UHCI_USBCMD_CONFIGURE   equ  0x0040        ; Config Flag
  255. UHCI_USBINTR_RESUME     equ  0x0002        ; Resume interrupt enable
  256.  
  257. PORTSC0                 equ  0x10
  258. PORTSC1                 equ  0x12
  259.  
  260.  
  261. UHCI_RH_RESET           equ  0
  262. UHCI_RH_SUSPENDED       equ  1
  263. UHCI_RH_AUTO_STOPPED    equ  2
  264. UHCI_RH_RESUMING        equ  3
  265.  
  266. ; In this state the HC changes from running to halted
  267. ; so it can legally appear either way.
  268. UHCI_RH_SUSPENDING      equ  4
  269.  
  270. ; In the following states it's an error if the HC is halted.
  271. ; These two must come last.
  272. UHCI_RH_RUNNING         equ 5  ; The normal state
  273. UHCI_RH_RUNNING_NODEVS  equ 6  ; Running with no devices
  274.  
  275. UHCI_IS_STOPPED         equ 9999
  276.  
  277. align 4
  278. proc uhci_reset stdcall, uhci:dword
  279.            mov esi, [uhci]
  280.            stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY
  281.            test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC)
  282.            jnz .reset
  283.  
  284.            mov edx, [esi+UHCI.io_base]
  285.            in ax, dx
  286.            test ax, UHCI_USBCMD_RUN
  287.            jnz .reset
  288.  
  289.            test ax, UHCI_USBCMD_CONFIGURE
  290.            jz .reset
  291.  
  292.            test ax, UHCI_USBCMD_EGSM
  293.            jz .reset
  294.  
  295.            add edx, UHCI_USBINTR
  296.            in ax, dx
  297.            test ax, not UHCI_USBINTR_RESUME
  298.            jnz .reset
  299.            ret
  300. .reset:
  301.            stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC
  302.  
  303.            mov edx, [esi+UHCI.io_base]
  304.            mov ax, UHCI_USBCMD_HCRESET
  305.            out dx, ax
  306.  
  307.            xor eax, eax
  308.            out dx, ax
  309.            add edx, UHCI_USBINTR
  310.            out dx, ax
  311.            ret
  312. endp
  313.  
  314. proc finish_reset stdcall, uhci:dword
  315.  
  316.            mov esi, [uhci]
  317.            mov edx, [esi+UHCI.io_base]
  318.            add edx, PORTSC0
  319.            xor eax, eax
  320.            out dx, ax
  321.            add edx, (PORTSC1-PORTSC0)
  322.            out dx, ax
  323.  
  324.            mov [esi+UHCI.port_c_suspend], eax
  325.            mov [esi+UHCI.resuming_ports], eax
  326.            mov [esi+UHCI.rh_state], UHCI_RH_RESET
  327.            mov [esi+UHCI.rh_numports], 2
  328.  
  329.            mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED
  330.      ;      mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
  331.      ;      uhci_to_hcd(uhci)->poll_rh = 0;
  332.  
  333.            mov [esi+UHCI.dead], eax  ; Full reset resurrects the controller
  334.  
  335.            ret
  336. endp
  337.  
  338. proc insert_td stdcall, td:dword, frame:dword
  339.  
  340.            mov edi, [td]
  341.            mov eax, [frame]
  342.            and eax, -1024
  343.            mov [edi+TD.frame], eax
  344.  
  345.            mov ebx, [framelist]
  346.            mov edx, [dma_framelist]
  347.            shl eax, 5
  348.  
  349.            mov ecx, [eax+ebx]
  350.            test ecx, ecx
  351.            jz .empty
  352.  
  353.            mov ecx, [ecx+TD.bk]               ;last TD
  354.  
  355.            mov edx, [ecx+TD.fd]
  356.            mov [edi+TD.fd], edx
  357.            mov [edi+TD.bk], ecx
  358.            mov [ecx+TD.fd], edi
  359.            mov [edx+TD.bk], edi
  360.  
  361.            mov eax, [ecx+TD.link]
  362.            mov [edi+TD.link], eax
  363.            mov ebx, [edi+TD.addr]
  364.            mov [ecx+TD.link], ebx
  365.            ret
  366. .empty:
  367.            mov ecx, [eax+edx]
  368.            mov [edi+TD.link], ecx
  369.            mov [ebx+eax], edi
  370.            mov ecx, [edi+TD.addr]
  371.            mov [eax+edx], ecx
  372.            ret
  373. endp
  374.  
  375.  
  376. align 4
  377. proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\
  378.                                  buf:dword, size:dword
  379.  
  380.            locals
  381.              count        dd ?
  382.            endl
  383.  
  384.            mov esi, [buf]
  385.            mov ecx, [size]
  386.            xor eax, eax
  387.            cld
  388.            rep stosb
  389.  
  390.            mov [count], 3
  391. @@:
  392.            mov eax, [type]
  393.            shl eax, 8
  394.            add eax, [index]
  395.            stdcall usb_control_msg, [dev],pipe,USB_REQ_GET_DESCRIPTOR,\
  396.                                     USB_DIR_IN, eax,0,[buf], [size],\
  397.                                     USB_CTRL_GET_TIMEOUT
  398.            test eax, eax
  399.            jz .next
  400.            cmp eax, -1
  401.            je .next
  402.            jmp. ok
  403. .next:
  404.            dec [count]
  405.            jnz @B
  406.            mov eax, -1
  407. .ok:
  408.            ret
  409. endp
  410.  
  411. DEVICE_ID    equ  0x24D2     ;  pci device id
  412. VENDOR_ID    equ  0x8086     ;  device vendor id
  413. QEMU_USB     equ  0x7020
  414.  
  415. ;all initialized data place here
  416.  
  417. align 4
  418. devices         dd (DEVICE_ID shl 16)+VENDOR_ID
  419.                 dd (QEMU_USB  shl 16)+VENDOR_ID
  420.                 dd 0      ;terminator
  421.  
  422. version         dd (5 shl 16) or (API_VERSION and 0xFFFF)
  423.  
  424. my_service      db 'UHCI',0  ;max 16 chars include zero
  425.  
  426. msgInit         db 'detect hardware...',13,10,0
  427. msgPCI          db 'PCI accsess not supported',13,10,0
  428. msgDevNotFound  db 'device not found',13,10,0
  429. msgMemFail      db 'Kmalloc failed', 10,10,0
  430. ;msgFail         db 'device not found',13,10,0
  431.  
  432. section '.data' data readable writable align 16
  433.  
  434. ;all uninitialized data place here
  435.  
  436.