Subversion Repositories Kolibri OS

Rev

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