Subversion Repositories Kolibri OS

Rev

Rev 5014 | Rev 5019 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4985 gtament 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
 
4975 gtament 8
format MS COFF
9
 
10
DEBUG = 1
11
 
12
__DEBUG__ = 1
13
__DEBUG_LEVEL__ = 1
14
 
4997 gtament 15
node equ ftdi_context
16
node.next equ ftdi_context.next_context
17
 
4980 gtament 18
include '../../proc32.inc'
19
include '../../imports.inc'
20
include '../../fdo.inc'
21
include '../../struct.inc'
4975 gtament 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
 
4992 gtament 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
 
4975 gtament 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      ?
5018 gtament 127
maxPacketSize           dd      ?
4975 gtament 128
interface               dd      ?
129
index                   dd      ?
130
inEP                    dd      ?
131
outEP                   dd      ?
132
nullP                   dd      ?
4997 gtament 133
lockPID                 dd      ?
4975 gtament 134
next_context            dd      ?
135
ends
136
 
137
struct IOCTL
138
handle                  dd      ?
139
io_code                 dd      ?
140
input                   dd      ?
141
inp_size                dd      ?
142
output                  dd      ?
143
out_size                dd      ?
144
ends
145
 
146
struct usb_descr
4979 gtament 147
bLength                 db      ?
148
bDescriptorType         db      ?
4975 gtament 149
bcdUSB                  dw      ?
150
bDeviceClass            db      ?
151
bDeviceSubClass         db      ?
152
bDeviceProtocol         db      ?
153
bMaxPacketSize0         db      ?
154
idVendor                dw      ?
155
idProduct               dw      ?
156
bcdDevice               dw      ?
157
iManufacturer           db      ?
158
iProduct                db      ?
159
iSerialNumber           db      ?
160
bNumConfigurations      db      ?
161
ends
162
 
4979 gtament 163
struct conf_packet
164
bmRequestType           db      ?
165
bRequest                db      ?
166
wValue                  dw      ?
167
wIndex                  dw      ?
168
wLength                 dw      ?
169
ends
170
 
4975 gtament 171
section '.flat' code readable align 16
172
; The start procedure.
173
proc START stdcall, .reason:DWORD
174
 
175
        xor     eax, eax        ; initialize return value
176
        cmp     [.reason], 1    ; compare the argument
177
        jnz     .nothing
178
        stdcall RegUSBDriver, my_driver, service_proc, usb_functions
179
 
180
.nothing:
4979 gtament 181
        ret
4975 gtament 182
endp
183
 
184
 
5018 gtament 185
proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
4975 gtament 186
 
187
        stdcall USBGetParam, [.config_pipe], 0
4997 gtament 188
        mov     edx, eax
5018 gtament 189
        DEBUGF 1,'K : Detected device vendor: %x\n', [eax+usb_descr.idVendor]
4979 gtament 190
        cmp     word[eax+usb_descr.idVendor], 0x0403
4975 gtament 191
        jnz     .notftdi
4984 gtament 192
        movi    eax, sizeof.ftdi_context
4975 gtament 193
        call    Kmalloc
194
        test    eax, eax
195
        jnz     @f
196
        mov     esi, nomemory_msg
197
        call    SysMsgBoardStr
198
        jmp     .nothing
4997 gtament 199
  @@:
4975 gtament 200
        DEBUGF 1,'K : Adding struct to list %x\n', eax
4997 gtament 201
        call    linkedlist_add
4975 gtament 202
 
203
        mov     ebx, [.config_pipe]
204
        mov     [eax + ftdi_context.nullP], ebx
4992 gtament 205
        mov     [eax + ftdi_context.index], 0
4997 gtament 206
        mov     [eax + ftdi_context.lockPID], 0
5018 gtament 207
        mov     [eax + ftdi_context.maxPacketSize], 64
5014 gtament 208
        mov     [eax + ftdi_context.readBufChunkSize], 64
209
        mov     [eax + ftdi_context.writeBufChunkSize], 64
4975 gtament 210
 
5018 gtament 211
        mov     cx, [edx+usb_descr.bcdDevice]
212
        cmp     cx, 0x400
4997 gtament 213
        jnz     @f
