0,0 → 1,305 |
; standard driver stuff |
format MS COFF |
|
DEBUG = 1 |
|
; this is for DEBUGF macro from 'fdo.inc' |
__DEBUG__ = 1 |
__DEBUG_LEVEL__ = 1 |
|
include '../proc32.inc' |
include '../imports.inc' |
include '../fdo.inc' |
include '../../struct.inc' |
|
public START |
public version |
|
; USB constants |
DEVICE_DESCR_TYPE = 1 |
CONFIG_DESCR_TYPE = 2 |
STRING_DESCR_TYPE = 3 |
INTERFACE_DESCR_TYPE = 4 |
ENDPOINT_DESCR_TYPE = 5 |
DEVICE_QUALIFIER_DESCR_TYPE = 6 |
|
CONTROL_PIPE = 0 |
ISOCHRONOUS_PIPE = 1 |
BULK_PIPE = 2 |
INTERRUPT_PIPE = 3 |
|
; USB HID constants |
HID_DESCR_TYPE = 21h |
REPORT_DESCR_TYPE = 22h |
PHYSICAL_DESCR_TYPE = 23h |
|
|
; LibUSB constatnts |
LIBUSB_REQUEST_TYPE_STANDARD = (0x00 shl 5) |
LIBUSB_REQUEST_TYPE_CLASS = (0x01 shl 5) |
LIBUSB_REQUEST_TYPE_VENDOR = (0x02 shl 5) |
LIBUSB_REQUEST_TYPE_RESERVED = (0x03 shl 5) |
|
LIBUSB_RECIPIENT_DEVICE = 0x00 |
LIBUSB_RECIPIENT_INTERFACE = 0x01 |
LIBUSB_RECIPIENT_ENDPOINT = 0x02 |
LIBUSB_RECIPIENT_OTHER = 0x03 |
|
LIBUSB_ENDPOINT_IN = 0x80 |
LIBUSB_ENDPOINT_OUT = 0x00 |
|
; FTDI Constants |
FTDI_DEVICE_OUT_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_OUT) |
FTDI_DEVICE_IN_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_IN) |
|
; Requests |
;Definitions for flow control |
SIO_RESET =0 ;Reset the port |
SIO_MODEM_CTRL =1 ;Set the modem control register |
SIO_SET_FLOW_CTRL =2 ;Set flow control register |
SIO_SET_BAUD_RATE =3 ;Set baud rate |
SIO_SET_DATA =4 ;Set the data characteristics of the port |
|
SIO_RESET_REQUEST =SIO_RESET |
SIO_SET_BAUDRATE_REQUEST =SIO_SET_BAUD_RATE |
SIO_SET_DATA_REQUEST =SIO_SET_DATA |
SIO_SET_FLOW_CTRL_REQUEST =SIO_SET_FLOW_CTRL |
SIO_SET_MODEM_CTRL_REQUEST =SIO_MODEM_CTRL |
SIO_POLL_MODEM_STATUS_REQUEST=0x05 |
SIO_SET_EVENT_CHAR_REQUEST =0x06 |
SIO_SET_ERROR_CHAR_REQUEST =0x07 |
SIO_SET_LATENCY_TIMER_REQUEST=0x09 |
SIO_GET_LATENCY_TIMER_REQUEST=0x0A |
SIO_SET_BITMODE_REQUEST =0x0B |
SIO_READ_PINS_REQUEST =0x0C |
SIO_READ_EEPROM_REQUEST =0x90 |
SIO_WRITE_EEPROM_REQUEST =0x91 |
SIO_ERASE_EEPROM_REQUEST =0x92 |
|
|
SIO_RESET_SIO=0 |
SIO_RESET_PURGE_RX=1 |
SIO_RESET_PURGE_TX=2 |
|
SIO_DISABLE_FLOW_CTRL=0x0 |
SIO_RTS_CTS_HS =(0x1 shl 8) |
SIO_DTR_DSR_HS =(0x2 shl 8) |
SIO_XON_XOFF_HS=(0x4 shl 8) |
|
SIO_SET_DTR_MASK=0x1 |
SIO_SET_DTR_HIGH=( 1 or ( SIO_SET_DTR_MASK shl 8)) |
SIO_SET_DTR_LOW =( 0 or ( SIO_SET_DTR_MASK shl 8)) |
SIO_SET_RTS_MASK=0x2 |
SIO_SET_RTS_HIGH=( 2 or ( SIO_SET_RTS_MASK shl 8 )) |
SIO_SET_RTS_LOW =( 0 or ( SIO_SET_RTS_MASK shl 8 )) |
|
SIO_RTS_CTS_HS =(0x1 shl 8) |
|
;strings |
my_driver db 'usbother',0 |
nomemory_msg db 'K : no memory',13,10,0 |
|
; Structures |
struct ftdi_context |
chipType db ? |
baudrate dd ? |
bitbangEnabled db ? |
readBufPtr dd ? |
readBufOffs dd ? |
readBufChunkSize dd ? |
writeBufChunkSize dd ? |
interface dd ? |
index dd ? |
inEP dd ? |
outEP dd ? |
nullP dd ? |
next_context dd ? |
ends |
|
struct IOCTL |
handle dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
ends |
|
struct usb_descr |
bcdUSB dw ? |
bDeviceClass db ? |
bDeviceSubClass db ? |
bDeviceProtocol db ? |
bMaxPacketSize0 db ? |
idVendor dw ? |
idProduct dw ? |
bcdDevice dw ? |
iManufacturer db ? |
iProduct db ? |
iSerialNumber db ? |
bNumConfigurations db ? |
ends |
|
section '.flat' code readable align 16 |
; The start procedure. |
proc START stdcall, .reason:DWORD |
|
xor eax, eax ; initialize return value |
cmp [.reason], 1 ; compare the argument |
jnz .nothing |
call linkedlist.init |
stdcall RegUSBDriver, my_driver, service_proc, usb_functions |
|
.nothing: |
ret 4 |
endp |
|
|
proc AddDevice stdcall uses ebx, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD |
|
stdcall USBGetParam, [.config_pipe], 0 |
cmp [eax+usb_descr.idVendor], 0x0403 |
jnz .notftdi |
DEBUGF 1,'K : FTDI USB device detected\n' |
movi eax, sizeof.ftdi_context |
call Kmalloc |
test eax, eax |
jnz @f |
mov esi, nomemory_msg |
call SysMsgBoardStr |
xor eax, eax |
jmp .nothing |
@@: |
DEBUGF 1,'K : Adding struct to list %x\n', eax |
call linkedlist.add |
|
mov ebx, [.config_pipe] |
mov [eax + ftdi_context.nullP], ebx |
|
DEBUGF 1,'K : Open first pipe\n' |
mov ebx, eax |
stdcall USBOpenPipe, [.config_pipe], 0x81, 0x40, BULK_PIPE, 0 |
mov [ebx + ftdi_context.inEP], eax |
DEBUGF 1,'K : Open second pipe\n' |
stdcall USBOpenPipe, [.config_pipe], 0x02, 0x40, BULK_PIPE, 0 |
mov [ebx + ftdi_context.outEP], eax |
|
.nothing: |
ret |
.notftdi: |
DEBUGF 1,'K : Skipping not FTDI device\n' |
xor eax, eax |
ret |
endp |
|
|
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
|
align 4 |
proc service_proc stdcall uses ebx esi edi, ioctl:DWORD |
locals |
ConfPacket rb 8 |
EventData rd 2 |
endl |
mov edi, [ioctl] |
mov eax, [edi + io_code] |
DEBUGF 1,'K : FTDI got the request: %d\n', eax |
test eax, eax ;0 |
jz .version |
dec eax ;1 |
jz .ftdi_get_list |
dec eax ;2 |
jz .ftdi_set_bitmode |
|
.version: |
.endswitch: |
xor eax, eax |
ret |
|
.ftdi_set_bitmode: |
DEBUGF 1,'K : FTDI Seting bitmode\n' |
call CreateEvent |
DEBUGF 1,'K : Event created %x %x\n' , eax, edx |
mov [EventData], eax |
mov [EventData+1], edx |
mov si, (FTDI_DEVICE_IN_REQTYPE) + (SIO_SET_BITMODE_REQUEST shl 8) |
mov word[ConfPacket], si |
mov edi, [edi+input] |
mov si, word[edi+1] |
DEBUGF 1,'K : Pin value is %x\n', si |
mov word[ConfPacket+4], si |
mov ebx, [edi] |
lea esi, [ConfPacket] |
lea edi, [EventData] |
stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP], esi, 0, 0, control_callback, edi, 0 |
DEBUGF 1, 'K : Returned value is %d\n', eax |
call WaitEvent |
jmp .endswitch |
.ftdi_read_pins: |
DEBUGF 1,'K : FTDI Reading pins\n' |
call CreateEvent |
mov [EventData], eax |
mov [EventData+1], edx |
mov eax, FTDI_DEVICE_IN_REQTYPE + (SIO_READ_PINS_REQUEST shl 8) |
mov dword[ConfPacket], eax |
jmp .endswitch |
.ftdi_get_list: |
call linkedlist.gethead |
DEBUGF 1, 'K : FTDI Device pointer %x\n' , eax |
mov edi, [edi+output] |
mov edi, eax |
mov eax, 4 |
mov edi, [ioctl] |
mov [edi+out_size], eax |
jmp .endswitch |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
|
|
align 4 |
proc control_callback stdcall uses ebx, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD |
|
mov eax, [.calldata] |
mov ebx, [.calldata+1] |
call RaiseEvent |
DEBUGF 1, 'K : status is %d\n', [.status+24h] |
ret |
endp |
|
|
proc DeviceDisconnected stdcall uses ebx esi edi, .device_data:DWORD |
|
DEBUGF 1, 'K : FTDI deleting device data\n' |
mov eax, [.device_data] |
;call linkedlist.delete |
endp |
|
include 'linkedlist.inc' |
|
; Exported variable: kernel API version. |
align 4 |
version dd 50005h |
; Structure with callback functions. |
usb_functions: |
dd 12 |
dd AddDevice |
dd DeviceDisconnected |
|
;for DEBUGF macro |
include_debug_strings |
|
|
|
|
; for uninitialized data |
;section '.data' data readable writable align 16 |