Rev 4592 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4592 | Rev 5051 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ; standard driver stuff |
1 | ; standard driver stuff; version of driver model = 5 |
2 | format MS COFF |
2 | format PE DLL native 0.05 |
- | 3 | entry START |
|
Line 3... | Line 4... | ||
3 | 4 | ||
Line 4... | Line 5... | ||
4 | DEBUG = 1 |
5 | DEBUG = 1 |
5 | 6 | ||
6 | ; this is for DEBUGF macro from 'fdo.inc' |
7 | ; this is for DEBUGF macro from 'fdo.inc' |
Line 7... | Line -... | ||
7 | __DEBUG__ = 1 |
- | |
8 | __DEBUG_LEVEL__ = 1 |
- | |
9 | - | ||
10 | include '../proc32.inc' |
8 | __DEBUG__ = 1 |
Line 11... | Line -... | ||
11 | include '../imports.inc' |
- | |
12 | include '../fdo.inc' |
- | |
13 | include '../../struct.inc' |
- | |
14 | 9 | __DEBUG_LEVEL__ = 1 |
|
15 | public START |
10 | |
16 | public version |
11 | include '../../struct.inc' |
17 | 12 | ||
18 | ; Compile-time settings. |
13 | ; Compile-time settings. |
Line 101... | Line 96... | ||
101 | input_transfer_size dd ? ; input transfer size |
96 | input_transfer_size dd ? ; input transfer size |
102 | input_buffer dd ? ; buffer for input transfers |
97 | input_buffer dd ? ; buffer for input transfers |
103 | control rb 8 ; control packet to device |
98 | control rb 8 ; control packet to device |
104 | ends |
99 | ends |
Line 105... | Line 100... | ||
105 | 100 | ||
- | 101 | section '.flat' code readable writable executable |
|
- | 102 | include '../../macros.inc' |
|
- | 103 | include '../../proc32.inc' |
|
- | 104 | include '../../peimport.inc' |
|
106 | section '.flat' code readable align 16 |
105 | include '../../fdo.inc' |
107 | ; The start procedure. |
106 | ; The start procedure. |
108 | proc START |
107 | proc START |
109 | virtual at esp |
108 | virtual at esp |
110 | dd ? ; return address |
109 | dd ? ; return address |
- | 110 | .reason dd ? |
|
111 | .reason dd ? |
111 | .cmdline dd ? |
112 | end virtual |
112 | end virtual |
113 | ; 1. Test whether the procedure is called with the argument DRV_ENTRY. |
113 | ; 1. Test whether the procedure is called with the argument DRV_ENTRY. |
114 | ; If not, return 0. |
114 | ; If not, return 0. |
115 | xor eax, eax ; initialize return value |
115 | xor eax, eax ; initialize return value |
116 | cmp [.reason], 1 ; compare the argument |
116 | cmp [.reason], 1 ; compare the argument |
117 | jnz .nothing |
117 | jnz .nothing |
118 | ; 2. Register self as a USB driver. |
118 | ; 2. Register self as a USB driver. |
119 | ; The name is my_driver = 'usbhid'; IOCTL interface is not supported; |
119 | ; The name is my_driver = 'usbhid'; IOCTL interface is not supported; |
120 | ; usb_functions is an offset of a structure with callback functions. |
120 | ; usb_functions is an offset of a structure with callback functions. |
121 | stdcall RegUSBDriver, my_driver, eax, usb_functions |
121 | invoke RegUSBDriver, my_driver, eax, usb_functions |
122 | ; 3. Return the returned value of RegUSBDriver. |
122 | ; 3. Return the returned value of RegUSBDriver. |
123 | .nothing: |
123 | .nothing: |
124 | ret 4 |
124 | ret |
Line 125... | Line 125... | ||
125 | endp |
125 | endp |
126 | 126 | ||
127 | ; This procedure is called when new HID device is detected. |
127 | ; This procedure is called when new HID device is detected. |
Line 136... | Line 136... | ||
136 | .interface dd ? |
136 | .interface dd ? |
137 | end virtual |
137 | end virtual |
138 | DEBUGF 1,'K : USB HID device detected\n' |
138 | DEBUGF 1,'K : USB HID device detected\n' |
139 | ; 1. Allocate memory for device data. |
139 | ; 1. Allocate memory for device data. |
140 | movi eax, sizeof.usb_device_data |
140 | movi eax, sizeof.usb_device_data |
141 | call Kmalloc |
141 | invoke Kmalloc |
142 | test eax, eax |
142 | test eax, eax |
143 | jnz @f |
143 | jnz @f |
144 | mov esi, nomemory_msg |
144 | mov esi, nomemory_msg |
145 | call SysMsgBoardStr |
145 | invoke SysMsgBoardStr |
146 | jmp .return0 |
146 | jmp .return0 |
147 | @@: |
147 | @@: |
148 | ; zero-initialize it |
148 | ; zero-initialize it |
149 | mov edi, eax |
149 | mov edi, eax |
150 | xchg eax, ebx |
150 | xchg eax, ebx |
Line 213... | Line 213... | ||
213 | jbe @f |
213 | jbe @f |
214 | ; 6. An error occured during processing endpoint descriptor. |
214 | ; 6. An error occured during processing endpoint descriptor. |
215 | .cfgerror: |
215 | .cfgerror: |
216 | ; 6a. Print a message. |
216 | ; 6a. Print a message. |
217 | mov esi, invalid_config_descr_msg |
217 | mov esi, invalid_config_descr_msg |
218 | call SysMsgBoardStr |
218 | invoke SysMsgBoardStr |
219 | ; 6b. Free memory allocated for device data. |
219 | ; 6b. Free memory allocated for device data. |
220 | .free: |
220 | .free: |
221 | xchg eax, ebx |
221 | xchg eax, ebx |
222 | call Kfree |
222 | invoke Kfree |
223 | .return0: |
223 | .return0: |
224 | ; 6c. Return an error. |
224 | ; 6c. Return an error. |
225 | xor eax, eax |
225 | xor eax, eax |
226 | .nothing: |
226 | .nothing: |
227 | pop edi esi ebx ; restore used registers to be stdcall |
227 | pop edi esi ebx ; restore used registers to be stdcall |
Line 253... | Line 253... | ||
253 | mov [ebx+usb_device_data.interface_number], eax |
253 | mov [ebx+usb_device_data.interface_number], eax |
254 | mov [edx+4], eax ; set interface number, zero length |
254 | mov [edx+4], eax ; set interface number, zero length |
255 | mov eax, [.config_pipe] |
255 | mov eax, [.config_pipe] |
256 | mov [ebx+usb_device_data.configpipe], eax |
256 | mov [ebx+usb_device_data.configpipe], eax |
257 | xor ecx, ecx |
257 | xor ecx, ecx |
258 | stdcall USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx |
258 | invoke USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx |
259 | ; 7. Return pointer to usb_device_data. |
259 | ; 7. Return pointer to usb_device_data. |
260 | xchg eax, ebx |
260 | xchg eax, ebx |
261 | jmp .nothing |
261 | jmp .nothing |
262 | endp |
262 | endp |
Line 293... | Line 293... | ||
293 | add esi, 3 |
293 | add esi, 3 |
294 | jmp .look_report |
294 | jmp .look_report |
295 | .cfgerror: |
295 | .cfgerror: |
296 | mov esi, invalid_config_descr_msg |
296 | mov esi, invalid_config_descr_msg |
297 | .abort_with_msg: |
297 | .abort_with_msg: |
298 | call SysMsgBoardStr |
298 | invoke SysMsgBoardStr |
299 | jmp .nothing |
299 | jmp .nothing |
300 | .found_report: |
300 | .found_report: |
301 | ; 2. Send request for the Report descriptor. |
301 | ; 2. Send request for the Report descriptor. |
302 | ; 2a. Allocate memory. |
302 | ; 2a. Allocate memory. |
303 | movzx eax, [esi+hid_descr.subDescriptorLength] |
303 | movzx eax, [esi+hid_descr.subDescriptorLength] |
304 | test eax, eax |
304 | test eax, eax |
305 | jz .cfgerror |
305 | jz .cfgerror |
306 | push eax |
306 | push eax |
307 | call Kmalloc |
307 | invoke Kmalloc |
308 | pop ecx |
308 | pop ecx |
309 | ; If failed, say a message and stop initialization. |
309 | ; If failed, say a message and stop initialization. |
310 | mov esi, nomemory_msg |
310 | mov esi, nomemory_msg |
311 | test eax, eax |
311 | test eax, eax |
312 | jz .abort_with_msg |
312 | jz .abort_with_msg |
Line 318... | Line 318... | ||
318 | (6 shl 8) + \ ; GET_DESCRIPTOR |
318 | (6 shl 8) + \ ; GET_DESCRIPTOR |
319 | (0 shl 16) + \ ; descriptor index: there is only one report descriptor |
319 | (0 shl 16) + \ ; descriptor index: there is only one report descriptor |
320 | (REPORT_DESCR_TYPE shl 24); descriptor type |
320 | (REPORT_DESCR_TYPE shl 24); descriptor type |
321 | mov [edx+4], ax ; Interface number |
321 | mov [edx+4], ax ; Interface number |
322 | mov [edx+6], cx ; descriptor length |
322 | mov [edx+6], cx ; descriptor length |
323 | stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ |
323 | invoke USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ |
324 | edx, esi, ecx, got_report, ebx, 0 |
324 | edx, esi, ecx, got_report, ebx, 0 |
325 | ; 2c. If failed, free the buffer and stop initialization. |
325 | ; 2c. If failed, free the buffer and stop initialization. |
326 | test eax, eax |
326 | test eax, eax |
327 | jnz .nothing |
327 | jnz .nothing |
328 | xchg eax, esi |
328 | xchg eax, esi |
329 | call Kfree |
329 | invoke Kfree |
330 | .nothing: |
330 | .nothing: |
331 | pop esi ebx ; restore used registers to be stdcall |
331 | pop esi ebx ; restore used registers to be stdcall |
332 | ret 20 |
332 | ret 20 |
333 | endp |
333 | endp |
Line 351... | Line 351... | ||
351 | sub [length], 8 |
351 | sub [length], 8 |
352 | ja .has_something |
352 | ja .has_something |
353 | .generic_fail: |
353 | .generic_fail: |
354 | push esi |
354 | push esi |
355 | mov esi, reportfail |
355 | mov esi, reportfail |
356 | call SysMsgBoardStr |
356 | invoke SysMsgBoardStr |
357 | pop esi |
357 | pop esi |
358 | jmp .exit |
358 | jmp .exit |
359 | .has_something: |
359 | .has_something: |
360 | ; 3. Process descriptor. |
360 | ; 3. Process descriptor. |
361 | ; 3a. Dump it to the debug board, if enabled in compile-time setting. |
361 | ; 3a. Dump it to the debug board, if enabled in compile-time setting. |
Line 384... | Line 384... | ||
384 | ; 5. Open interrupt IN pipe. If failed, stop initialization. |
384 | ; 5. Open interrupt IN pipe. If failed, stop initialization. |
385 | mov edx, [ebx+usb_device_data.epdescr] |
385 | mov edx, [ebx+usb_device_data.epdescr] |
386 | movzx ecx, [edx+endpoint_descr.bEndpointAddress] |
386 | movzx ecx, [edx+endpoint_descr.bEndpointAddress] |
387 | movzx eax, [edx+endpoint_descr.bInterval] |
387 | movzx eax, [edx+endpoint_descr.bInterval] |
388 | movzx edx, [edx+endpoint_descr.wMaxPacketSize] |
388 | movzx edx, [edx+endpoint_descr.wMaxPacketSize] |
389 | stdcall USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax |
389 | invoke USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax |
390 | test eax, eax |
390 | test eax, eax |
391 | jz got_report.exit |
391 | jz got_report.exit |
392 | mov [ebx+usb_device_data.intpipe], eax |
392 | mov [ebx+usb_device_data.intpipe], eax |
393 | ; 6. Initialize buffer for input packet. |
393 | ; 6. Initialize buffer for input packet. |
394 | ; 6a. Find the length of input packet. |
394 | ; 6a. Find the length of input packet. |
Line 416... | Line 416... | ||
416 | mov [ebx+usb_device_data.input_transfer_size], eax |
416 | mov [ebx+usb_device_data.input_transfer_size], eax |
417 | ; 6b. Allocate memory for input packet: dword-align and add additional dword |
417 | ; 6b. Allocate memory for input packet: dword-align and add additional dword |
418 | ; for extract_field_value. |
418 | ; for extract_field_value. |
419 | add eax, 4+3 |
419 | add eax, 4+3 |
420 | and eax, not 3 |
420 | and eax, not 3 |
421 | call Kmalloc |
421 | invoke Kmalloc |
422 | test eax, eax |
422 | test eax, eax |
423 | jnz @f |
423 | jnz @f |
424 | mov esi, nomemory_msg |
424 | mov esi, nomemory_msg |
425 | call SysMsgBoardStr |
425 | invoke SysMsgBoardStr |
426 | jmp got_report.exit |
426 | jmp got_report.exit |
427 | @@: |
427 | @@: |
428 | mov [ebx+usb_device_data.input_buffer], eax |
428 | mov [ebx+usb_device_data.input_buffer], eax |
429 | ; 7. Submit a request for input packet and wait for input. |
429 | ; 7. Submit a request for input packet and wait for input. |
430 | call ask_for_input |
430 | call ask_for_input |
431 | got_report.exit: |
431 | got_report.exit: |
432 | mov eax, [buffer] |
432 | mov eax, [buffer] |
433 | call Kfree |
433 | invoke Kfree |
434 | ret |
434 | ret |
435 | endp |
435 | endp |
Line 436... | Line 436... | ||
436 | 436 | ||
437 | ; Helper procedure for got_report and got_input. |
437 | ; Helper procedure for got_report and got_input. |
438 | ; Submits a request for the next input packet. |
438 | ; Submits a request for the next input packet. |
439 | proc ask_for_input |
439 | proc ask_for_input |
440 | ; just call USBNormalTransferAsync with correct parameters, |
440 | ; just call USBNormalTransferAsync with correct parameters, |
441 | ; allow short packets |
441 | ; allow short packets |
442 | stdcall USBNormalTransferAsync, \ |
442 | invoke USBNormalTransferAsync, \ |
443 | [ebx+usb_device_data.intpipe], \ |
443 | [ebx+usb_device_data.intpipe], \ |
444 | [ebx+usb_device_data.input_buffer], \ |
444 | [ebx+usb_device_data.input_buffer], \ |
445 | [ebx+usb_device_data.input_transfer_size], \ |
445 | [ebx+usb_device_data.input_transfer_size], \ |
446 | got_input, ebx, \ |
446 | got_input, ebx, \ |
Line 490... | Line 490... | ||
490 | call ask_for_input |
490 | call ask_for_input |
491 | .nothing: |
491 | .nothing: |
492 | ret |
492 | ret |
493 | .fail: |
493 | .fail: |
494 | mov esi, transfer_error_msg |
494 | mov esi, transfer_error_msg |
495 | call SysMsgBoardStr |
495 | invoke SysMsgBoardStr |
496 | jmp .nothing |
496 | jmp .nothing |
497 | endp |
497 | endp |
Line 498... | Line 498... | ||
498 | 498 | ||
499 | ; This function is called by the USB subsystem when a device is disconnected. |
499 | ; This function is called by the USB subsystem when a device is disconnected. |
Line 505... | Line 505... | ||
505 | .device_data dd ? |
505 | .device_data dd ? |
506 | end virtual |
506 | end virtual |
507 | ; 1. Say a message. |
507 | ; 1. Say a message. |
508 | mov ebx, [.device_data] |
508 | mov ebx, [.device_data] |
509 | mov esi, disconnectmsg |
509 | mov esi, disconnectmsg |
510 | stdcall SysMsgBoardStr |
510 | invoke SysMsgBoardStr |
511 | ; 2. Ask HID layer to release all HID-related resources. |
511 | ; 2. Ask HID layer to release all HID-related resources. |
512 | hid_cleanup |
512 | hid_cleanup |
513 | ; 3. Free the device data. |
513 | ; 3. Free the device data. |
514 | xchg eax, ebx |
514 | xchg eax, ebx |
515 | call Kfree |
515 | invoke Kfree |
516 | ; 4. Return. |
516 | ; 4. Return. |
517 | .nothing: |
517 | .nothing: |
518 | pop edi esi ebx ; restore used registers to be stdcall |
518 | pop edi esi ebx ; restore used registers to be stdcall |
519 | ret 4 ; purge one dword argument to be stdcall |
519 | ret 4 ; purge one dword argument to be stdcall |
520 | endp |
520 | endp |
Line 532... | Line 532... | ||
532 | transfer_error_msg db 'K : USB transfer error, disabling HID device',13,10,0 |
532 | transfer_error_msg db 'K : USB transfer error, disabling HID device',13,10,0 |
533 | disconnectmsg db 'K : USB HID device disconnected',13,10,0 |
533 | disconnectmsg db 'K : USB HID device disconnected',13,10,0 |
534 | invalid_report_msg db 'K : report descriptor is invalid',13,10,0 |
534 | invalid_report_msg db 'K : report descriptor is invalid',13,10,0 |
535 | delimiter_note db 'K : note: alternate usage ignored',13,10,0 |
535 | delimiter_note db 'K : note: alternate usage ignored',13,10,0 |
Line 536... | Line -... | ||
536 | - | ||
537 | ; Exported variable: kernel API version. |
536 | |
538 | align 4 |
- | |
539 | version dd 50005h |
537 | align 4 |
540 | ; Structure with callback functions. |
538 | ; Structure with callback functions. |
541 | usb_functions: |
539 | usb_functions: |
542 | dd 12 |
540 | dd 12 |
543 | dd AddDevice |
541 | dd AddDevice |
Line 547... | Line 545... | ||
547 | include_debug_strings |
545 | include_debug_strings |
Line 548... | Line 546... | ||
548 | 546 | ||
549 | ; Workers data |
547 | ; Workers data |
Line -... | Line 548... | ||
- | 548 | workers_globals |
|
550 | workers_globals |
549 | |
551 | 550 | align 4 |