214
        mov     [eax + ftdi_context.chipType], TYPE_BM
5018 gtament 215
        jmp     .slow
4997 gtament 216
  @@:
5018 gtament 217
        cmp     cx, 0x200
4997 gtament 218
        jnz     @f
219
        mov     [eax + ftdi_context.chipType], TYPE_AM
5018 gtament 220
        jmp     .slow
4997 gtament 221
  @@:
5018 gtament 222
        cmp     cx, 0x500
4997 gtament 223
        jnz     @f
5018 gtament 224
        mov     [eax + ftdi_context.chipType], TYPE_2232C
225
        jmp     .slow
4997 gtament 226
  @@:
5018 gtament 227
        cmp     cx, 0x600
4997 gtament 228
        jnz     @f
229
        mov     [eax + ftdi_context.chipType], TYPE_R
5018 gtament 230
        jmp     .slow
4997 gtament 231
  @@:
5018 gtament 232
        cmp     cx, 0x700
4997 gtament 233
        jnz     @f
234
        mov     [eax + ftdi_context.chipType], TYPE_2232H
5018 gtament 235
        jmp     .fast
4997 gtament 236
  @@:
5018 gtament 237
        cmp     cx, 0x900
4997 gtament 238
        jnz     @f
239
        mov     [eax + ftdi_context.chipType], TYPE_232H
5018 gtament 240
        jmp     .fast
4997 gtament 241
  @@:
5018 gtament 242
        cmp     cx, 0x1000
243
        jnz     .slow
244
        mov     [eax + ftdi_context.chipType], TYPE_230X
245
        jmp     .fast
246
 
247
  .fast:
248
        add     [eax + ftdi_context.maxPacketSize], 512-64
249
  .slow:
4975 gtament 250
        mov     ebx, eax
5018 gtament 251
        stdcall USBOpenPipe, [.config_pipe],  0x81,  [ebx + ftdi_context.maxPacketSize],  BULK_PIPE, 0
252
        test    eax, eax
253
        jz      .nothing
4975 gtament 254
        mov     [ebx + ftdi_context.inEP], eax
5018 gtament 255
        stdcall USBOpenPipe, [.config_pipe],  0x02,  [ebx + ftdi_context.maxPacketSize],  BULK_PIPE, 0
256
        test    eax, eax
257
        jz      .nothing
5014 gtament 258
        mov     [ebx + ftdi_context.outEP], eax
259
        mov     eax, ebx
260
        ret
4997 gtament 261
 
4975 gtament 262
  .notftdi:
263
        DEBUGF 1,'K : Skipping not FTDI device\n'
4997 gtament 264
  .nothing:
4975 gtament 265
        xor     eax, eax
266
        ret
267
endp
268
 
269
 
270
handle     equ  IOCTL.handle
271
io_code    equ  IOCTL.io_code
272
input      equ  IOCTL.input
273
inp_size   equ  IOCTL.inp_size
274
output     equ  IOCTL.output
275
out_size   equ  IOCTL.out_size
276
 
277
align 4
278
proc service_proc stdcall uses ebx esi edi, ioctl:DWORD
279
locals
280
ConfPacket  rb  8
5014 gtament 281
EventData   rd  3
4975 gtament 282
endl
4979 gtament 283
        mov     edi, [ioctl]
4997 gtament 284
        mov     eax, [edi+io_code]
4975 gtament 285
        DEBUGF 1,'K : FTDI got the request: %d\n', eax
4979 gtament 286
        test    eax, eax           ;0
287
        jz      .version
288
        dec     eax                 ;1
289
        jz      .ftdi_get_list
4985 gtament 290
 
4997 gtament 291
        push    eax
292
        mov     esi, [edi+input]
293
        mov     eax, [esi+4]
294
        call    linkedlist_isvalid
295
        test    eax, eax
296
        pop     eax
297
        jnz     .endswitch
298
 
299
        dec     eax
300
        jz      .ftdi_lock      ;2
301
        dec     eax
302
        jz      .ftdi_unlock    ;3
303
 
304
        mov     ebx, [esi+4]
305
        mov     ecx, [ebx + ftdi_context.lockPID]
306
        cmp     ecx, [esi]
307
        jz      .pid_ok
