Subversion Repositories Kolibri OS

Rev

Rev 5020 | Rev 5035 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. format MS COFF
  9.  
  10. DEBUG = 1
  11.  
  12. __DEBUG__ = 1
  13. __DEBUG_LEVEL__ = 1
  14.  
  15. node equ ftdi_context
  16. node.next equ ftdi_context.next_context
  17.  
  18. include '../../proc32.inc'
  19. include '../../imports.inc'
  20. include '../../fdo.inc'
  21. include '../../struct.inc'
  22.  
  23. public START
  24. public version
  25.  
  26. ; USB constants
  27. DEVICE_DESCR_TYPE           = 1
  28. CONFIG_DESCR_TYPE           = 2
  29. STRING_DESCR_TYPE           = 3
  30. INTERFACE_DESCR_TYPE        = 4
  31. ENDPOINT_DESCR_TYPE         = 5
  32. DEVICE_QUALIFIER_DESCR_TYPE = 6
  33.  
  34. CONTROL_PIPE     = 0
  35. ISOCHRONOUS_PIPE = 1
  36. BULK_PIPE        = 2
  37. INTERRUPT_PIPE   = 3
  38.  
  39. ; USB HID constants
  40. HID_DESCR_TYPE      = 21h
  41. REPORT_DESCR_TYPE   = 22h
  42. PHYSICAL_DESCR_TYPE = 23h
  43.  
  44.  
  45. ; LibUSB constatnts
  46. LIBUSB_REQUEST_TYPE_STANDARD = (0x00 shl 5)
  47. LIBUSB_REQUEST_TYPE_CLASS = (0x01 shl 5)
  48. LIBUSB_REQUEST_TYPE_VENDOR = (0x02 shl 5)
  49. LIBUSB_REQUEST_TYPE_RESERVED = (0x03 shl 5)
  50.  
  51. LIBUSB_RECIPIENT_DEVICE = 0x00
  52. LIBUSB_RECIPIENT_INTERFACE = 0x01
  53. LIBUSB_RECIPIENT_ENDPOINT = 0x02
  54. LIBUSB_RECIPIENT_OTHER = 0x03
  55.  
  56. LIBUSB_ENDPOINT_IN = 0x80
  57. LIBUSB_ENDPOINT_OUT = 0x00
  58.  
  59. ; FTDI Constants
  60. FTDI_DEVICE_OUT_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_OUT)
  61. FTDI_DEVICE_IN_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_IN)
  62.  
  63. ; Requests
  64. ;Definitions for flow control
  65. SIO_RESET         =0  ;Reset the port
  66. SIO_MODEM_CTRL    =1  ;Set the modem control register
  67. SIO_SET_FLOW_CTRL =2  ;Set flow control register
  68. SIO_SET_BAUD_RATE =3  ;Set baud rate
  69. SIO_SET_DATA      =4  ;Set the data characteristics of the port
  70.  
  71. SIO_RESET_REQUEST            =SIO_RESET
  72. SIO_SET_BAUDRATE_REQUEST     =SIO_SET_BAUD_RATE
  73. SIO_SET_DATA_REQUEST         =SIO_SET_DATA
  74. SIO_SET_FLOW_CTRL_REQUEST    =SIO_SET_FLOW_CTRL
  75. SIO_SET_MODEM_CTRL_REQUEST   =SIO_MODEM_CTRL
  76. SIO_POLL_MODEM_STATUS_REQUEST=0x05
  77. SIO_SET_EVENT_CHAR_REQUEST   =0x06
  78. SIO_SET_ERROR_CHAR_REQUEST   =0x07
  79. SIO_SET_LATENCY_TIMER_REQUEST=0x09
  80. SIO_GET_LATENCY_TIMER_REQUEST=0x0A
  81. SIO_SET_BITMODE_REQUEST      =0x0B
  82. SIO_READ_PINS_REQUEST        =0x0C
  83. SIO_READ_EEPROM_REQUEST      =0x90
  84. SIO_WRITE_EEPROM_REQUEST     =0x91
  85. SIO_ERASE_EEPROM_REQUEST     =0x92
  86.  
  87.  
  88. SIO_RESET_SIO=0
  89. SIO_RESET_PURGE_RX=1
  90. SIO_RESET_PURGE_TX=2
  91.  
  92. SIO_DISABLE_FLOW_CTRL=0x0
  93. SIO_RTS_CTS_HS =(0x1 shl 8)
  94. SIO_DTR_DSR_HS =(0x2 shl 8)
  95. SIO_XON_XOFF_HS=(0x4 shl 8)
  96.  
  97. SIO_SET_DTR_MASK=0x1
  98. SIO_SET_DTR_HIGH=( 1 or ( SIO_SET_DTR_MASK  shl 8))
  99. SIO_SET_DTR_LOW =( 0 or ( SIO_SET_DTR_MASK  shl 8))
  100. SIO_SET_RTS_MASK=0x2
  101. SIO_SET_RTS_HIGH=( 2 or ( SIO_SET_RTS_MASK shl 8 ))
  102. SIO_SET_RTS_LOW =( 0 or ( SIO_SET_RTS_MASK shl 8 ))
  103.  
  104. SIO_RTS_CTS_HS =(0x1 shl 8)
  105.  
  106. ;FTDI chip type
  107. TYPE_AM=0
  108. TYPE_BM=1
  109. TYPE_2232C=2
  110. TYPE_R=3
  111. TYPE_2232H=4
  112. TYPE_4232H=5
  113. TYPE_232H=6
  114. TYPE_230X=7
  115.  
  116. ;strings
  117. my_driver       db      'usbother',0
  118. nomemory_msg    db      'K : no memory',13,10,0
  119.  
  120. ; Structures
  121. struct ftdi_context
  122. chipType                db      ?
  123. baudrate                dd      ?
  124. bitbangEnabled          db      ?
  125. readBufChunkSize        dd      ?
  126. writeBufChunkSize       dd      ?
  127. readBufPtr              dd      ?
  128. writeBufPtr             dd      ?
  129. readBufSize             dd      ?
  130. writeBufSize            dd      ?
  131. maxPacketSize           dd      ?
  132. interface               dd      ?
  133. index                   dd      ?
  134. inEP                    dd      ?
  135. outEP                   dd      ?
  136. nullP                   dd      ?
  137. lockPID                 dd      ?
  138. next_context            dd      ?
  139. ends
  140.  
  141. struct IOCTL
  142. handle                  dd      ?
  143. io_code                 dd      ?
  144. input                   dd      ?
  145. inp_size                dd      ?
  146. output                  dd      ?
  147. out_size                dd      ?
  148. ends
  149.  
  150. struct usb_descr
  151. bLength                 db      ?
  152. bDescriptorType         db      ?
  153. bcdUSB                  dw      ?
  154. bDeviceClass            db      ?
  155. bDeviceSubClass         db      ?
  156. bDeviceProtocol         db      ?
  157. bMaxPacketSize0         db      ?
  158. idVendor                dw      ?
  159. idProduct               dw      ?
  160. bcdDevice               dw      ?
  161. iManufacturer           db      ?
  162. iProduct                db      ?
  163. iSerialNumber           db      ?
  164. bNumConfigurations      db      ?
  165. ends
  166.  
  167. struct conf_packet
  168. bmRequestType           db      ?
  169. bRequest                db      ?
  170. wValue                  dw      ?
  171. wIndex                  dw      ?
  172. wLength                 dw      ?
  173. ends
  174.  
  175. section '.flat' code readable align 16
  176. ; The start procedure.
  177. proc START stdcall, .reason:DWORD
  178.  
  179.         xor     eax, eax        ; initialize return value
  180.         cmp     [.reason], 1    ; compare the argument
  181.         jnz     .nothing                
  182.         stdcall RegUSBDriver, my_driver, service_proc, usb_functions
  183.  
  184. .nothing:
  185.         ret
  186. endp
  187.  
  188.  
  189. proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
  190.        
  191.         stdcall USBGetParam, [.config_pipe], 0
  192.         mov     edx, eax
  193.         DEBUGF 1,'K : Detected device vendor: %x\n', [eax+usb_descr.idVendor]
  194.         cmp     word[eax+usb_descr.idVendor], 0x0403
  195.         jnz     .notftdi
  196.         mov     eax, sizeof.ftdi_context
  197.         call    Kmalloc
  198.         test    eax, eax
  199.         jnz     @f
  200.         mov     esi, nomemory_msg
  201.         call    SysMsgBoardStr
  202.         jmp     .nothing
  203.   @@:
  204.         DEBUGF 1,'K : Adding struct to list %x\n', eax
  205.         call    linkedlist_add
  206.        
  207.         mov     ebx, [.config_pipe]
  208.         mov     [eax + ftdi_context.nullP], ebx
  209.         mov     [eax + ftdi_context.index], 0
  210.         mov     [eax + ftdi_context.lockPID], 0
  211.         mov     [eax + ftdi_context.maxPacketSize], 64      
  212.         mov     [eax + ftdi_context.readBufChunkSize], 64
  213.         mov     [eax + ftdi_context.writeBufChunkSize], 64
  214.  
  215.         mov     [eax + ftdi_context.chipType], TYPE_R
  216.         jmp     .slow
  217.        
  218.         mov     cx, [edx+usb_descr.bcdDevice]
  219.         DEBUGF 1, 'K : Chip type %x\n', ecx
  220.         cmp     cx, 0x400
  221.         jnz     @f
  222.         mov     [eax + ftdi_context.chipType], TYPE_BM
  223.         jmp     .slow
  224.   @@:      
  225.         cmp     cx, 0x200
  226.         jnz     @f
  227.         mov     [eax + ftdi_context.chipType], TYPE_AM
  228.         jmp     .slow
  229.   @@:    
  230.         cmp     cx, 0x500
  231.         jnz     @f
  232.         mov     [eax + ftdi_context.chipType], TYPE_2232C
  233.         jmp     .slow
  234.   @@:      
  235.         cmp     cx, 0x600
  236.         jnz     @f
  237.         mov     [eax + ftdi_context.chipType], TYPE_R
  238.         jmp     .slow
  239.   @@:      
  240.         cmp     cx, 0x700
  241.         jnz     @f
  242.         mov     [eax + ftdi_context.chipType], TYPE_2232H
  243.         jmp     .fast
  244.   @@:      
  245.         cmp     cx, 0x900
  246.         jnz     @f
  247.         mov     [eax + ftdi_context.chipType], TYPE_232H
  248.         jmp     .fast
  249.   @@:      
  250.         cmp     cx, 0x1000
  251.         jnz     .slow
  252.         mov     [eax + ftdi_context.chipType], TYPE_230X
  253.         jmp     .fast
  254.        
  255.   .fast:
  256.         add     [eax + ftdi_context.maxPacketSize], 512-64
  257.   .slow:    
  258.         mov     ebx, eax
  259.         stdcall USBOpenPipe, [.config_pipe],  0x81,  [ebx + ftdi_context.maxPacketSize],  BULK_PIPE, 0
  260.         test    eax, eax
  261.         jz      .nothing
  262.         mov     [ebx + ftdi_context.outEP], eax
  263.         stdcall USBOpenPipe, [.config_pipe],  0x02,  [ebx + ftdi_context.maxPacketSize],  BULK_PIPE, 0
  264.         test    eax, eax
  265.         jz      .nothing
  266.         mov     [ebx + ftdi_context.inEP], eax
  267.         mov     eax, ebx
  268.         ret        
  269.            
  270.   .notftdi:
  271.         DEBUGF 1,'K : Skipping not FTDI device\n'
  272.   .nothing:        
  273.         xor     eax, eax
  274.         ret
  275. endp
  276.  
  277.  
  278. handle     equ  IOCTL.handle
  279. io_code    equ  IOCTL.io_code
  280. input      equ  IOCTL.input
  281. inp_size   equ  IOCTL.inp_size
  282. output     equ  IOCTL.output
  283. out_size   equ  IOCTL.out_size
  284.  
  285. align 4
  286. proc service_proc stdcall uses ebx esi edi, ioctl:DWORD
  287. locals
  288. ConfPacket  rb  8
  289. EventData   rd  3
  290. endl
  291.         mov     edi, [ioctl]
  292.         mov     eax, [edi+io_code]
  293.         DEBUGF 1,'K : FTDI got the request: %d\n', eax
  294.         test    eax, eax           ;0
  295.         jz      .version
  296.         dec     eax                 ;1
  297.         jz      .ftdi_get_list
  298.        
  299.         push    eax
  300.         mov     esi, [edi+input]
  301.         mov     eax, [esi+4]
  302.         call    linkedlist_isvalid
  303.         test    eax, eax
  304.         pop     eax        
  305.         jnz     .endswitch
  306.        
  307.         dec     eax
  308.         jz      .ftdi_lock      ;2
  309.         dec     eax
  310.         jz      .ftdi_unlock    ;3
  311.        
  312.         mov     ebx, [esi+4]
  313.         mov     ecx, [ebx + ftdi_context.lockPID]    
  314.         cmp     ecx, [esi]
  315.         jz      .pid_ok
  316.         mov     esi, [edi+output]
  317.         mov     dword[esi], 'LCKD'
  318.         jmp     .endswitch
  319.        
  320.   .pid_ok:
  321.         dec     eax
  322.         jz      .ftdi_get_wchunksize    ;4
  323.         dec     eax
  324.         jz      .ftdi_get_rchunksize    ;5        
  325.        
  326.         mov     edi, [edi+input]
  327.        
  328.         dec     eax
  329.         jz      .ftdi_set_rchunksize    ;6
  330.         dec     eax
  331.         jz      .ftdi_set_wchunksize    ;7
  332.  
  333.         push    eax edi
  334.         mov     ecx, 0x80000000
  335.         cmp     eax, 8-7
  336.         je      .bulkevent
  337.         cmp     eax, 9-7
  338.         je      .bulkevent
  339.         xor     ecx, ecx
  340.   .bulkevent:                
  341.         xor     esi, esi
  342.         call    CreateEvent        
  343.         mov     [EventData], eax
  344.         mov     [EventData+4], edx
  345.         pop     edi eax
  346.        
  347.         dec     eax                 ;8
  348.         jz      .ftdi_write_data
  349.         dec     eax                 ;9
  350.         jz      .ftdi_read_data
  351.         dec     eax                 ;10
  352.         jz      .ftdi_set_baudrate
  353.         dec     eax                 ;11
  354.         jz      .ftdi_set_bitmode
  355.         dec     eax                 ;12
  356.         jz      .ftdi_setrtshigh  
  357.         dec     eax                 ;13
  358.         jz      .ftdi_setrtslow  
  359.         dec     eax                 ;14
  360.         jz      .ftdi_setdtrhigh
  361.         dec     eax                 ;15
  362.         jz      .ftdi_setdtrlow
  363.         dec     eax                 ;16
  364.         jz      .ftdi_usb_reset
  365.         dec     eax                 ;17
  366.         jz      .ftdi_setflowctrl
  367.         dec     eax                 ;18
  368.         jz      .ftdi_set_event_char
  369.         dec     eax                 ;19
  370.         jz      .ftdi_set_error_char
  371.         dec     eax                 ;20
  372.         jz      .ftdi_set_latency_timer
  373.         dec     eax                 ;21
  374.         jz      .ftdi_get_latency_timer
  375.         dec     eax                 ;22
  376.         jz      .ftdi_read_pins
  377.         dec     eax                 ;23
  378.         jz      .ftdi_poll_modem_status        
  379.         dec     eax                 ;24
  380.         jz      .ftdi_set_line_property
  381.         dec     eax                 ;25
  382.         jz      .ftdi_purge_rx_buf
  383.         dec     eax                 ;26
  384.         jz      .ftdi_purge_tx_buf
  385.         jmp     .error
  386.                  
  387.   .version:    
  388.         jmp     .endswitch
  389.   .error:
  390.         mov     esi, [edi+output]
  391.         mov     [esi], dword 'ERR0'
  392.         or      [esi], eax
  393.   .endswitch:
  394.         xor     eax, eax
  395.             ret
  396.        
  397.   .eventdestroy:
  398.         ;---Dirty hack begin
  399.         test    eax, eax
  400.         jz      @f
  401.         mov     eax, dword[ConfPacket]
  402.         call    Kfree
  403.   @@:
  404.         ;---Dirty hack end
  405.         mov     eax, [EventData]
  406.         mov     ebx, [EventData+4]
  407.         call    DestroyEvent
  408.         jmp     .endswitch
  409.        
  410.   .ftdi_out_control_transfer_withinp:              
  411.         mov     dx, word[edi+8]                
  412.         mov     word[ConfPacket+2], dx
  413.   .ftdi_out_control_transfer_noinp:
  414.         mov     ebx, [edi+4]
  415.         mov     cx, word[ebx + ftdi_context.index]
  416.         mov     word[ConfPacket+4], cx
  417.         xor     cx, cx
  418.         mov     word[ConfPacket+6], cx
  419.   .own_index:
  420.         mov     ebx, [edi+4]
  421.         DEBUGF 1,'K : ConfPacket %x %x\n', [ConfPacket], [ConfPacket+4]          
  422.         lea     esi, [ConfPacket]
  423.         lea     edi, [EventData]        
  424.         stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, 0, 0, control_callback, edi, 0
  425.         test    eax, eax        
  426.         jz      .error
  427.         mov     eax, [EventData]
  428.         mov     ebx, [EventData+4]
  429.         call    WaitEvent    
  430.         jmp     .endswitch
  431.        
  432.   .ftdi_setrtshigh:
  433.         DEBUGF 1,'K : FTDI Setting RTS pin HIGH\n'                    
  434.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_HIGH shl 16)
  435.         jmp     .ftdi_out_control_transfer_noinp        
  436.  
  437.   .ftdi_setrtslow:
  438.         DEBUGF 1,'K : FTDI Setting RTS pin LOW\n'            
  439.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_LOW shl 16)
  440.         jmp     .ftdi_out_control_transfer_noinp          
  441.        
  442.   .ftdi_setdtrhigh:
  443.         DEBUGF 1,'K : FTDI Setting DTR pin HIGH\n'                    
  444.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_HIGH shl 16)
  445.         jmp     .ftdi_out_control_transfer_noinp          
  446.  
  447.   .ftdi_setdtrlow:
  448.         DEBUGF 1,'K : FTDI Setting DTR pin LOW\n'            
  449.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_LOW shl 16)
  450.         jmp     .ftdi_out_control_transfer_noinp          
  451.        
  452.   .ftdi_usb_reset:
  453.         DEBUGF 1,'K : FTDI Reseting\n'
  454.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_SIO shl 16)
  455.         jmp     .ftdi_out_control_transfer_noinp  
  456.        
  457.   .ftdi_purge_rx_buf:
  458.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_RX shl 16)
  459.         jmp     .ftdi_out_control_transfer_noinp  
  460.        
  461.   .ftdi_purge_tx_buf:
  462.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_TX shl 16)
  463.         jmp     .ftdi_out_control_transfer_noinp  
  464.        
  465.   .ftdi_set_bitmode:
  466.         DEBUGF 1,'K : FTDI Seting bitmode\n'                  
  467.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BITMODE_REQUEST shl 8)                                      
  468.         jmp     .ftdi_out_control_transfer_withinp        
  469.      
  470.   .ftdi_set_line_property:
  471.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_DATA_REQUEST shl 8)
  472.         jmp     .ftdi_out_control_transfer_withinp
  473.        
  474.   .ftdi_set_latency_timer:
  475.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_LATENCY_TIMER_REQUEST shl 8)        
  476.         jmp     .ftdi_out_control_transfer_withinp
  477.        
  478.   .ftdi_set_event_char:
  479.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_EVENT_CHAR_REQUEST shl 8)
  480.         jmp     .ftdi_out_control_transfer_withinp
  481.  
  482.   .ftdi_set_error_char:
  483.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_ERROR_CHAR_REQUEST shl 8)
  484.         jmp     .ftdi_out_control_transfer_withinp
  485.        
  486.   .ftdi_setflowctrl:
  487.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_FLOW_CTRL_REQUEST shl 8) + (0 shl 16)
  488.         mov     ebx, [edi+4]
  489.         mov     cx, word[edi+8]  
  490.         or      ecx, [ebx + ftdi_context.index]
  491.         mov     word[ConfPacket+4], cx
  492.         xor     cx, cx
  493.         mov     word[ConfPacket+6], cx
  494.         jmp     .own_index
  495.  
  496.   .ftdi_read_pins:                            
  497.         mov     ebx, [edi]
  498.         mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_READ_PINS_REQUEST shl 8) + (0 shl 16)
  499.         mov     ecx, [ebx + ftdi_context.index]
  500.         mov     word[ConfPacket+4], cx
  501.         mov     word[ConfPacket+6], 1
  502.         lea     esi, [ConfPacket]
  503.         lea     edi, [EventData]
  504.         mov     ecx, [ioctl]
  505.         mov     ecx, [ecx+output]
  506.         stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 1, control_callback, edi, 0
  507.         mov     eax, [EventData]
  508.         mov     ebx, [EventData+4]
  509.         call    WaitEvent    
  510.         jmp     .endswitch
  511.        
  512.   .ftdi_set_wchunksize:
  513.         mov     ebx, [edi+4]
  514.         mov     ecx, [edi+8]
  515.         cmp     [ebx + ftdi_context.maxPacketSize], ecx
  516.         jg      .error
  517.         mov     [ebx + ftdi_context.writeBufChunkSize], ecx
  518.         jmp     .endswitch
  519.    
  520.   .ftdi_get_wchunksize:
  521.         mov     esi, [edi+output]
  522.         mov     edi, [edi+input]
  523.         mov     ebx, [edi+4]
  524.         mov     ecx, [ebx + ftdi_context.writeBufChunkSize]
  525.         mov     [esi], ecx
  526.         jmp     .endswitch
  527.  
  528.   .ftdi_set_rchunksize:
  529.         mov     ebx, [edi+4]
  530.         mov     ecx, [edi+8]
  531.         cmp     [ebx + ftdi_context.maxPacketSize], ecx
  532.         jg      .error
  533.         mov     [ebx + ftdi_context.readBufChunkSize], ecx
  534.         jmp     .endswitch
  535.  
  536.   .ftdi_get_rchunksize:
  537.         mov     esi, [edi+output]
  538.         mov     edi, [edi+input]
  539.         mov     ebx, [edi+4]
  540.         mov     ecx, [ebx + ftdi_context.readBufChunkSize]
  541.         mov     [esi], ecx
  542.         jmp     .endswitch        
  543.  
  544.   .ftdi_write_data:
  545.         mov     esi, edi
  546.         add     esi, 12        
  547.         mov     ebx, [edi+4]
  548.         ;---Dirty hack begin
  549.         mov     eax, [edi+8]
  550.         call    Kmalloc
  551.         test    eax, eax
  552.         jnz     @f
  553.         mov     esi, nomemory_msg
  554.         call    SysMsgBoardStr
  555.         jmp     .eventdestroy
  556.   @@:
  557.         mov     dword[ConfPacket], eax
  558.         mov     ecx, [edi+8]
  559.         push    edi esi
  560.         mov     edi, eax
  561.         rep movsb
  562.         pop     esi edi
  563.         ;---Dirty hack end
  564.         xor     ecx, ecx        ; ecx - offset      
  565.   .write_loop:
  566.         mov     edx, [edi+8]    ; edx - write_size
  567.         sub     edx, ecx
  568.         cmp     edx, [ebx + ftdi_context.writeBufChunkSize]
  569.         jle     .lessthanchunk_write
  570.         mov     edx, [ebx + ftdi_context.writeBufChunkSize]
  571.   .lessthanchunk_write:
  572.         add     esi, ecx
  573.         lea     eax, [EventData]
  574.         push    ecx ebx esi edi
  575.         stdcall USBNormalTransferAsync, [ebx + ftdi_context.inEP], esi, edx, bulk_callback, eax, 1        
  576.         mov     eax, [EventData]
  577.         mov     ebx, [EventData+4]
  578.         call    WaitEvent
  579.         mov     eax, [EventData]
  580.         mov     ebx, [EventData+4]        
  581.         call    ClearEvent
  582.         pop     edi esi ebx ecx
  583.         cmp     [EventData+8], -1
  584.         jz      .error
  585.         add     ecx, [EventData+8]
  586.         cmp     ecx, [edi+8]
  587.         jge     .eventdestroy
  588.         jmp     .write_loop
  589.        
  590.   .ftdi_read_data:
  591.         mov     edi, [ioctl]
  592.         mov     esi, [edi+input]
  593.         mov     edi, [edi+output]
  594.         mov     ebx, [esi+4]                
  595.         ;---Dirty hack begin
  596.         mov     eax, [esi+8]
  597.         call    Kmalloc
  598.         test    eax, eax
  599.         jnz     @f
  600.         mov     esi, nomemory_msg
  601.         call    SysMsgBoardStr
  602.         jmp     .eventdestroy
  603.   @@:
  604.         mov     edi, eax
  605.         mov     dword[ConfPacket], eax
  606.         ;---Dirty hack end        
  607.         xor     ecx, ecx
  608.   .read_loop:
  609.         mov     edx, [esi+8]
  610.         cmp     ecx, edx
  611.         jge     .read_end;jge     .eventdestroy ;part of Dirty hack
  612.         sub     edx, ecx
  613.         cmp     edx, [ebx + ftdi_context.readBufChunkSize]
  614.         jl      .lessthanchunk_read
  615.         mov     edx, [ebx + ftdi_context.readBufChunkSize]    
  616.   .lessthanchunk_read:
  617.         lea     eax, [EventData]
  618.         add     edi, ecx
  619.         push    esi edi ecx ebx
  620.         stdcall USBNormalTransferAsync, [ebx + ftdi_context.outEP], edi, edx, bulk_callback, eax, 1        
  621.         mov     eax, [EventData]
  622.         mov     ebx, [EventData+4]        
  623.         call    WaitEvent
  624.         mov     eax, [EventData]
  625.         mov     ebx, [EventData+4]        
  626.         call    ClearEvent
  627.         pop     ebx ecx edi esi
  628.         cmp     [EventData+8], -1        
  629.         jz      .error
  630.         add     ecx, [EventData+8]
  631.         jmp     .read_loop
  632.         ;---Dirty hack begin        
  633.   .read_end:
  634.         mov     esi, dword[ConfPacket]
  635.         mov     edi, [ioctl]
  636.         mov     ecx, [edi+input]
  637.         mov     ecx, [ecx+8]
  638.         mov     edi, [edi+output]
  639.         rep     movsb
  640.         jmp     .eventdestroy
  641.         ;---Dirty hack end
  642.        
  643.   .ftdi_poll_modem_status:                                
  644.         mov     ebx, [edi+4]
  645.         mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_POLL_MODEM_STATUS_REQUEST shl 8) + (0 shl 16)
  646.         mov     ecx, [ebx + ftdi_context.index]
  647.         mov     word[ConfPacket+4], cx
  648.         mov     word[ConfPacket+6], 1
  649.         lea     esi, [ConfPacket]
  650.         lea     edi, [EventData]
  651.         mov     ecx, [ioctl]
  652.         mov     ecx, [ecx+output]
  653.         stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 2, control_callback, edi, 0
  654.         mov     eax, [EventData]
  655.         mov     ebx, [EventData+4]
  656.         call    WaitEvent
  657.         mov     ax, word[ecx]
  658.         xchg    ah, al
  659.         and     ah, 0xFF
  660.         mov     word[ecx], ax
  661.         jmp     .endswitch
  662.        
  663.   .ftdi_get_latency_timer:                                
  664.         mov     ebx, [edi+4]
  665.         mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_GET_LATENCY_TIMER_REQUEST shl 8) + (0 shl 16)
  666.         mov     ecx, [ebx + ftdi_context.index]
  667.         mov     word[ConfPacket+4], cx
  668.         mov     word[ConfPacket+6], 1
  669.         lea     esi, [ConfPacket]
  670.         lea     edi, [EventData]
  671.         mov     ecx, [ioctl]
  672.         mov     ecx, [ecx+output]
  673.         stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 2, control_callback, edi, 0
  674.         mov     eax, [EventData]
  675.         mov     ebx, [EventData+4]
  676.         call    WaitEvent
  677.         jmp     .endswitch
  678.                
  679.   .ftdi_get_list:
  680.         call    linkedlist_gethead
  681.         test    eax, eax
  682.         jz      .endswitch                        
  683.         mov     edi, [edi+output]
  684.         push    edi
  685.         add     edi, 4
  686.         xor     ecx, ecx
  687.   .nextdev:
  688.         inc     ecx
  689.         cmp     [eax + ftdi_context.lockPID], 0
  690.         jnz      .dev_is_locked        
  691.         mov     dword[edi], 'NLKD'
  692.         jmp     .nextfields
  693.   .dev_is_locked:
  694.         mov     dword[edi], 'LCKD'
  695.   .nextfields:
  696.         mov     bl, [eax + ftdi_context.chipType]
  697.         mov     [edi+4], ebx
  698.         mov     [edi+8], eax
  699.         add     edi, 12
  700.         mov     eax, [eax + ftdi_context.next_context]
  701.         test    eax, eax
  702.         jnz     .nextdev
  703.         pop     edi
  704.         mov     [edi], ecx
  705.         jmp     .endswitch
  706.                    
  707.   .ftdi_lock:
  708.         DEBUGF 1, 'K : FTDI lock attempt\n'
  709.         mov     esi, [edi+input]
  710.         mov     ebx, [esi+4]
  711.         mov     eax, [ebx + ftdi_context.lockPID]
  712.         test    eax, eax
  713.         jnz     .lockedby
  714.         DEBUGF 1, 'K : Lock success\n'
  715.         mov     eax, [esi]
  716.         mov     [ebx + ftdi_context.lockPID], eax
  717.   .lockedby:
  718.         mov     edi, [edi+output]
  719.         mov     [edi], eax
  720.         jmp     .endswitch
  721.        
  722.   .ftdi_unlock:
  723.         mov     esi, [edi+input]
  724.         mov     edi, [edi+output]
  725.         mov     ebx, [esi+4]
  726.         mov     eax, [ebx + ftdi_context.lockPID]
  727.         cmp     eax, [esi]
  728.         jnz     .unlockimp
  729.         mov     [ebx + ftdi_context.lockPID], 0
  730.         mov     dword[edi], 0
  731.         jmp     .endswitch  
  732.   .unlockimp:    
  733.         mov     [edi], eax
  734.         jmp     .endswitch
  735.  
  736. H_CLK = 120000000
  737. C_CLK = 48000000        
  738.   .ftdi_set_baudrate:
  739.         mov     ebx, [edi+4]
  740.         cmp     [ebx + ftdi_context.chipType], TYPE_2232H
  741.         jl      .c_clk        
  742.         imul    eax, [edi+8], 10
  743.         cmp     eax, H_CLK / 0x3FFF        
  744.         jle     .c_clk
  745.   .h_clk:
  746.         cmp     dword[edi+8], H_CLK/10
  747.         jl      .h_nextbaud1
  748.         xor     edx, edx
  749.         mov     ecx, H_CLK/10
  750.         jmp     .calcend
  751.        
  752.   .c_clk:
  753.         cmp     dword[edi+8], C_CLK/16
  754.         jl      .c_nextbaud1
  755.         xor     edx, edx
  756.         mov     ecx, C_CLK/16
  757.         jmp     .calcend  
  758.  
  759.   .h_nextbaud1:
  760.         cmp     dword[edi+8], H_CLK/(10 + 10/2)
  761.         jl      .h_nextbaud2
  762.         mov     edx, 1
  763.         mov     ecx, H_CLK/(10 + 10/2)
  764.         jmp     .calcend
  765.        
  766.   .c_nextbaud1:
  767.         cmp     dword[edi+8], C_CLK/(16 + 16/2)
  768.         jl      .c_nextbaud2
  769.         mov     edx, 1
  770.         mov     ecx, C_CLK/(16 + 16/2)
  771.         jmp     .calcend        
  772.        
  773.   .h_nextbaud2:
  774.         cmp     dword[edi+8], H_CLK/(2*10)
  775.         jl      .h_nextbaud3
  776.         mov     edx, 2
  777.         mov     ecx, H_CLK/(2*10)
  778.         jmp     .calcend
  779.        
  780.   .c_nextbaud2:  
  781.         cmp     dword[edi+8], C_CLK/(2*16)
  782.         jl      .c_nextbaud3
  783.         mov     edx, 2
  784.         mov     ecx, C_CLK/(2*16)
  785.         jmp     .calcend        
  786.        
  787.   .h_nextbaud3:
  788.         mov     eax, H_CLK*16/10  ; eax - best_divisor
  789.         xor     edx, edx
  790.         div     dword[edi+8]      ; [edi+8] - baudrate
  791.         push    eax
  792.         and     eax, 1
  793.         pop     eax
  794.         shr     eax, 1
  795.         jz      .h_rounddowndiv     ; jump by result of and eax, 1
  796.         inc     eax
  797.   .h_rounddowndiv:
  798.         cmp     eax, 0x20000
  799.         jle     .h_best_divok
  800.         mov     eax, 0x1FFFF
  801.   .h_best_divok:
  802.         mov     ecx, eax        
  803.         mov     eax, H_CLK*16/10
  804.         xor     edx, edx
  805.         div     ecx
  806.         xchg    ecx, eax            ; ecx - best_baud
  807.         push    ecx
  808.         and     ecx, 1
  809.         pop     ecx
  810.         shr     ecx, 1
  811.         jz      .rounddownbaud
  812.         inc     ecx
  813.         jmp     .rounddownbaud
  814.        
  815.   .c_nextbaud3:
  816.         mov     eax, C_CLK        ; eax - best_divisor
  817.         xor     edx, edx
  818.         div     dword[edi+8]      ; [edi+8] - baudrate
  819.         push    eax
  820.         and     eax, 1
  821.         pop     eax
  822.         shr     eax, 1
  823.         jnz     .c_rounddowndiv     ; jump by result of and eax, 1
  824.         inc     eax
  825.   .c_rounddowndiv:
  826.         cmp     eax, 0x20000
  827.         jle     .c_best_divok
  828.         mov     eax, 0x1FFFF
  829.   .c_best_divok:
  830.         mov     ecx, eax        
  831.         mov     eax, C_CLK
  832.         xor     edx, edx
  833.         div     ecx
  834.         xchg    ecx, eax            ; ecx - best_baud
  835.         push    ecx
  836.         and     ecx, 1
  837.         pop     ecx
  838.         shr     ecx, 1
  839.         jnz     .rounddownbaud
  840.         inc     ecx
  841.        
  842.   .rounddownbaud:
  843.         mov     edx, eax            ; edx - encoded_divisor
  844.         shr     edx, 3
  845.         and     eax, 0x7
  846.         push    esp
  847.         push    7 6 5 1 4 2 3 0
  848.         mov     eax, [esp+eax*4]
  849.         shl     eax, 14
  850.         or      edx, eax
  851.         mov     esp, [esp+36]
  852.        
  853.   .calcend:
  854.         mov     eax, edx        ; eax - *value
  855.         mov     ecx, edx        ; ecx - *index
  856.         and     eax, 0xFFFF
  857.         cmp     [ebx + ftdi_context.chipType], TYPE_2232H
  858.         jge     .foxyindex        
  859.         shr     ecx, 16
  860.         jmp     .preparepacket
  861.   .foxyindex:
  862.         shr     ecx, 8
  863.         and     ecx, 0xFF00
  864.         or      ecx, [ebx + ftdi_context.index]
  865.        
  866.   .preparepacket:
  867.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BAUDRATE_REQUEST shl 8)
  868.         mov     word[ConfPacket+2], ax
  869.         mov     word[ConfPacket+4], cx
  870.         mov     word[ConfPacket+6], 0
  871.         jmp     .own_index        
  872.        
  873. endp
  874. restore   handle
  875. restore   io_code
  876. restore   input
  877. restore   inp_size
  878. restore   output
  879. restore   out_size
  880.  
  881.  
  882. align 4
  883. proc control_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD  
  884.    
  885.         DEBUGF 1, 'K : status is %d\n', [.status]
  886.         mov     ecx, [.calldata]
  887.         mov     eax, [ecx]
  888.         mov     ebx, [ecx+4]
  889.         mov     edx, [.status]
  890.         mov     [ecx+8], edx
  891.         xor     esi, esi
  892.         xor     edx, edx
  893.         call    RaiseEvent              
  894.         ret
  895. endp
  896.  
  897. proc bulk_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD
  898.  
  899.         DEBUGF 1, 'K : status is %d\n', [.status]        
  900.         mov     ecx, [.calldata]
  901.         mov     eax, [ecx]
  902.         mov     ebx, [ecx+4]
  903.         cmp     [.status], 0
  904.         jz      .normal
  905.         cmp     [.status], 9
  906.         jne     .error
  907.   .normal:
  908.         mov     edx, [.length]
  909.         mov     [ecx+8], edx
  910.         jmp     .ok
  911.   .error:
  912.         mov     [ecx+8], dword -1
  913.   .ok:    
  914.         xor     esi, esi
  915.         xor     edx, edx
  916.         call    RaiseEvent            
  917.         ret
  918. endp
  919.  
  920. proc DeviceDisconnected stdcall uses  ebx esi edi, .device_data:DWORD
  921.  
  922.         DEBUGF 1, 'K : FTDI deleting device data %x\n', [.device_data]
  923.         mov     eax, [.device_data]
  924.         call    linkedlist_delete
  925.         ret          
  926. endp
  927.  
  928. include 'linkedlist.inc'
  929.        
  930. ; Exported variable: kernel API version.
  931. align 4
  932. version dd      50005h
  933. ; Structure with callback functions.
  934. usb_functions:
  935.         dd      12
  936.         dd      AddDevice
  937.         dd      DeviceDisconnected
  938.  
  939. ;for DEBUGF macro
  940. include_debug_strings
  941.  
  942.  
  943.  
  944.  
  945. ; for uninitialized data
  946. ;section '.data' data readable writable align 16
  947.