From 7dce54fc55dd9b700d3ebb4691d778de8f954d1e Mon Sep 17 00:00:00 2001 From: CleverMouse Date: Fri, 22 Aug 2014 09:54:27 +0000 Subject: [PATCH] convert usbhid and usbstor to PE git-svn-id: svn://kolibrios.org@5051 a494cfbc-eb01-0410-851d-a64ba20cac60 --- data/common/Makefile.main | 6 +- .../usb}/usbhid/keyboard.inc | 30 +- .../drivers => drivers/usb}/usbhid/mouse.inc | 6 +- .../drivers => drivers/usb}/usbhid/report.inc | 34 +- .../drivers => drivers/usb}/usbhid/sort.inc | 0 .../usb}/usbhid/unclaimed.inc | 0 .../drivers => drivers/usb}/usbhid/usbhid.asm | 65 ++- .../trunk/drivers => drivers/usb}/usbstor.asm | 414 ++++++++---------- 8 files changed, 261 insertions(+), 294 deletions(-) rename {kernel/trunk/drivers => drivers/usb}/usbhid/keyboard.inc (96%) rename {kernel/trunk/drivers => drivers/usb}/usbhid/mouse.inc (98%) rename {kernel/trunk/drivers => drivers/usb}/usbhid/report.inc (99%) rename {kernel/trunk/drivers => drivers/usb}/usbhid/sort.inc (100%) rename {kernel/trunk/drivers => drivers/usb}/usbhid/unclaimed.inc (100%) rename {kernel/trunk/drivers => drivers/usb}/usbhid/usbhid.asm (94%) rename {kernel/trunk/drivers => drivers/usb}/usbstor.asm (86%) diff --git a/data/common/Makefile.main b/data/common/Makefile.main index bbfb88a916..c0f0c18aac 100644 --- a/data/common/Makefile.main +++ b/data/common/Makefile.main @@ -134,8 +134,6 @@ FASM_PROGRAMS:=\ drivers/sb16.obj:DRIVERS/SB16.OBJ:$(KERNEL)/drivers/sb16/sb16.asm \ drivers/sound.obj:DRIVERS/SOUND.OBJ:$(KERNEL)/drivers/sound.asm \ drivers/intelac97.obj:DRIVERS/INTELAC97.OBJ:$(KERNEL)/drivers/intelac97.asm \ - drivers/usbhid.obj:DRIVERS/USBHID.OBJ:$(KERNEL)/drivers/usbhid/usbhid.asm \ - drivers/usbstor.obj:DRIVERS/USBSTOR.OBJ:$(KERNEL)/drivers/usbstor.asm \ drivers/vt823x.obj:DRIVERS/VT823X.OBJ:$(KERNEL)/drivers/vt823x.asm \ drivers/3c59x.obj:DRIVERS/3C59X.OBJ:$(REPOSITORY)/drivers/ethernet/3c59x.asm \ File|Managers/kfar:File|Managers/KFAR:$(PROGS)/fs/kfar/trunk/kfar.asm \ @@ -221,11 +219,13 @@ FASM_PROGRAMS_PESTRIP:=\ drivers/rhine.sys:DRIVERS/RHINE.SYS:$(REPOSITORY)/drivers/ethernet/rhine.asm \ drivers/rtl8029.sys:DRIVERS/RTL8029.SYS:$(REPOSITORY)/drivers/ethernet/RTL8029.asm \ drivers/rtl8139.sys:DRIVERS/RTL8139.SYS:$(REPOSITORY)/drivers/ethernet/RTL8139.asm \ - drivers/rtl8169.sys:DRIVERS/RTL8169.SYS:$(REPOSITORY)/drivers/ethernet/RTL8169.asm \ + drivers/rtl8169.sys:DRIVERS/RTL8169.SYS:$(REPOSITORY)/drivers/ethernet/RTL8169.asm \ drivers/sis900.sys:DRIVERS/SIS900.SYS:$(REPOSITORY)/drivers/ethernet/sis900.asm \ drivers/uhci.sys:DRIVERS/UHCI.SYS:$(REPOSITORY)/drivers/usb/uhci.asm \ drivers/ohci.sys:DRIVERS/OHCI.SYS:$(REPOSITORY)/drivers/usb/ohci.asm \ drivers/ehci.sys:DRIVERS/EHCI.SYS:$(REPOSITORY)/drivers/usb/ehci.asm \ + drivers/usbhid.sys:DRIVERS/USBHID.SYS:$(REPOSITORY)/drivers/usb/usbhid/usbhid.asm \ + drivers/usbstor.sys:DRIVERS/USBSTOR.SYS:$(REPOSITORY)/drivers/usb/usbstor.asm \ drivers/rdc.sys:DRIVERS/RDC.SYS:$(REPOSITORY)/drivers/video/rdc.asm \ drivers/ps2mouse.sys:DRIVERS/PS2MOUSE.SYS:$(REPOSITORY)/drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm \ drivers/tmpdisk.sys:DRIVERS/TMPDISK.SYS:$(REPOSITORY)/drivers/disk/tmpdisk.asm \ diff --git a/kernel/trunk/drivers/usbhid/keyboard.inc b/drivers/usb/usbhid/keyboard.inc similarity index 96% rename from kernel/trunk/drivers/usbhid/keyboard.inc rename to drivers/usb/usbhid/keyboard.inc index 139dcd42ad..3e776ee550 100644 --- a/kernel/trunk/drivers/usbhid/keyboard.inc +++ b/drivers/usb/usbhid/keyboard.inc @@ -60,7 +60,7 @@ ends proc keyboard_driver_add_device ; 1. Allocate memory for keyboard_device_data. If failed, return NULL. movi eax, sizeof.keyboard_device_data - call Kmalloc + invoke Kmalloc test eax, eax jz .nothing ; 2. Initialize keyboard_device_data: store pointer to USB layer data, @@ -154,7 +154,7 @@ proc keyboard_driver_add_device ; store pointer to keyboard_device_data in the stack push eax ; call kernel API - stdcall RegKeyboard, kbd_functions, eax + invoke RegKeyboard, kbd_functions, eax ; restore pointer to keyboard_device_data from the stack, ; putting keyboard handle from API to the stack xchg eax, [esp] @@ -167,7 +167,7 @@ proc keyboard_driver_add_device .nothing: ret .fail_free: - call Kfree + invoke Kfree xor eax, eax ret endp @@ -179,10 +179,10 @@ proc keyboard_driver_disconnect ; 1. If an autorepeat timer is active, stop it. cmp [edi+keyboard_device_data.timer], 0 jz @f - stdcall CancelTimerHS, [edi+keyboard_device_data.timer] + invoke CancelTimerHS, [edi+keyboard_device_data.timer] @@: ; 2. Unregister keyboard in the kernel. - stdcall DelKeyboard, [edi+keyboard_device_data.handle] + invoke DelKeyboard, [edi+keyboard_device_data.handle] ; We should free data in CloseKeyboard, not here. ret endp @@ -245,11 +245,11 @@ end if mov eax, [edi+keyboard_device_data.timer] test eax, eax jz @f - stdcall CancelTimerHS, eax + invoke CancelTimerHS, eax @@: ; 1h. Start the new autorepeat timer with 250 ms initial delay ; and 50 ms subsequent delays. - stdcall TimerHS, 25, 5, autorepeat_timer, edi + invoke TimerHS, 25, 5, autorepeat_timer, edi mov [edi+keyboard_device_data.timer], eax if ~HID_DUMP_UNCLAIMED .unclaimed: @@ -265,7 +265,7 @@ end if mov eax, [edi+keyboard_device_data.timer] test eax, eax jz @f - stdcall CancelTimerHS, eax + invoke CancelTimerHS, eax mov [edi+keyboard_device_data.timer], 0 @@: pop ecx @@ -321,10 +321,10 @@ end if jnc @f push ecx mov ecx, 0xE0 - call SetKeyboardData + invoke SetKeyboardData pop ecx @@: - call SetKeyboardData + invoke SetKeyboardData ret endp @@ -359,7 +359,7 @@ virtual at esp .device_data dd ? end virtual mov eax, [.device_data] - call Kfree + invoke Kfree ret 4 endp @@ -392,7 +392,7 @@ endl add eax, 8 + 3 and eax, not 3 push eax - call Kmalloc + invoke Kmalloc pop ecx test eax, eax jz .nothing @@ -444,14 +444,14 @@ endl or edx, [ebx+usb_device_data.interface_number] mov [eax+4], edx ; 8. Submit output control request. - stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ + invoke USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ eax, edi, [size], after_set_keyboard_lights, ebx, 0 ; If failed, free the buffer now. ; If succeeded, the callback will free the buffer. test eax, eax jnz .nothing lea eax, [edi-8] - call Kfree + invoke Kfree .nothing: ret endp @@ -470,6 +470,6 @@ end virtual ; Ignore status, just free the buffer allocated by SetKeyboardLights. mov eax, [.buffer] sub eax, 8 - call Kfree + invoke Kfree ret 20 endp diff --git a/kernel/trunk/drivers/usbhid/mouse.inc b/drivers/usb/usbhid/mouse.inc similarity index 98% rename from kernel/trunk/drivers/usbhid/mouse.inc rename to drivers/usb/usbhid/mouse.inc index 7cd6807b0c..b52e938a2e 100644 --- a/kernel/trunk/drivers/usbhid/mouse.inc +++ b/drivers/usb/usbhid/mouse.inc @@ -34,7 +34,7 @@ ends proc mouse_driver_add_device ; Just allocate memory; no initialization needed. movi eax, sizeof.mouse_device_data - call Kmalloc + invoke Kmalloc ret endp @@ -44,7 +44,7 @@ endp proc mouse_driver_disconnect ; Free the allocated memory. mov eax, edi - call Kfree + invoke Kfree ret endp @@ -153,7 +153,7 @@ endp ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) proc mouse_driver_end_packet ; Call the kernel, passing collected state. - stdcall SetMouseData, \ + invoke SetMouseData, \ [edi+mouse_device_data.buttons], \ [edi+mouse_device_data.dx], \ [edi+mouse_device_data.dy], \ diff --git a/kernel/trunk/drivers/usbhid/report.inc b/drivers/usb/usbhid/report.inc similarity index 99% rename from kernel/trunk/drivers/usbhid/report.inc rename to drivers/usb/usbhid/report.inc index a54432729c..a6695dc526 100644 --- a/kernel/trunk/drivers/usbhid/report.inc +++ b/drivers/usb/usbhid/report.inc @@ -353,7 +353,7 @@ parse_descr_label: mov [last_collection], eax ; 1b. Allocate state of global items. movi eax, sizeof.global_items - call Kmalloc + invoke Kmalloc test eax, eax jz .memory_error ; 1c. Zero-initialize it and move pointer to edi. @@ -373,7 +373,7 @@ parse_descr_label: test eax, eax jz @f push [eax+usage_list_item.next] - call Kfree + invoke Kfree pop eax jmp @b @@: @@ -496,7 +496,7 @@ end if cmp [ebx+report_set.data], 0 jnz .invalid_report mov eax, 256*4 - call Kmalloc + invoke Kmalloc test eax, eax jz .memory_error mov [ebx+report_set.data], eax @@ -521,7 +521,7 @@ end if jnz .report_allocated ; 7b. Allocate. movi eax, sizeof.report - call Kmalloc + invoke Kmalloc test eax, eax jz .memory_error ; 7c. Initialize. @@ -568,7 +568,7 @@ end if mov edx, [num_usage_ranges] lea eax, [eax+edx*sizeof.usage_range+4] @@: - call Kmalloc + invoke Kmalloc pop edx test eax, eax jz .memory_error @@ -688,7 +688,7 @@ end if ; allocate, zero-initialize, update parent, if there is one, ; make it current. movi eax, sizeof.collection - call Kmalloc + invoke Kmalloc test eax, eax jz .memory_error push eax edi @@ -817,7 +817,7 @@ end if ; For Push, allocate new global_items structure, ; initialize from the current one and make it current. movi eax, sizeof.global_items - call Kmalloc + invoke Kmalloc test eax, eax jz .memory_error push esi eax @@ -835,7 +835,7 @@ end if jz .invalid_report push eax xchg eax, edi - call Kfree + invoke Kfree pop edi jmp .item_parsed ; -------------------------------- Local items -------------------------------- @@ -862,7 +862,7 @@ end if push 1 .new_usage: movi eax, sizeof.usage_list_item - call Kmalloc + invoke Kmalloc pop edx test eax, eax jz .memory_error @@ -912,7 +912,7 @@ end if inc [delimiter_depth] push esi mov esi, delimiter_note - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi jmp .item_parsed .delimiter.close: @@ -954,14 +954,14 @@ end if .memory_error: mov esi, nomemory_msg .end_str: - call SysMsgBoardStr + invoke SysMsgBoardStr .end: ; Free all global_items structures. test edi, edi jz @f push [edi+global_items.next] xchg eax, edi - call Kfree + invoke Kfree pop edi jmp .end @@: @@ -971,7 +971,7 @@ end if test eax, eax jz @f push [eax+usage_list_item.next] - call Kfree + invoke Kfree pop eax jmp @b @@: @@ -1116,7 +1116,7 @@ macro hid_cleanup mov eax, [esi+collection.parent] @@: xchg eax, esi - call Kfree + invoke Kfree jmp .free_collections .collections_done: ; 3. Free all three report sets. @@ -1136,19 +1136,19 @@ macro hid_cleanup test eax, eax jz .field_done push [eax+report_field_group.next] - call Kfree + invoke Kfree pop eax jmp .field_loop .field_done: mov eax, [edi+report.next] xchg eax, edi - call Kfree + invoke Kfree jmp .report_loop .report_done: cmp [esi+report_set.numbered], 0 jz @f mov eax, [esi+report_set.data] - call Kfree + invoke Kfree @@: add esi, sizeof.report_set dec dword [esp] diff --git a/kernel/trunk/drivers/usbhid/sort.inc b/drivers/usb/usbhid/sort.inc similarity index 100% rename from kernel/trunk/drivers/usbhid/sort.inc rename to drivers/usb/usbhid/sort.inc diff --git a/kernel/trunk/drivers/usbhid/unclaimed.inc b/drivers/usb/usbhid/unclaimed.inc similarity index 100% rename from kernel/trunk/drivers/usbhid/unclaimed.inc rename to drivers/usb/usbhid/unclaimed.inc diff --git a/kernel/trunk/drivers/usbhid/usbhid.asm b/drivers/usb/usbhid/usbhid.asm similarity index 94% rename from kernel/trunk/drivers/usbhid/usbhid.asm rename to drivers/usb/usbhid/usbhid.asm index 0c4227131a..89d9226b1b 100644 --- a/kernel/trunk/drivers/usbhid/usbhid.asm +++ b/drivers/usb/usbhid/usbhid.asm @@ -1,5 +1,6 @@ -; standard driver stuff -format MS COFF +; standard driver stuff; version of driver model = 5 +format PE DLL native 0.05 +entry START DEBUG = 1 @@ -7,14 +8,8 @@ DEBUG = 1 __DEBUG__ = 1 __DEBUG_LEVEL__ = 1 -include '../proc32.inc' -include '../imports.inc' -include '../fdo.inc' include '../../struct.inc' -public START -public version - ; Compile-time settings. ; If set, the code will dump all descriptors as they are read to the debug board. USB_DUMP_DESCRIPTORS = 1 @@ -103,12 +98,17 @@ input_buffer dd ? ; buffer for input transfers control rb 8 ; control packet to device ends -section '.flat' code readable align 16 +section '.flat' code readable writable executable +include '../../macros.inc' +include '../../proc32.inc' +include '../../peimport.inc' +include '../../fdo.inc' ; The start procedure. proc START virtual at esp dd ? ; return address .reason dd ? +.cmdline dd ? end virtual ; 1. Test whether the procedure is called with the argument DRV_ENTRY. ; If not, return 0. @@ -118,10 +118,10 @@ end virtual ; 2. Register self as a USB driver. ; The name is my_driver = 'usbhid'; IOCTL interface is not supported; ; usb_functions is an offset of a structure with callback functions. - stdcall RegUSBDriver, my_driver, eax, usb_functions + invoke RegUSBDriver, my_driver, eax, usb_functions ; 3. Return the returned value of RegUSBDriver. .nothing: - ret 4 + ret endp ; This procedure is called when new HID device is detected. @@ -138,11 +138,11 @@ end virtual DEBUGF 1,'K : USB HID device detected\n' ; 1. Allocate memory for device data. movi eax, sizeof.usb_device_data - call Kmalloc + invoke Kmalloc test eax, eax jnz @f mov esi, nomemory_msg - call SysMsgBoardStr + invoke SysMsgBoardStr jmp .return0 @@: ; zero-initialize it @@ -215,11 +215,11 @@ end virtual .cfgerror: ; 6a. Print a message. mov esi, invalid_config_descr_msg - call SysMsgBoardStr + invoke SysMsgBoardStr ; 6b. Free memory allocated for device data. .free: xchg eax, ebx - call Kfree + invoke Kfree .return0: ; 6c. Return an error. xor eax, eax @@ -255,7 +255,7 @@ end virtual mov eax, [.config_pipe] mov [ebx+usb_device_data.configpipe], eax xor ecx, ecx - stdcall USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx + invoke USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx ; 7. Return pointer to usb_device_data. xchg eax, ebx jmp .nothing @@ -295,7 +295,7 @@ end virtual .cfgerror: mov esi, invalid_config_descr_msg .abort_with_msg: - call SysMsgBoardStr + invoke SysMsgBoardStr jmp .nothing .found_report: ; 2. Send request for the Report descriptor. @@ -304,7 +304,7 @@ end virtual test eax, eax jz .cfgerror push eax - call Kmalloc + invoke Kmalloc pop ecx ; If failed, say a message and stop initialization. mov esi, nomemory_msg @@ -320,13 +320,13 @@ end virtual (REPORT_DESCR_TYPE shl 24); descriptor type mov [edx+4], ax ; Interface number mov [edx+6], cx ; descriptor length - stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ + invoke USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ edx, esi, ecx, got_report, ebx, 0 ; 2c. If failed, free the buffer and stop initialization. test eax, eax jnz .nothing xchg eax, esi - call Kfree + invoke Kfree .nothing: pop esi ebx ; restore used registers to be stdcall ret 20 @@ -353,7 +353,7 @@ endl .generic_fail: push esi mov esi, reportfail - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi jmp .exit .has_something: @@ -386,7 +386,7 @@ end if movzx ecx, [edx+endpoint_descr.bEndpointAddress] movzx eax, [edx+endpoint_descr.bInterval] movzx edx, [edx+endpoint_descr.wMaxPacketSize] - stdcall USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax + invoke USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax test eax, eax jz got_report.exit mov [ebx+usb_device_data.intpipe], eax @@ -418,11 +418,11 @@ end if ; for extract_field_value. add eax, 4+3 and eax, not 3 - call Kmalloc + invoke Kmalloc test eax, eax jnz @f mov esi, nomemory_msg - call SysMsgBoardStr + invoke SysMsgBoardStr jmp got_report.exit @@: mov [ebx+usb_device_data.input_buffer], eax @@ -430,7 +430,7 @@ end if call ask_for_input got_report.exit: mov eax, [buffer] - call Kfree + invoke Kfree ret endp @@ -439,7 +439,7 @@ endp proc ask_for_input ; just call USBNormalTransferAsync with correct parameters, ; allow short packets - stdcall USBNormalTransferAsync, \ + invoke USBNormalTransferAsync, \ [ebx+usb_device_data.intpipe], \ [ebx+usb_device_data.input_buffer], \ [ebx+usb_device_data.input_transfer_size], \ @@ -492,7 +492,7 @@ endl ret .fail: mov esi, transfer_error_msg - call SysMsgBoardStr + invoke SysMsgBoardStr jmp .nothing endp @@ -507,12 +507,12 @@ end virtual ; 1. Say a message. mov ebx, [.device_data] mov esi, disconnectmsg - stdcall SysMsgBoardStr + invoke SysMsgBoardStr ; 2. Ask HID layer to release all HID-related resources. hid_cleanup ; 3. Free the device data. xchg eax, ebx - call Kfree + invoke Kfree ; 4. Return. .nothing: pop edi esi ebx ; restore used registers to be stdcall @@ -534,9 +534,7 @@ disconnectmsg db 'K : USB HID device disconnected',13,10,0 invalid_report_msg db 'K : report descriptor is invalid',13,10,0 delimiter_note db 'K : note: alternate usage ignored',13,10,0 -; Exported variable: kernel API version. align 4 -version dd 50005h ; Structure with callback functions. usb_functions: dd 12 @@ -549,5 +547,6 @@ include_debug_strings ; Workers data workers_globals -; for uninitialized data -;section '.data' data readable writable align 16 +align 4 +data fixups +end data diff --git a/kernel/trunk/drivers/usbstor.asm b/drivers/usb/usbstor.asm similarity index 86% rename from kernel/trunk/drivers/usbstor.asm rename to drivers/usb/usbstor.asm index ba5e21eea1..777257aa49 100644 --- a/kernel/trunk/drivers/usbstor.asm +++ b/drivers/usb/usbstor.asm @@ -1,5 +1,6 @@ -; standard driver stuff -format MS COFF +; standard driver stuff; version of driver model = 5 +format PE DLL native 0.05 +entry START DEBUG = 1 DUMP_PACKETS = 0 @@ -8,12 +9,7 @@ DUMP_PACKETS = 0 __DEBUG__ = 1 __DEBUG_LEVEL__ = 1 -include 'proc32.inc' -include 'imports.inc' -include 'fdo.inc' - -public START -public version +include '../struct.inc' ; USB constants DEVICE_DESCR_TYPE = 1 @@ -29,43 +25,37 @@ BULK_PIPE = 2 INTERRUPT_PIPE = 3 ; USB structures -virtual at 0 -config_descr: -.bLength db ? -.bDescriptorType db ? -.wTotalLength dw ? -.bNumInterfaces db ? -.bConfigurationValue db ? -.iConfiguration db ? -.bmAttributes db ? -.bMaxPower db ? -.sizeof: -end virtual +struct config_descr +bLength db ? +bDescriptorType db ? +wTotalLength dw ? +bNumInterfaces db ? +bConfigurationValue db ? +iConfiguration db ? +bmAttributes db ? +bMaxPower db ? +ends -virtual at 0 -interface_descr: -.bLength db ? -.bDescriptorType db ? -.bInterfaceNumber db ? -.bAlternateSetting db ? -.bNumEndpoints db ? -.bInterfaceClass db ? -.bInterfaceSubClass db ? -.bInterfaceProtocol db ? -.iInterface db ? -.sizeof: -end virtual +struct interface_descr +bLength db ? +bDescriptorType db ? +bInterfaceNumber db ? +bAlternateSetting db ? +bNumEndpoints db ? +bInterfaceClass db ? +bInterfaceSubClass db ? +bInterfaceProtocol db ? +iInterface db ? +ends -virtual at 0 -endpoint_descr: -.bLength db ? -.bDescriptorType db ? -.bEndpointAddress db ? -.bmAttributes db ? -.wMaxPacketSize dw ? -.bInterval db ? -.sizeof: -end virtual +struct endpoint_descr +bLength db ? +bDescriptorType db ? +bEndpointAddress db ? +bmAttributes db ? +wMaxPacketSize dw ? +bInterval db ? +ends ; Mass storage protocol constants, USB layer REQUEST_GETMAXLUN = 0xFE ; get max lun @@ -73,38 +63,28 @@ REQUEST_BORESET = 0xFF ; bulk-only reset ; Mass storage protocol structures, USB layer ; Sent from host to device in the first stage of an operation. -struc command_block_wrapper -{ -.Signature dd ? ; the constant 'USBC' -.Tag dd ? ; identifies response with request -.Length dd ? ; length of data-transport phase -.Flags db ? ; one of CBW_FLAG_* +struct command_block_wrapper +Signature dd ? ; the constant 'USBC' +Tag dd ? ; identifies response with request +Length dd ? ; length of data-transport phase +Flags db ? ; one of CBW_FLAG_* CBW_FLAG_OUT = 0 CBW_FLAG_IN = 80h -.LUN db ? ; addressed unit -.CommandLength db ? ; the length of the following field -.Command rb 16 -.sizeof: -} -virtual at 0 -command_block_wrapper command_block_wrapper -end virtual +LUN db ? ; addressed unit +CommandLength db ? ; the length of the following field +Command rb 16 +ends ; Sent from device to host in the last stage of an operation. -struc command_status_wrapper -{ -.Signature dd ? ; the constant 'USBS' -.Tag dd ? ; identifies response with request -.LengthRest dd ? ; .Length - (size of data which were transferred) -.Status db ? ; one of CSW_STATUS_* +struct command_status_wrapper +Signature dd ? ; the constant 'USBS' +Tag dd ? ; identifies response with request +LengthRest dd ? ; .Length - (size of data which were transferred) +Status db ? ; one of CSW_STATUS_* CSW_STATUS_OK = 0 CSW_STATUS_FAIL = 1 CSW_STATUS_FATAL = 2 -.sizeof: -} -virtual at 0 -command_status_wrapper command_status_wrapper -end virtual +ends ; Constants of SCSI layer SCSI_REQUEST_SENSE = 3 @@ -133,73 +113,62 @@ SENSE_MISCOMPARE = 14 ; Structures of SCSI layer ; Result of SCSI INQUIRY request. -struc inquiry_data -{ -.PeripheralDevice db ? ; lower 5 bits are PeripheralDeviceType +struct inquiry_data +PeripheralDevice db ? ; lower 5 bits are PeripheralDeviceType ; upper 3 bits are PeripheralQualifier -.RemovableMedium db ? ; upper bit is RemovableMedium +RemovableMedium db ? ; upper bit is RemovableMedium ; other bits are for compatibility -.Version db ? ; lower 3 bits are ANSI-Approved version +Version db ? ; lower 3 bits are ANSI-Approved version ; next 3 bits are ECMA version ; upper 2 bits are ISO version -.ResponseDataFormat db ? ; lower 4 bits are ResponseDataFormat +ResponseDataFormat db ? ; lower 4 bits are ResponseDataFormat ; bit 6 is TrmIOP ; bit 7 is AENC -.AdditionalLength db ? +AdditionalLength db ? dw ? ; reserved -.Flags db ? -.VendorID rb 8 ; vendor ID, big-endian -.ProductID rb 16 ; product ID, big-endian -.ProductRevBE dd ? ; product revision, big-endian -.sizeof: -} -virtual at 0 -inquiry_data inquiry_data -end virtual +Flags db ? +VendorID rb 8 ; vendor ID, big-endian +ProductID rb 16 ; product ID, big-endian +ProductRevBE dd ? ; product revision, big-endian +ends -struc sense_data -{ -.ErrorCode db ? ; lower 7 bits are error code: +struct sense_data +ErrorCode db ? ; lower 7 bits are error code: ; 70h = current error, ; 71h = deferred error ; upper bit is InformationValid -.SegmentNumber db ? ; number of segment descriptor +SegmentNumber db ? ; number of segment descriptor ; for commands COPY [+VERIFY], COMPARE -.SenseKey db ? ; bits 0-3 are one of SENSE_* +SenseKey db ? ; bits 0-3 are one of SENSE_* ; bit 4 is reserved ; bit 5 is IncorrectLengthIndicator ; bits 6 and 7 are used by ; sequential-access devices -.Information dd ? ; command-specific -.AdditionalLength db ? ; length of data starting here -.CommandInformation dd ? ; command-specific -.AdditionalSenseCode db ? ; \ more detailed error code -.AdditionalSenseQual db ? ; / standard has a large table of them -.FRUCode db ? ; which part of device has failed +Information dd ? ; command-specific +AdditionalLength db ? ; length of data starting here +CommandInformation dd ? ; command-specific +AdditionalSenseCode db ? ; \ more detailed error code +AdditionalSenseQual db ? ; / standard has a large table of them +FRUCode db ? ; which part of device has failed ; (device-specific, not regulated) -.SenseKeySpecific rb 3 ; depends on SenseKey -.sizeof: -} -virtual at 0 -sense_data sense_data -end virtual +SenseKeySpecific rb 3 ; depends on SenseKey +ends ; Device data ; USB Mass storage device has one or more logical units, identified by LUN, ; logical unit number. The highest value of LUN, that is, number of units ; minus 1, can be obtained via control request Get Max LUN. -virtual at 0 -usb_device_data: -.ConfigPipe dd ? ; configuration pipe -.OutPipe dd ? ; pipe for OUT bulk endpoint -.InPipe dd ? ; pipe for IN bulk endpoint -.MaxLUN dd ? ; maximum Logical Unit Number -.LogicalDevices dd ? ; pointer to array of usb_unit_data +struct usb_device_data +ConfigPipe dd ? ; configuration pipe +OutPipe dd ? ; pipe for OUT bulk endpoint +InPipe dd ? ; pipe for IN bulk endpoint +MaxLUN dd ? ; maximum Logical Unit Number +LogicalDevices dd ? ; pointer to array of usb_unit_data ; 1 for a connected USB device, 1 for each disk device ; the structure can be freed when .NumReferences decreases to zero -.NumReferences dd ? ; number of references -.ConfigRequest rb 8 ; buffer for configuration requests -.LengthRest dd ? ; Length - (size of data which were transferred) +NumReferences dd ? ; number of references +ConfigRequest rb 8 ; buffer for configuration requests +LengthRest dd ? ; Length - (size of data which were transferred) ; All requests to a given device are serialized, ; only one request to a given device can be processed at a time. ; The current request and all pending requests are organized in the following @@ -208,46 +177,42 @@ usb_device_data: ; data stage is not tagged (unlike command_*_wrapper), so the only way to know ; what request the data are associated with is to guarantee that only one ; request is processing at the time. -.RequestsQueue rd 2 -.QueueLock rd 3 ; protects .RequestsQueue -.InquiryData inquiry_data ; information about device +RequestsQueue rd 2 +QueueLock rd 3 ; protects .RequestsQueue +InquiryData inquiry_data ; information about device ; data for the current request -.Command command_block_wrapper -.DeviceDisconnected db ? -.Status command_status_wrapper -.Sense sense_data -.sizeof: -end virtual +Command command_block_wrapper +DeviceDisconnected db ? +Status command_status_wrapper +Sense sense_data +ends ; Information about one logical device. -virtual at 0 -usb_unit_data: -.Parent dd ? ; pointer to parent usb_device_data -.LUN db ? ; index in usb_device_data.LogicalDevices array -.DiskIndex db ? ; for name "usbhd" -.MediaPresent db ? +struct usb_unit_data +Parent dd ? ; pointer to parent usb_device_data +LUN db ? ; index in usb_device_data.LogicalDevices array +DiskIndex db ? ; for name "usbhd" +MediaPresent db ? db ? ; alignment -.DiskDevice dd ? ; handle of disk device or NULL -.SectorSize dd ? ; sector size +DiskDevice dd ? ; handle of disk device or NULL +SectorSize dd ? ; sector size ; For some devices, the first request to the medium fails with 'unit not ready'. ; When the code sees this status, it retries the command several times. ; Two following variables track the retry count and total time for those; ; total time is currently used only for debug output. -.UnitReadyAttempts dd ? -.TimerTicks dd ? -.sizeof: -end virtual +UnitReadyAttempts dd ? +TimerTicks dd ? +ends ; This is the structure for items in the queue usb_device_data.RequestsQueue. -virtual at 0 -request_queue_item: -.Next dd ? ; next item in the queue -.Prev dd ? ; prev item in the queue -.ReqBuilder dd ? ; procedure to fill command_block_wrapper -.Buffer dd ? ; input or output data +struct request_queue_item +Next dd ? ; next item in the queue +Prev dd ? ; prev item in the queue +ReqBuilder dd ? ; procedure to fill command_block_wrapper +Buffer dd ? ; input or output data ; (length is command_block_wrapper.Length) -.Callback dd ? ; procedure to call in the end of transfer -.UserData dd ? ; passed as-is to .Callback +Callback dd ? ; procedure to call in the end of transfer +UserData dd ? ; passed as-is to .Callback ; There are 3 possible stages of any request, one of them optional: ; command stage (host sends command_block_wrapper to device), ; optional data stage, @@ -255,16 +220,21 @@ request_queue_item: ; Also, if a request fails, the code queues additional request ; SCSI_REQUEST_SENSE; sense_data from SCSI_REQUEST_SENSE ; contains some information about the error. -.Stage db ? -.sizeof: -end virtual +Stage db ? +ends + +section '.flat' code readable writable executable +include '../proc32.inc' +include '../peimport.inc' +include '../fdo.inc' +include '../macros.inc' -section '.flat' code readable align 16 ; The start procedure. proc START virtual at esp dd ? ; return address .reason dd ? ; DRV_ENTRY or DRV_EXIT +.cmdline dd ? end virtual ; 1. Test whether the procedure is called with the argument DRV_ENTRY. ; If not, return 0. @@ -273,14 +243,14 @@ end virtual jnz .nothing ; 2. Initialize: we have one global mutex. mov ecx, free_numbers_lock - call MutexInit + invoke MutexInit ; 3. Register self as a USB driver. ; The name is my_driver = 'usbstor'; IOCTL interface is not supported; ; usb_functions is an offset of a structure with callback functions. - stdcall RegUSBDriver, my_driver, 0, usb_functions + invoke RegUSBDriver, my_driver, 0, usb_functions ; 4. Return the returned value of RegUSBDriver. .nothing: - ret 4 + ret endp ; Helper procedures to work with requests queue. @@ -298,12 +268,12 @@ virtual at esp .UserData dd ? ; request_queue_item.UserData end virtual ; 1. Allocate the memory for the request description. - movi eax, request_queue_item.sizeof - call Kmalloc + movi eax, sizeof.request_queue_item + invoke Kmalloc test eax, eax jnz @f mov esi, nomemory - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi ebx ret 20 @@: @@ -322,7 +292,7 @@ end virtual ; 4. Lock the queue. mov esi, [.device] lea ecx, [esi+usb_device_data.QueueLock] - call MutexLock + invoke MutexLock ; 5. Insert the request to the tail of the queue. add esi, usb_device_data.RequestsQueue mov edx, [esi+request_queue_item.Prev] @@ -340,7 +310,7 @@ end virtual call setup_request jmp .nothing .unlock: - call MutexUnlock + invoke MutexUnlock ; 9. Return. .nothing: pop esi ebx @@ -369,7 +339,7 @@ end if stdcall [ebx+request_queue_item.Callback], esi, [ebx+request_queue_item.UserData] ; 4. Lock the queue. lea ecx, [esi+usb_device_data.QueueLock] - call MutexLock + invoke MutexLock ; 5. Remove the request. lea edx, [esi+usb_device_data.RequestsQueue] mov eax, [ebx+request_queue_item.Next] @@ -378,14 +348,14 @@ end if ; 6. Free the request memory. push eax edx xchg eax, ebx - call Kfree + invoke Kfree pop edx ebx ; 7. If there is a next request, start processing. cmp ebx, edx jnz setup_request ; 8. Unlock the queue and return. lea ecx, [esi+usb_device_data.QueueLock] - call MutexUnlock + invoke MutexUnlock ret endp @@ -410,14 +380,14 @@ proc setup_request lea edx, [esi+usb_device_data.ConfigRequest] mov word [edx], (REQUEST_BORESET shl 8) + 21h ; class request mov word [edx+6], ax ; length = 0 - stdcall USBControlTransferAsync, [esi+usb_device_data.ConfigPipe], edx, eax, eax, recovery_callback1, esi, eax + invoke USBControlTransferAsync, [esi+usb_device_data.ConfigPipe], edx, eax, eax, recovery_callback1, esi, eax ; 2b. Fail here = fatal error. test eax, eax jz .fatal ; 2c. Otherwise, unlock the queue and return. recovery_callback1 will continue processing. .unlock_return: lea ecx, [esi+usb_device_data.QueueLock] - call MutexUnlock + invoke MutexUnlock ret .norecovery: ; 3. Send the command. Fail (no memory or device disconnected) = fatal error. @@ -429,7 +399,7 @@ proc setup_request ; 4. Fatal error. Set status = FATAL, unlock the queue, complete the request. mov [esi+usb_device_data.Status.Status], CSW_STATUS_FATAL lea ecx, [esi+usb_device_data.QueueLock] - call MutexUnlock + invoke MutexUnlock jmp complete_request endp @@ -453,11 +423,11 @@ proc request_stage1 if DUMP_PACKETS DEBUGF 1,'K : USBSTOR out:' mov eax, edx - mov ecx, command_block_wrapper.sizeof + mov ecx, sizeof.command_block_wrapper call debug_dump DEBUGF 1,'\n' end if - stdcall USBNormalTransferAsync, [esi+usb_device_data.OutPipe], edx, command_block_wrapper.sizeof, request_callback1, esi, 0 + invoke USBNormalTransferAsync, [esi+usb_device_data.OutPipe], edx, sizeof.command_block_wrapper, request_callback1, esi, 0 test eax, eax jz .nothing ; 5. If the next stage is data stage in the same direction, enqueue it here. @@ -473,7 +443,7 @@ if DUMP_PACKETS call debug_dump DEBUGF 1,'\n' end if - stdcall USBNormalTransferAsync, [esi+usb_device_data.OutPipe], [edx+request_queue_item.Buffer], [esi+usb_device_data.Command.Length], request_callback2, esi, 0 + invoke USBNormalTransferAsync, [esi+usb_device_data.OutPipe], [edx+request_queue_item.Buffer], [esi+usb_device_data.Command.Length], request_callback2, esi, 0 .nothing: ret endp @@ -551,7 +521,7 @@ end virtual cmp [ecx+usb_device_data.Command.Flags], 0 jns .nothing ; 5. Initiate USB transfer. If this fails, go to the error handler. - stdcall USBNormalTransferAsync, [ecx+usb_device_data.InPipe], [edx+request_queue_item.Buffer], [ecx+usb_device_data.Command.Length], request_callback2, ecx, 0 + invoke USBNormalTransferAsync, [ecx+usb_device_data.InPipe], [edx+request_queue_item.Buffer], [ecx+usb_device_data.Command.Length], request_callback2, ecx, 0 test eax, eax jz .error ; 6. The status stage goes to the same direction, enqueue it now. @@ -625,7 +595,7 @@ end if ; 4. Initiate USB transfer. If this fails, go to the error handler. ..enqueue_status: lea edx, [ecx+usb_device_data.Status] - stdcall USBNormalTransferAsync, [ecx+usb_device_data.InPipe], edx, command_status_wrapper.sizeof, request_callback3, ecx, 0 + invoke USBNormalTransferAsync, [ecx+usb_device_data.InPipe], edx, sizeof.command_status_wrapper, request_callback3, ecx, 0 test eax, eax jz .error .nothing: @@ -698,7 +668,7 @@ end if ; 6. Invalid status block. Say error, set status to fatal and complete request. push esi mov esi, invresponse - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi mov [esi+usb_device_data.Status.Status], CSW_STATUS_FATAL jmp .complete @@ -728,10 +698,10 @@ endp ; edx = first argument = pointer to usb_device_data.Command, ; second argument = custom data given to queue_request (ignored). proc request_sense_req - mov [edx+command_block_wrapper.Length], sense_data.sizeof + mov [edx+command_block_wrapper.Length], sizeof.sense_data mov [edx+command_block_wrapper.Flags], CBW_FLAG_IN mov byte [edx+command_block_wrapper.Command+0], SCSI_REQUEST_SENSE - mov byte [edx+command_block_wrapper.Command+4], sense_data.sizeof + mov byte [edx+command_block_wrapper.Command+4], sizeof.sense_data ret 8 endp @@ -780,25 +750,25 @@ end virtual jz .known ; 1c. If the device is unknown, print a message and go to 11c. mov esi, unkdevice - call SysMsgBoardStr + invoke SysMsgBoardStr jmp .nothing ; 1d. If the device uses known command set, print a message and continue ; configuring. .known: push esi mov esi, okdevice - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi ; 2. Allocate memory for internal device data. ; 2a. Call the kernel. - mov eax, usb_device_data.sizeof - call Kmalloc + mov eax, sizeof.usb_device_data + invoke Kmalloc ; 2b. Check return value. test eax, eax jnz @f ; 2c. If failed, say a message and go to 11c. mov esi, nomemory - call SysMsgBoardStr + invoke SysMsgBoardStr jmp .nothing @@: ; 2d. If succeeded, zero the contents and continue configuring. @@ -829,7 +799,7 @@ end virtual mov [eax+request_queue_item.Next], eax mov [eax+request_queue_item.Prev], eax lea ecx, [ebx+usb_device_data.QueueLock] - call MutexInit + invoke MutexInit ; Bulk-only mass storage devices use one OUT bulk endpoint for sending ; command/data and one IN bulk endpoint for receiving data/status. ; Look for those endpoints. @@ -862,9 +832,9 @@ end virtual jnz .lookep ; 5. Check that the descriptor contains all required data and all data are ; readable. The opposite is an error. - cmp byte [esi+endpoint_descr.bLength], endpoint_descr.sizeof + cmp byte [esi+endpoint_descr.bLength], sizeof.endpoint_descr jb .errorep - lea ecx, [esi+endpoint_descr.sizeof] + lea ecx, [esi+sizeof.endpoint_descr] cmp ecx, edx ja .errorep ; 6. Check that the endpoint is bulk endpoint. The opposite is an error. @@ -887,7 +857,7 @@ end virtual movzx edx, [esi+endpoint_descr.wMaxPacketSize] movzx eax, [esi+endpoint_descr.bInterval] ; not used for USB1, may be important for USB2 ; 9c. Call the kernel. - stdcall USBOpenPipe, [ebx+usb_device_data.ConfigPipe], ecx, edx, BULK_PIPE, eax + invoke USBOpenPipe, [ebx+usb_device_data.ConfigPipe], ecx, edx, BULK_PIPE, eax ; 9d. Restore registers. pop edx ecx ; 9e. Check result. If failed, go to 11b. @@ -907,7 +877,7 @@ end virtual .free: ; 11b. Free the allocated usb_device_data. xchg eax, ebx - call Kfree + invoke Kfree .nothing: ; 11c. Return an error. xor eax, eax @@ -922,7 +892,7 @@ end virtual if DUMP_PACKETS DEBUGF 1,'K : GETMAXLUN: %x %x %x %x %x %x %x %x\n',[eax]:2,[eax+1]:2,[eax+2]:2,[eax+3]:2,[eax+4]:2,[eax+5]:2,[eax+6]:2,[eax+7]:2 end if - stdcall USBControlTransferAsync, [ebx+usb_device_data.ConfigPipe], eax, ecx, 1, known_lun_callback, ebx, 0 + invoke USBControlTransferAsync, [ebx+usb_device_data.ConfigPipe], eax, ecx, 1, known_lun_callback, ebx, 0 ; 13. Return with pointer to device data as returned value. xchg eax, ebx .return: @@ -955,15 +925,15 @@ end virtual mov eax, [ebx+usb_device_data.MaxLUN] inc eax DEBUGF 1,'K : %d logical unit(s)\n',eax - imul eax, usb_unit_data.sizeof + imul eax, sizeof.usb_unit_data push ebx - call Kmalloc + invoke Kmalloc pop ebx ; If failed, print a message and do nothing. test eax, eax jnz @f mov esi, nomemory - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi ebx ret 20 @@: @@ -980,12 +950,12 @@ end virtual mov [esi+usb_unit_data.SectorSize], eax mov [esi+usb_unit_data.UnitReadyAttempts], eax push ecx - call GetTimerTicks + invoke GetTimerTicks mov [esi+usb_unit_data.TimerTicks], eax stdcall queue_request, ebx, test_unit_ready_req, 0, test_unit_ready_callback, esi pop ecx inc ecx - add esi, usb_unit_data.sizeof + add esi, sizeof.usb_unit_data cmp ecx, [ebx+usb_device_data.MaxLUN] jbe .looplun ; 4. Return. @@ -999,11 +969,11 @@ endp proc inquiry_req mov eax, [esp+8] mov al, [eax+usb_unit_data.LUN] - mov [edx+command_block_wrapper.Length], inquiry_data.sizeof + mov [edx+command_block_wrapper.Length], sizeof.inquiry_data mov [edx+command_block_wrapper.Flags], CBW_FLAG_IN mov [edx+command_block_wrapper.LUN], al mov byte [edx+command_block_wrapper.Command+0], SCSI_INQUIRY - mov byte [edx+command_block_wrapper.Command+4], inquiry_data.sizeof + mov byte [edx+command_block_wrapper.Command+4], sizeof.inquiry_data ret 8 endp @@ -1034,7 +1004,7 @@ proc inquiry_callback movi ebx, 1 mov ecx, new_disk_thread ; edx = parameter - call CreateThread + invoke CreateThread pop edi esi ecx ebx cmp eax, -1 jnz .nothing @@ -1046,7 +1016,7 @@ proc inquiry_callback ; 4. The command has failed. Print a message and do nothing. push esi mov esi, inquiry_fail - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi ret 8 endp @@ -1079,7 +1049,7 @@ end virtual ; possibly after some repetitions. Print a debug message showing ; number and time of those. Remember that media is ready and go to 4. DEBUGF 1,'K : media is ready\n' - call GetTimerTicks + invoke GetTimerTicks sub eax, [edx+usb_unit_data.TimerTicks] DEBUGF 1,'K : %d attempts, %d ticks\n',[edx+usb_unit_data.UnitReadyAttempts],eax inc [edx+usb_unit_data.MediaPresent] @@ -1094,7 +1064,7 @@ end virtual jz @f push ecx edx esi movi esi, 10 - call Sleep + invoke Sleep pop esi edx ecx stdcall queue_request, ecx, test_unit_ready_req, 0, test_unit_ready_callback, edx ret 8 @@ -1120,7 +1090,7 @@ end virtual ; 1. Generate name. ; 1a. Find a free index. mov ecx, free_numbers_lock - call MutexLock + invoke MutexLock xor eax, eax @@: bsf edx, [free_numbers+eax] @@ -1128,10 +1098,10 @@ end virtual add eax, 4 cmp eax, 4*4 jnz @b - call MutexUnlock + invoke MutexUnlock push esi mov esi, noindex - call SysMsgBoardStr + invoke SysMsgBoardStr pop esi jmp .drop_reference @@: @@ -1139,7 +1109,7 @@ end virtual btr [free_numbers+eax], edx lea eax, [eax*8+edx] push eax - call MutexUnlock + invoke MutexUnlock pop eax ; 1c. Generate a name of the form "usbhd" in the stack. mov dword [esp], 'usbh' @@ -1166,41 +1136,41 @@ end virtual ; 4. Notify the kernel about a new disk. ; 4a. Add a disk. ; stdcall queue_request, ecx, read_capacity_req, eax, read_capacity_callback, eax - stdcall DiskAdd, disk_functions, edx, esi, 0 + invoke DiskAdd, disk_functions, edx, esi, 0 mov ebx, eax ; 4b. If it failed, release the index and do nothing. test eax, eax jz .free_index ; 4c. Notify the kernel that a media is present. - stdcall DiskMediaChanged, eax, 1 + invoke DiskMediaChanged, eax, 1 ; 5. Lock the requests queue, check that device is not disconnected, ; store the disk handle, unlock the requests queue. mov ecx, [esi+usb_unit_data.Parent] add ecx, usb_device_data.QueueLock - call MutexLock + invoke MutexLock cmp byte [ecx+usb_device_data.DeviceDisconnected-usb_device_data.QueueLock], 0 jnz .disconnected mov [esi+usb_unit_data.DiskDevice], ebx - call MutexUnlock + invoke MutexUnlock jmp .exit .disconnected: - call MutexUnlock + invoke MutexUnlock stdcall disk_close, ebx jmp .exit .free_index: mov ecx, free_numbers_lock - call MutexLock + invoke MutexLock movzx eax, [esi+usb_unit_data.DiskIndex] bts [free_numbers], eax - call MutexUnlock + invoke MutexUnlock .drop_reference: mov esi, [esi+usb_unit_data.Parent] lock dec [esi+usb_device_data.NumReferences] jnz .exit mov eax, [esi+usb_device_data.LogicalDevices] - call Kfree + invoke Kfree xchg eax, esi - call Kfree + invoke Kfree .exit: or eax, -1 int 0x40 @@ -1216,7 +1186,7 @@ virtual at esp end virtual ; 1. Say a message. mov esi, disconnectmsg - call SysMsgBoardStr + invoke SysMsgBoardStr ; 2. Lock the requests queue, set .DeviceDisconnected to 1, ; unlock the requests queue. ; Locking is required for synchronization with queue_request: @@ -1229,9 +1199,9 @@ end virtual ; then queue_request tries to use them. mov esi, [.device] lea ecx, [esi+usb_device_data.QueueLock] - call MutexLock + invoke MutexLock mov [esi+usb_device_data.DeviceDisconnected], 1 - call MutexUnlock + invoke MutexUnlock ; 3. Drop one reference to the structure and check whether ; that was the last reference. lock dec [esi+usb_device_data.NumReferences] @@ -1247,9 +1217,9 @@ end virtual mov eax, [esi+usb_unit_data.DiskDevice] test eax, eax jz @f - stdcall DiskDel, eax + invoke DiskDel, eax @@: - add esi, usb_unit_data.sizeof + add esi, sizeof.usb_unit_data dec ebx jnz .diskdel ; In this case, some operations with those disks are still possible, @@ -1262,10 +1232,10 @@ end virtual mov eax, [esi+usb_device_data.LogicalDevices] test eax, eax jz @f - call Kfree + invoke Kfree @@: xchg eax, esi - call Kfree + invoke Kfree jmp .return endp @@ -1286,17 +1256,17 @@ virtual at esp end virtual mov esi, [.userdata] mov ecx, free_numbers_lock - call MutexLock + invoke MutexLock movzx eax, [esi+usb_unit_data.DiskIndex] bts [free_numbers], eax - call MutexUnlock + invoke MutexUnlock mov esi, [esi+usb_unit_data.Parent] lock dec [esi+usb_device_data.NumReferences] jnz .nothing mov eax, [esi+usb_device_data.LogicalDevices] - call Kfree + invoke Kfree xchg eax, esi - call Kfree + invoke Kfree .nothing: pop esi ebx ret 4 @@ -1308,7 +1278,7 @@ proc disk_querymedia stdcall uses ebx esi edi, \ ; 1. Create event for waiting. xor esi, esi xor ecx, ecx - call CreateEvent + invoke CreateEvent test eax, eax jz .generic_fail push eax @@ -1340,7 +1310,7 @@ end virtual ; 3. Wait for event. This destroys it. mov eax, [.event] mov ebx, [.event_code] - call WaitEvent + invoke WaitEvent ; 4. Get the status and results. pop ecx bswap ecx ; .LastLBA @@ -1403,7 +1373,7 @@ proc read_capacity_callback mov ebx, [ecx+disk_querymedia.event_code-disk_querymedia.locals] xor edx, edx xor esi, esi - call RaiseEvent + invoke RaiseEvent pop edi esi ebx ret 8 endp @@ -1443,7 +1413,7 @@ max_sectors_at_time = 0xFFFF ; 4. Create event for waiting. xor esi, esi xor ecx, ecx - call CreateEvent + invoke CreateEvent test eax, eax jz .generic_fail push eax ; .event @@ -1476,7 +1446,7 @@ end virtual ; 6. Wait for event. This destroys it. mov eax, [.event] mov ebx, [.event_code] - call WaitEvent + invoke WaitEvent ; 7. Get the status. If the operation has failed, abort. pop eax ; .status pop ecx ecx ; cleanup .event_code, .event @@ -1579,7 +1549,7 @@ end virtual mov ebx, [esi+disk_read_write.event_code-disk_read_write.locals] xor edx, edx xor esi, esi - call RaiseEvent + invoke RaiseEvent ; 6. Return. pop edi esi ebx ret 8 @@ -1599,9 +1569,7 @@ inquiry_fail db 'K : INQUIRY command failed',13,10,0 ;read_fail db 'K : READ command failed',13,10,0 noindex db 'K : failed to generate disk name',13,10,0 -; Exported variable: kernel API version. align 4 -version dd 50005h ; Structure with callback functions. usb_functions: dd usb_functions_end - usb_functions @@ -1620,12 +1588,12 @@ disk_functions: dd 0 ; adjust_cache_size: use default cache disk_functions_end: +data fixups +end data + free_numbers_lock rd 3 ; 128 devices should be enough for everybody free_numbers dd -1, -1, -1, -1 ; for DEBUGF macro include_debug_strings - -; for uninitialized data -section '.data' data readable writable align 16