308
        mov     esi, [edi+output]
309
        mov     dword[esi], 'LCKD'
310
        jmp     .endswitch
311
 
5018 gtament 312
  .pid_ok:
313
        dec     eax
314
        jz      .ftdi_get_wchunksize    ;5
315
        dec     eax
316
        jz      .ftdi_get_rchunksize    ;7
317
 
318
        mov     edi, [edi+input]
319
 
320
        dec     eax
321
        jz      .ftdi_set_rchunksize    ;6
322
        dec     eax
323
        jz      .ftdi_set_wchunksize    ;4
324
 
4985 gtament 325
        push    eax edi
5014 gtament 326
        mov     ecx, 0x80000000
327
        cmp     eax, 17
5018 gtament 328
        je      .bulkevent
5014 gtament 329
        cmp     eax, 18
330
        je      .bulkevent
4985 gtament 331
        xor     ecx, ecx
5014 gtament 332
  .bulkevent:
4985 gtament 333
        xor     esi, esi
334
        call    CreateEvent
335
        mov     [EventData], eax
336
        mov     [EventData+4], edx
5018 gtament 337
        pop     edi eax
4985 gtament 338
 
5018 gtament 339
        dec     eax                 ;8
4979 gtament 340
        jz      .ftdi_set_bitmode
5018 gtament 341
        dec     eax                 ;9
4984 gtament 342
        jz      .ftdi_setrtshigh
5018 gtament 343
        dec     eax                 ;10
4997 gtament 344
        jz      .ftdi_setrtslow
5018 gtament 345
        dec     eax                 ;11
4997 gtament 346
        jz      .ftdi_setdtrhigh
5018 gtament 347
        dec     eax                 ;12
4997 gtament 348
        jz      .ftdi_setdtrlow
5018 gtament 349
        dec     eax                 ;13
4997 gtament 350
        jz      .ftdi_usb_reset
5018 gtament 351
        dec     eax                 ;14
4997 gtament 352
        jz      .ftdi_setflowctrl
5018 gtament 353
        dec     eax                 ;15
4997 gtament 354
        jz      .ftdi_set_event_char
5018 gtament 355
        dec     eax                 ;16
4997 gtament 356
        jz      .ftdi_set_error_char
5018 gtament 357
        dec     eax                 ;17
4997 gtament 358
        jz      .ftdi_set_latency_timer
5018 gtament 359
        dec     eax                 ;18
4997 gtament 360
        jz      .ftdi_get_latency_timer
5018 gtament 361
        dec     eax                 ;19
4997 gtament 362
        jz      .ftdi_read_pins
5018 gtament 363
        dec     eax                 ;20
4997 gtament 364
        jz      .ftdi_poll_modem_status
5018 gtament 365
        dec     eax                 ;21
4997 gtament 366
        jz      .ftdi_write_data
5018 gtament 367
        dec     eax                 ;22
5014 gtament 368
        jz      .ftdi_read_data
5018 gtament 369
        dec     eax                 ;23
4997 gtament 370
        jz      .ftdi_set_baudrate
5018 gtament 371
        dec     eax                 ;24
4997 gtament 372
        jz      .ftdi_set_line_property
5018 gtament 373
        dec     eax                 ;25
4997 gtament 374
        jz      .ftdi_purge_rx_buf
5018 gtament 375
        dec     eax                 ;26
4997 gtament 376
        jz      .ftdi_purge_tx_buf
5018 gtament 377
        jmp     .error
378
 
4975 gtament 379
  .version:
5018 gtament 380
        jmp     .endswitch
381
  .error:
382
        mov     esi, [edi+output]
383
        mov     [esi], dword 'ERR0'
384
        or      [esi], eax
4975 gtament 385
  .endswitch:
4979 gtament 386
        xor     eax, eax
5018 gtament 387
	    ret
4985 gtament 388
 
5018 gtament 389
  .eventdestroy:
390
        mov     eax, [EventData]
391
        mov     ebx, [EventData+4]
392
        call    DestroyEvent
393
        jmp     .endswitch
394
 
395
  .ftdi_out_control_transfer_withinp:
396
        mov     dx, word[edi+8]
397
        mov     word[ConfPacket+2], dx
