Subversion Repositories Kolibri OS

Rev

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