Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. 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.