398
  .ftdi_out_control_transfer_noinp:
399
        mov     ebx, [edi+4]
4992 gtament 400
        mov     cx, word[ebx + ftdi_context.index]
401
        mov     word[ConfPacket+4], cx
402
        xor     cx, cx
403
        mov     word[ConfPacket+6], cx
404
  .own_index:
5018 gtament 405
        mov     ebx, [edi+4]
4992 gtament 406
        DEBUGF 1,'K : ConfPacket %x %x\n', [ConfPacket], [ConfPacket+4]
4975 gtament 407
        lea     esi, [ConfPacket]
4979 gtament 408
        lea     edi, [EventData]
4975 gtament 409
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, 0, 0, control_callback, edi, 0
5018 gtament 410
        test    eax, eax
411
        jz      .error
4979 gtament 412
        mov     eax, [EventData]
413
        mov     ebx, [EventData+4]
4975 gtament 414
        call    WaitEvent
415
        jmp     .endswitch
4985 gtament 416
 
4984 gtament 417
  .ftdi_setrtshigh:
4985 gtament 418
        DEBUGF 1,'K : FTDI Setting RTS pin HIGH\n'
4984 gtament 419
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_HIGH shl 16)
5018 gtament 420
        jmp     .ftdi_out_control_transfer_noinp
4984 gtament 421
 
422
  .ftdi_setrtslow:
4985 gtament 423
        DEBUGF 1,'K : FTDI Setting RTS pin LOW\n'
4984 gtament 424
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_LOW shl 16)
5018 gtament 425
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 426
 
427
  .ftdi_setdtrhigh:
428
        DEBUGF 1,'K : FTDI Setting DTR pin HIGH\n'
429
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_HIGH shl 16)
5018 gtament 430
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 431
 
432
  .ftdi_setdtrlow:
433
        DEBUGF 1,'K : FTDI Setting DTR pin LOW\n'
434
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_LOW shl 16)
5018 gtament 435
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 436
 
437
  .ftdi_usb_reset:
438
        DEBUGF 1,'K : FTDI Reseting\n'
439
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_SIO shl 16)
5018 gtament 440
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 441
 
442
  .ftdi_purge_rx_buf:
443
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_RX shl 16)
5018 gtament 444
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 445
 
446
  .ftdi_purge_tx_buf:
447
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_TX shl 16)
5018 gtament 448
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 449
 
5018 gtament 450
  .ftdi_set_bitmode:
451
        DEBUGF 1,'K : FTDI Seting bitmode\n'
452
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BITMODE_REQUEST shl 8)
453
        jmp     .ftdi_out_control_transfer_withinp
4992 gtament 454
 
4985 gtament 455
  .ftdi_set_line_property:
4992 gtament 456
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_DATA_REQUEST shl 8)
5018 gtament 457
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 458
 
459
  .ftdi_set_latency_timer:
5018 gtament 460
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_LATENCY_TIMER_REQUEST shl 8)
461
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 462
 
463
  .ftdi_set_event_char:
4992 gtament 464
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_EVENT_CHAR_REQUEST shl 8)
5018 gtament 465
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 466
 
467
  .ftdi_set_error_char:
4992 gtament 468
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_ERROR_CHAR_REQUEST shl 8)
5018 gtament 469
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 470
 
4992 gtament 471
  .ftdi_setflowctrl:
5018 gtament 472
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_FLOW_CTRL_REQUEST shl 8) + (0 shl 16)
473
        mov     ebx, [edi+4]
4997 gtament 474
        mov     cx, word[edi+8]
4992 gtament 475
        or      ecx, [ebx + ftdi_context.index]
476
        mov     word[ConfPacket+4], cx
477
        xor     cx, cx
478
        mov     word[ConfPacket+6], cx
479
        jmp     .own_index
4985 gtament 480
 
5018 gtament 481
  .ftdi_read_pins:
4984 gtament 482
        mov     ebx, [edi]
4997 gtament 483
        mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_READ_PINS_REQUEST shl 8) + (0 shl 16)
484
        mov     ecx, [ebx + ftdi_context.index]
485
        mov     word[ConfPacket+4], cx
486
        mov     word[ConfPacket+6], 1
