Rev 4932 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4932 | Rev 5051 | ||
---|---|---|---|
Line 58... | Line 58... | ||
58 | ; in: ebx -> usb_device_data, edi -> collection |
58 | ; in: ebx -> usb_device_data, edi -> collection |
59 | ; out: eax = device-specific data or NULL on error |
59 | ; out: eax = device-specific data or NULL on error |
60 | proc keyboard_driver_add_device |
60 | proc keyboard_driver_add_device |
61 | ; 1. Allocate memory for keyboard_device_data. If failed, return NULL. |
61 | ; 1. Allocate memory for keyboard_device_data. If failed, return NULL. |
62 | movi eax, sizeof.keyboard_device_data |
62 | movi eax, sizeof.keyboard_device_data |
63 | call Kmalloc |
63 | invoke Kmalloc |
64 | test eax, eax |
64 | test eax, eax |
65 | jz .nothing |
65 | jz .nothing |
66 | ; 2. Initialize keyboard_device_data: store pointer to USB layer data, |
66 | ; 2. Initialize keyboard_device_data: store pointer to USB layer data, |
67 | ; zero some fields, initialize bit positions to -1. |
67 | ; zero some fields, initialize bit positions to -1. |
68 | mov [eax+keyboard_device_data.usbdev], ebx |
68 | mov [eax+keyboard_device_data.usbdev], ebx |
Line 152... | Line 152... | ||
152 | pop esi ebx |
152 | pop esi ebx |
153 | ; 4. Register keyboard in the kernel. |
153 | ; 4. Register keyboard in the kernel. |
154 | ; store pointer to keyboard_device_data in the stack |
154 | ; store pointer to keyboard_device_data in the stack |
155 | push eax |
155 | push eax |
156 | ; call kernel API |
156 | ; call kernel API |
157 | stdcall RegKeyboard, kbd_functions, eax |
157 | invoke RegKeyboard, kbd_functions, eax |
158 | ; restore pointer to keyboard_device_data from the stack, |
158 | ; restore pointer to keyboard_device_data from the stack, |
159 | ; putting keyboard handle from API to the stack |
159 | ; putting keyboard handle from API to the stack |
160 | xchg eax, [esp] |
160 | xchg eax, [esp] |
161 | ; put keyboard handle from API from the stack to keyboard_device_data field |
161 | ; put keyboard handle from API from the stack to keyboard_device_data field |
162 | pop [eax+keyboard_device_data.handle] |
162 | pop [eax+keyboard_device_data.handle] |
Line 165... | Line 165... | ||
165 | jz .fail_free |
165 | jz .fail_free |
166 | ; 5. Return pointer to keyboard_device_data. |
166 | ; 5. Return pointer to keyboard_device_data. |
167 | .nothing: |
167 | .nothing: |
168 | ret |
168 | ret |
169 | .fail_free: |
169 | .fail_free: |
170 | call Kfree |
170 | invoke Kfree |
171 | xor eax, eax |
171 | xor eax, eax |
172 | ret |
172 | ret |
173 | endp |
173 | endp |
Line 174... | Line 174... | ||
174 | 174 | ||
Line 177... | Line 177... | ||
177 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
177 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
178 | proc keyboard_driver_disconnect |
178 | proc keyboard_driver_disconnect |
179 | ; 1. If an autorepeat timer is active, stop it. |
179 | ; 1. If an autorepeat timer is active, stop it. |
180 | cmp [edi+keyboard_device_data.timer], 0 |
180 | cmp [edi+keyboard_device_data.timer], 0 |
181 | jz @f |
181 | jz @f |
182 | stdcall CancelTimerHS, [edi+keyboard_device_data.timer] |
182 | invoke CancelTimerHS, [edi+keyboard_device_data.timer] |
183 | @@: |
183 | @@: |
184 | ; 2. Unregister keyboard in the kernel. |
184 | ; 2. Unregister keyboard in the kernel. |
185 | stdcall DelKeyboard, [edi+keyboard_device_data.handle] |
185 | invoke DelKeyboard, [edi+keyboard_device_data.handle] |
186 | ; We should free data in CloseKeyboard, not here. |
186 | ; We should free data in CloseKeyboard, not here. |
187 | ret |
187 | ret |
188 | endp |
188 | endp |
Line 189... | Line 189... | ||
189 | 189 | ||
Line 243... | Line 243... | ||
243 | call .send_key |
243 | call .send_key |
244 | ; 1g. Stop the previous autorepeat timer, if any. |
244 | ; 1g. Stop the previous autorepeat timer, if any. |
245 | mov eax, [edi+keyboard_device_data.timer] |
245 | mov eax, [edi+keyboard_device_data.timer] |
246 | test eax, eax |
246 | test eax, eax |
247 | jz @f |
247 | jz @f |
248 | stdcall CancelTimerHS, eax |
248 | invoke CancelTimerHS, eax |
249 | @@: |
249 | @@: |
250 | ; 1h. Start the new autorepeat timer with 250 ms initial delay |
250 | ; 1h. Start the new autorepeat timer with 250 ms initial delay |
251 | ; and 50 ms subsequent delays. |
251 | ; and 50 ms subsequent delays. |
252 | stdcall TimerHS, 25, 5, autorepeat_timer, edi |
252 | invoke TimerHS, 25, 5, autorepeat_timer, edi |
253 | mov [edi+keyboard_device_data.timer], eax |
253 | mov [edi+keyboard_device_data.timer], eax |
254 | if ~HID_DUMP_UNCLAIMED |
254 | if ~HID_DUMP_UNCLAIMED |
255 | .unclaimed: |
255 | .unclaimed: |
256 | end if |
256 | end if |
257 | ret |
257 | ret |
Line 263... | Line 263... | ||
263 | push ecx |
263 | push ecx |
264 | mov [edi+keyboard_device_data.repeatkey], 0 |
264 | mov [edi+keyboard_device_data.repeatkey], 0 |
265 | mov eax, [edi+keyboard_device_data.timer] |
265 | mov eax, [edi+keyboard_device_data.timer] |
266 | test eax, eax |
266 | test eax, eax |
267 | jz @f |
267 | jz @f |
268 | stdcall CancelTimerHS, eax |
268 | invoke CancelTimerHS, eax |
269 | mov [edi+keyboard_device_data.timer], 0 |
269 | mov [edi+keyboard_device_data.timer], 0 |
270 | @@: |
270 | @@: |
271 | pop ecx |
271 | pop ecx |
272 | .no_stop_timer: |
272 | .no_stop_timer: |
273 | ; 1j. Copy bit 7 to CF and send scancode with bit 7 set. |
273 | ; 1j. Copy bit 7 to CF and send scancode with bit 7 set. |
Line 319... | Line 319... | ||
319 | ; If CF is set, precede it with special code 0xE0. |
319 | ; If CF is set, precede it with special code 0xE0. |
320 | .send_key: |
320 | .send_key: |
321 | jnc @f |
321 | jnc @f |
322 | push ecx |
322 | push ecx |
323 | mov ecx, 0xE0 |
323 | mov ecx, 0xE0 |
324 | call SetKeyboardData |
324 | invoke SetKeyboardData |
325 | pop ecx |
325 | pop ecx |
326 | @@: |
326 | @@: |
327 | call SetKeyboardData |
327 | invoke SetKeyboardData |
328 | ret |
328 | ret |
329 | endp |
329 | endp |
Line 330... | Line 330... | ||
330 | 330 | ||
331 | ; This procedure is called when HID layer ends processing a new input packet |
331 | ; This procedure is called when HID layer ends processing a new input packet |
Line 357... | Line 357... | ||
357 | virtual at esp |
357 | virtual at esp |
358 | dd ? ; return address |
358 | dd ? ; return address |
359 | .device_data dd ? |
359 | .device_data dd ? |
360 | end virtual |
360 | end virtual |
361 | mov eax, [.device_data] |
361 | mov eax, [.device_data] |
362 | call Kfree |
362 | invoke Kfree |
363 | ret 4 |
363 | ret 4 |
364 | endp |
364 | endp |
Line 365... | Line 365... | ||
365 | 365 | ||
366 | ; This function is called from the keyboard layer |
366 | ; This function is called from the keyboard layer |
Line 390... | Line 390... | ||
390 | ; Dword-align size for subsequent rep stosd and bts. |
390 | ; Dword-align size for subsequent rep stosd and bts. |
391 | ; If failed, exit from the function. |
391 | ; If failed, exit from the function. |
392 | add eax, 8 + 3 |
392 | add eax, 8 + 3 |
393 | and eax, not 3 |
393 | and eax, not 3 |
394 | push eax |
394 | push eax |
395 | call Kmalloc |
395 | invoke Kmalloc |
396 | pop ecx |
396 | pop ecx |
397 | test eax, eax |
397 | test eax, eax |
398 | jz .nothing |
398 | jz .nothing |
399 | ; 4. Zero-initialize output report. |
399 | ; 4. Zero-initialize output report. |
400 | push eax |
400 | push eax |
Line 442... | Line 442... | ||
442 | mov edx, [size] |
442 | mov edx, [size] |
443 | shl edx, 16 ; move Size to last word |
443 | shl edx, 16 ; move Size to last word |
444 | or edx, [ebx+usb_device_data.interface_number] |
444 | or edx, [ebx+usb_device_data.interface_number] |
445 | mov [eax+4], edx |
445 | mov [eax+4], edx |
446 | ; 8. Submit output control request. |
446 | ; 8. Submit output control request. |
447 | stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ |
447 | invoke USBControlTransferAsync, [ebx+usb_device_data.configpipe], \ |
448 | eax, edi, [size], after_set_keyboard_lights, ebx, 0 |
448 | eax, edi, [size], after_set_keyboard_lights, ebx, 0 |
449 | ; If failed, free the buffer now. |
449 | ; If failed, free the buffer now. |
450 | ; If succeeded, the callback will free the buffer. |
450 | ; If succeeded, the callback will free the buffer. |
451 | test eax, eax |
451 | test eax, eax |
452 | jnz .nothing |
452 | jnz .nothing |
453 | lea eax, [edi-8] |
453 | lea eax, [edi-8] |
454 | call Kfree |
454 | invoke Kfree |
455 | .nothing: |
455 | .nothing: |
456 | ret |
456 | ret |
457 | endp |
457 | endp |
Line 458... | Line 458... | ||
458 | 458 | ||
Line 468... | Line 468... | ||
468 | .calldata dd ? |
468 | .calldata dd ? |
469 | end virtual |
469 | end virtual |
470 | ; Ignore status, just free the buffer allocated by SetKeyboardLights. |
470 | ; Ignore status, just free the buffer allocated by SetKeyboardLights. |
471 | mov eax, [.buffer] |
471 | mov eax, [.buffer] |
472 | sub eax, 8 |
472 | sub eax, 8 |
473 | call Kfree |
473 | invoke Kfree |
474 | ret 20 |
474 | ret 20 |
475 | endp |
475 | endp |