Subversion Repositories Kolibri OS

Rev

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