4984 gtament 487
        lea     esi, [ConfPacket]
4985 gtament 488
        lea     edi, [EventData]
489
        mov     ecx, [ioctl]
490
        mov     ecx, [ecx+output]
491
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 1, control_callback, edi, 0
4984 gtament 492
        mov     eax, [EventData]
493
        mov     ebx, [EventData+4]
494
        call    WaitEvent
495
        jmp     .endswitch
5018 gtament 496
 
497
  .ftdi_set_wchunksize:
498
        mov     ebx, [edi+4]
499
        mov     ecx, [edi+8]
500
        cmp     [ebx + ftdi_context.maxPacketSize], ecx
501
        jg      .error
502
        mov     [ebx + ftdi_context.writeBufChunkSize], ecx
503
        jmp     .endswitch
504
 
505
  .ftdi_get_wchunksize:
506
        mov     esi, [edi+output]
507
        mov     edi, [edi+input]
508
        mov     ebx, [edi+4]
509
        mov     ecx, [ebx + ftdi_context.writeBufChunkSize]
510
        mov     [esi], ecx
511
        jmp     .endswitch
4997 gtament 512
 
5018 gtament 513
  .ftdi_set_rchunksize:
514
        mov     ebx, [edi+4]
515
        mov     ecx, [edi+8]
516
        cmp     [ebx + ftdi_context.maxPacketSize], ecx
517
        jg      .error
518
        mov     [ebx + ftdi_context.readBufChunkSize], ecx
519
        jmp     .endswitch
520
 
521
  .ftdi_get_rchunksize:
522
        mov     esi, [edi+output]
523
        mov     edi, [edi+input]
524
        mov     ebx, [edi+4]
525
        mov     ecx, [ebx + ftdi_context.readBufChunkSize]
526
        mov     [esi], ecx
527
        jmp     .endswitch
528
 
4997 gtament 529
  .ftdi_write_data:
5018 gtament 530
        mov     esi, edi
531
        add     esi, 12
4997 gtament 532
        mov     ebx, [edi+4]
5018 gtament 533
        xor     ecx, ecx        ; ecx - offset
534
  .write_loop:
535
        mov     edx, [edi+8]    ; edx - write_size
4997 gtament 536
        sub     edx, ecx
5018 gtament 537
        cmp     edx, [ebx + ftdi_context.writeBufChunkSize]
538
        jle     .lessthanchunk_write
539
        mov     edx, [ebx + ftdi_context.writeBufChunkSize]
540
  .lessthanchunk_write:
541
        add     esi, ecx
5014 gtament 542
        lea     eax, [EventData]
5018 gtament 543
        push    ecx ebx esi edi
544
        stdcall USBNormalTransferAsync, [ebx + ftdi_context.inEP], esi, edx, bulk_callback, eax, 1
4997 gtament 545
        mov     eax, [EventData]
546
        mov     ebx, [EventData+4]
5014 gtament 547
        call    WaitEvent
5018 gtament 548
        mov     eax, [EventData]
549
        mov     ebx, [EventData+4]
550
        call    ClearEvent
551
        pop     edi esi ebx ecx
5014 gtament 552
        cmp     [EventData+8], -1
5018 gtament 553
        jz .error
5014 gtament 554
        add     ecx, [EventData+8]
4997 gtament 555
        cmp     ecx, [edi+8]
5018 gtament 556
        jge     .eventdestroy
557
        jmp     .write_loop
4985 gtament 558
 
5014 gtament 559
  .ftdi_read_data:
5018 gtament 560
        mov     edi, [ioctl]
5014 gtament 561
        mov     esi, [edi+input]
562
        mov     edi, [edi+output]
563
        mov     ebx, [esi+4]
564
        xor     ecx, ecx
5018 gtament 565
  .read_loop:
5014 gtament 566
        mov     edx, [esi+8]
5018 gtament 567
        cmp     ecx, edx
568
        jge     .eventdestroy ;!!!
5014 gtament 569
        sub     edx, ecx
570
        cmp     edx, [ebx + ftdi_context.readBufChunkSize]
571
        jl      .lessthanchunk_read
572
        mov     edx, [ebx + ftdi_context.readBufChunkSize]
573
  .lessthanchunk_read:
