Subversion Repositories Kolibri OS

Rev

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