Subversion Repositories Kolibri OS

Rev

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