574
        lea     eax, [EventData]
5018 gtament 575
        add     edi, ecx
5014 gtament 576
        push    esi edi ecx ebx
5018 gtament 577
        stdcall USBNormalTransferAsync, [ebx + ftdi_context.outEP], edi, edx, bulk_callback, eax, 1
5014 gtament 578
        mov     eax, [EventData]
579
        mov     ebx, [EventData+4]
580
        call    WaitEvent
5018 gtament 581
        mov     eax, [EventData]
582
        mov     ebx, [EventData+4]
583
        call    ClearEvent
5014 gtament 584
        pop     ebx ecx edi esi
585
        cmp     [EventData+8], -1
5018 gtament 586
        jz      .error
5014 gtament 587
        add     ecx, [EventData+8]
588
        jmp     .read_loop
589
 
5018 gtament 590
  .ftdi_poll_modem_status:
4997 gtament 591
        mov     ebx, [edi+4]
592
        mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_POLL_MODEM_STATUS_REQUEST shl 8) + (0 shl 16)
593
        mov     ecx, [ebx + ftdi_context.index]
594
        mov     word[ConfPacket+4], cx
595
        mov     word[ConfPacket+6], 1
596
        lea     esi, [ConfPacket]
597
        lea     edi, [EventData]
598
        mov     ecx, [ioctl]
599
        mov     ecx, [ecx+output]
600
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 2, control_callback, edi, 0
601
        mov     eax, [EventData]
602
        mov     ebx, [EventData+4]
603
        call    WaitEvent
604
        mov     ax, word[ecx]
605
        xchg    ah, al
606
        and     ah, 0xFF
607
        mov     word[ecx], ax
608
        jmp     .endswitch
609
 
5018 gtament 610
  .ftdi_get_latency_timer:
4997 gtament 611
        mov     ebx, [edi+4]
612
        mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_GET_LATENCY_TIMER_REQUEST shl 8) + (0 shl 16)
613
        mov     ecx, [ebx + ftdi_context.index]
614
        mov     word[ConfPacket+4], cx
615
        mov     word[ConfPacket+6], 1
616
        lea     esi, [ConfPacket]
617
        lea     edi, [EventData]
618
        mov     ecx, [ioctl]
619
        mov     ecx, [ecx+output]
620
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 2, control_callback, edi, 0
621
        mov     eax, [EventData]
622
        mov     ebx, [EventData+4]
623
        call    WaitEvent
624
        jmp     .endswitch
625
 
626
  .ftdi_get_list:
5018 gtament 627
        call    linkedlist_gethead
628
        test    eax, eax
629
        jz      .endswitch
4975 gtament 630
        mov     edi, [edi+output]
5014 gtament 631
        push    edi
632
        add     edi, 4
633
        xor     ecx, ecx
4997 gtament 634
  .nextdev:
5014 gtament 635
        inc     ecx
4997 gtament 636
        cmp     [eax + ftdi_context.lockPID], 0
637
        jnz      .dev_is_locked
638
        mov     dword[edi], 'NLKD'
639
        jmp     .nextfields
640
  .dev_is_locked:
641
        mov     dword[edi], 'LCKD'
642
  .nextfields:
643
        mov     bl, [eax + ftdi_context.chipType]
644
        mov     [edi+4], ebx
645
        mov     [edi+8], eax
646
        add     edi, 12
647
        mov     eax, [eax + ftdi_context.next_context]
648
        test    eax, eax
649
        jnz     .nextdev
5014 gtament 650
        pop     edi
651
        mov     [edi], ecx
4997 gtament 652
        jmp     .endswitch
653
 
654
  .ftdi_lock:
5014 gtament 655
        DEBUGF 1, 'K : FTDI lock attempt\n'
4997 gtament 656
        mov     esi, [edi+input]
657
        mov     ebx, [esi+4]
658
        mov     eax, [ebx + ftdi_context.lockPID]
659
        test    eax, eax
660
        jnz     .lockedby
5014 gtament 661
        DEBUGF 1, 'K : Lock success\n'
4997 gtament 662
        mov     eax, [esi]
663
        mov     [ebx + ftdi_context.lockPID], eax
664
  .lockedby:
665
        mov     edi, [edi+output]
4979 gtament 666
        mov     [edi], eax
4985 gtament 667
        jmp     .endswitch
4997 gtament 668
 
669
  .ftdi_unlock:
670
        mov     esi, [edi+input]
671
        mov     edi, [edi+output]
672
        mov     ebx, [esi+4]
673
        mov     eax, [ebx + ftdi_context.lockPID]
674
        cmp     eax, [esi]
675
        jnz     .unlockimp
676
        mov     [ebx + ftdi_context.lockPID], 0
677
        mov     dword[edi], 0
678
        jmp     .endswitch
679
  .unlockimp:
680
        mov     [edi], eax
5018 gtament 681
        jmp     .endswitch
682
 
683
H_CLK = 120000000
684
C_CLK = 48000000
685
  .ftdi_set_baudrate:
686
        mov     ebx, [edi+4]
687
        cmp     [ebx + ftdi_context.chipType], TYPE_2232H
688
        jl      .c_clk
689
        imul    eax, [edi+8], 10
690
        cmp     eax, H_CLK / 0x3FFF
691
        jle     .c_clk
692
  .h_clk:
693
        cmp     dword[edi+8], H_CLK/10
694
        jl      .h_nextbaud1
695
        xor     edx, edx
696
        mov     ecx, H_CLK/10
697
        jmp     .calcend
4997 gtament 698
 
5018 gtament 699
  .c_clk:
700
        cmp     dword[edi+8], C_CLK/10
701
        jl      .c_nextbaud1
702
        xor     edx, edx
703
        mov     ecx, C_CLK/10
704
        jmp     .calcend
705
 
706
  .h_nextbaud1:
707
        cmp     dword[edi+8], H_CLK/(10 + 10/2)
708
        jl      .h_nextbaud2
709
        mov     edx, 1
710
        mov     ecx, H_CLK/(10 + 10/2)
711
        jmp     .calcend
712
 
713
  .c_nextbaud1:
714
        cmp     dword[edi+8], C_CLK/(10 + 10/2)
715
        jl      .c_nextbaud2
716
        mov     edx, 1
717
        mov     ecx, C_CLK/(10 + 10/2)
718
        jmp     .calcend
719
 
720
  .h_nextbaud2:
721
        cmp     dword[edi+8], H_CLK/(2*10)
722
        jl      .h_nextbaud3
723
        mov     edx, 2
724
        mov     ecx, H_CLK/(2*10)
725
        jmp     .calcend
726
 
727
  .c_nextbaud2:
728
        cmp     dword[edi+8], C_CLK/(2*10)
729
        jl      .c_nextbaud3
730
        mov     edx, 2
731
        mov     ecx, C_CLK/(2*10)
732
        jmp     .calcend
733
 
734
  .h_nextbaud3:
735
        mov     eax, H_CLK*16/10  ; eax - best_divisor
736
        div     dword[edi+8]      ; [edi+8] - baudrate
737
        push    eax
738
        and     eax, 1
739
        pop     eax
740
        shr     eax, 1
741
        jz      .h_rounddowndiv     ; jump by result of and eax, 1
742
        inc     eax
743
  .h_rounddowndiv:
744
        cmp     eax, 0x20000
745
        jle     .h_best_divok
746
        mov     eax, 0x1FFFF
747
  .h_best_divok:
748
        mov     ecx, eax
749
        mov     eax, H_CLK*16/10
750
        div     ecx
751
        xchg    ecx, eax            ; ecx - best_baud
752
        push    ecx
753
        and     ecx, 1
754
        pop     ecx
755
        shr     ecx, 1
756
        jz      .rounddownbaud
757
        inc     ecx
758
        jmp     .rounddownbaud
759
 
760
  .c_nextbaud3:
761
        mov     eax, C_CLK*16/10  ; eax - best_divisor
762
        div     dword[edi+8]      ; [edi+8] - baudrate
763
        push    eax
764
        and     eax, 1
765
        pop     eax
766
        shr     eax, 1
767
        jz      .c_rounddowndiv     ; jump by result of and eax, 1
768
        inc     eax
769
  .c_rounddowndiv:
770
        cmp     eax, 0x20000
771
        jle     .c_best_divok
772
        mov     eax, 0x1FFFF
773
  .c_best_divok:
774
        mov     ecx, eax
775
        mov     eax, C_CLK*16/10
776
        div     ecx
777
        xchg    ecx, eax            ; ecx - best_baud
778
        push    ecx
779
        and     ecx, 1
780
        pop     ecx
781
        shr     ecx, 1
782
        jz      .rounddownbaud
783
        inc     ecx
784
 
785
  .rounddownbaud:
786
        mov     edx, eax            ; edx - encoded_divisor
787
        shr     edx, 3
788
        and     eax, 0x7
789
        push    esp
790
        push    7 6 5 1 4 2 3 0
791
        mov     eax, [esp+eax*4]
792
        shl     eax, 14
793
        or      edx, eax
794
        mov     esp, [esp+36]
795
 
796
  .calcend:
797
        mov     eax, edx        ; eax - *value
798
        mov     ecx, edx        ; ecx - *index
799
        and     eax, 0xFFFF
800
        cmp     [ebx + ftdi_context.chipType], TYPE_2232H
801
        jge     .foxyindex
802
        shr     ecx, 16
803
        jmp     .preparepacket
804
  .foxyindex:
805
        shr     ecx, 8
806
        and     ecx, 0xFF00
807
        or      ecx, [ebx + ftdi_context.index]
808
 
809
  .preparepacket:
810
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BAUDRATE_REQUEST shl 8)
811
        mov     word[ConfPacket+2], ax
812
        mov     word[ConfPacket+4], cx
813
        mov     word[ConfPacket+6], 0
814
        jmp     .own_index
815
 
4975 gtament 816
endp
817
restore   handle
818
restore   io_code
819
restore   input
820
restore   inp_size
821
restore   output
822
restore   out_size
823
 
824
 
825
align 4
4984 gtament 826
proc control_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD
4975 gtament 827
 
4985 gtament 828
        DEBUGF 1, 'K : status is %d\n', [.status]
4980 gtament 829
        mov     ecx, [.calldata]
830
        mov     eax, [ecx]
831
        mov     ebx, [ecx+4]
5014 gtament 832
        mov     edx, [.status]
833
        mov     [ecx+8], edx
4997 gtament 834
        xor     esi, esi
4979 gtament 835
        xor     edx, edx
5014 gtament 836
        call    RaiseEvent
4975 gtament 837
        ret
838
endp
839
 
4997 gtament 840
proc bulk_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD
4975 gtament 841
 
5014 gtament 842
        DEBUGF 1, 'K : status is %d\n', [.status]
4997 gtament 843
        mov     ecx, [.calldata]
844
        mov     eax, [ecx]
845
        mov     ebx, [ecx+4]
5014 gtament 846
        cmp     [.status], 0
5018 gtament 847
        jz      .normal
5014 gtament 848
        cmp     [.status], 9
849
        jne     .error
5018 gtament 850
  .normal:
4997 gtament 851
        mov     edx, [.length]
5014 gtament 852
        mov     [ecx+8], edx
853
        jmp     .ok
854
  .error:
855
        mov     [ecx+8], dword -1
5018 gtament 856
  .ok:
4997 gtament 857
        xor     esi, esi
5014 gtament 858
        xor     edx, edx
859
        call    RaiseEvent
4997 gtament 860
        ret
861
endp
862
 
4975 gtament 863
proc DeviceDisconnected stdcall uses  ebx esi edi, .device_data:DWORD
864
 
5014 gtament 865
        DEBUGF 1, 'K : FTDI deleting device data %x\n', [.device_data]
4975 gtament 866
        mov     eax, [.device_data]
4997 gtament 867
        call    linkedlist_delete
4979 gtament 868
        ret
4975 gtament 869
endp
870
 
871
include 'linkedlist.inc'
872
 
873
; Exported variable: kernel API version.
874
align 4
875
version dd      50005h
876
; Structure with callback functions.
877
usb_functions:
878
        dd      12
879
        dd      AddDevice
880
        dd      DeviceDisconnected
881
 
882
;for DEBUGF macro
883
include_debug_strings
884
 
885
 
886
 
887
 
888
; for uninitialized data
889
;section '.data' data readable writable align 16