Changeset 0c8562c in mainline
- Timestamp:
- 2011-03-11T11:15:44Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3005db6
- Parents:
- c0964800 (diff), b3bdb68 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
dist/Makefile
rc0964800 r0c8562c 43 43 44 44 SUFFIX = $(suffix $(IMGFILE)) 45 DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX) 45 46 ifdef PROFILE 47 DISTFILE = Helenos-$(shell echo $(PROFILE) | tr '/' '-')$(SUFFIX) 48 else 49 DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX) 50 endif 46 51 47 52 .PHONY: all clean dist distfile … … 53 58 cp $< $@ 54 59 60 $(IMGFILE): 61 $(MAKE) -C .. 62 55 63 dist: 56 64 for profile in $(PROFILES); do \ -
uspace/drv/usbhid/Makefile
rc0964800 r0c8562c 42 42 hidreq.c \ 43 43 kbddev.c \ 44 kbdrepeat.c \ 44 45 hiddev.c \ 45 46 $(STOLEN_LAYOUT_SOURCES) -
uspace/drv/usbhid/conv.c
rc0964800 r0c8562c 40 40 #include "conv.h" 41 41 42 /** 43 * Mapping between USB HID key codes (from HID Usage Tables) and corresponding 44 * HelenOS key codes. 45 */ 42 46 static int scanmap_simple[255] = { 43 47 … … 163 167 }; 164 168 169 /** 170 * Translate USB HID key codes (from HID Usage Tables) to generic key codes 171 * recognized by HelenOS. 172 * 173 * @param scancode USB HID key code (from HID Usage Tables). 174 * 175 * @retval HelenOS key code corresponding to the given USB HID key code. 176 */ 165 177 unsigned int usbhid_parse_scancode(int scancode) 166 178 { -
uspace/drv/usbhid/descdump.c
rc0964800 r0c8562c 44 44 #define BYTES_PER_LINE 12 45 45 46 /** 47 * Dumps the given buffer in hexadecimal format to standard output. 48 * 49 * @param msg Message to print before the buffer. 50 * @param buffer Buffer to print. 51 * @param length Size of the buffer in bytes. 52 */ 46 53 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length) 47 54 { … … 62 69 #define INDENT " " 63 70 71 /** 72 * Print standard configuration descriptor to standard output. 73 * 74 * @param index Index of the descriptor. 75 * @param d Standard configuration descriptor to print. 76 */ 64 77 void dump_standard_configuration_descriptor( 65 78 int index, const usb_standard_configuration_descriptor_t *d) … … 84 97 } 85 98 99 /** 100 * Print standard interface descriptor to standard output. 101 * 102 * @param d Standard interface descriptor to print. 103 */ 86 104 void dump_standard_interface_descriptor( 87 105 const usb_standard_interface_descriptor_t *d) … … 99 117 } 100 118 119 /** 120 * Print standard endpoint descriptor to standard output. 121 * 122 * @param d Standard endpoint descriptor to print. 123 */ 101 124 void dump_standard_endpoint_descriptor( 102 125 const usb_standard_endpoint_descriptor_t *d) … … 126 149 } 127 150 151 /** 152 * Print standard HID descriptor to standard output. 153 * 154 * @param d Standard HID descriptor to print. 155 */ 128 156 void dump_standard_hid_descriptor_header( 129 157 const usb_standard_hid_descriptor_t *d) … … 139 167 } 140 168 169 /** 170 * Print HID class-specific descriptor header (type and length) to standard 171 * output. 172 * 173 * @param d HID class-specific descriptor header to print. 174 */ 141 175 void dump_standard_hid_class_descriptor_info( 142 176 const usb_standard_hid_class_descriptor_info_t *d) … … 146 180 } 147 181 182 /** 183 * Print HID class-specific descriptor (without the header) to standard output. 184 * 185 * @param index Index of the descriptor. 186 * @param type Type of the HID class-specific descriptor (Report or Physical). 187 * @param d HID class descriptor to print. 188 * @param size Size of the descriptor in bytes. 189 */ 148 190 void dump_hid_class_descriptor(int index, uint8_t type, 149 191 const uint8_t *d, size_t size ) -
uspace/drv/usbhid/hiddev.c
rc0964800 r0c8562c 53 53 /* Non-API functions */ 54 54 /*----------------------------------------------------------------------------*/ 55 55 /** 56 * Retreives HID Report descriptor from the device. 57 * 58 * This function first parses the HID descriptor from the Interface descriptor 59 * to get the size of the Report descriptor and then requests the Report 60 * descriptor from the device. 61 * 62 * @param hid_dev HID device structure. 63 * @param config_desc Full configuration descriptor (including all nested 64 * descriptors). 65 * @param config_desc_size Size of the full configuration descriptor (in bytes). 66 * @param iface_desc Pointer to the interface descriptor inside the full 67 * configuration descriptor (@a config_desc) for the interface 68 * assigned with this device (@a hid_dev). 69 * 70 * @retval EOK if successful. 71 * @retval ENOENT if no HID descriptor could be found. 72 * @retval EINVAL if the HID descriptor or HID report descriptor have different 73 * size than expected. 74 * @retval ENOMEM if some allocation failed. 75 * @return Other value inherited from function usb_request_get_descriptor(). 76 * 77 * @sa usb_request_get_descriptor() 78 */ 56 79 static int usbhid_dev_get_report_descriptor(usbhid_dev_t *hid_dev, 57 80 uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc) … … 141 164 142 165 /*----------------------------------------------------------------------------*/ 143 166 /** 167 * Retreives descriptors from the device, initializes pipes and stores 168 * important information from descriptors. 169 * 170 * Initializes the polling pipe described by the given endpoint description 171 * (@a poll_ep_desc). 172 * 173 * Information retreived from descriptors and stored in the HID device structure: 174 * - Assigned interface number (the interface controlled by this instance of 175 * the driver) 176 * - Polling interval (from the interface descriptor) 177 * - Report descriptor 178 * 179 * @param hid_dev HID device structure to be initialized. 180 * @param poll_ep_desc Description of the polling (Interrupt In) endpoint 181 * that has to be present in the device in order to 182 * successfuly initialize the structure. 183 * 184 * @sa usb_endpoint_pipe_initialize_from_configuration(), 185 * usbhid_dev_get_report_descriptor() 186 */ 144 187 static int usbhid_dev_process_descriptors(usbhid_dev_t *hid_dev, 145 188 usb_endpoint_description_t *poll_ep_desc) … … 230 273 /* API functions */ 231 274 /*----------------------------------------------------------------------------*/ 232 275 /** 276 * Creates new uninitialized HID device structure. 277 * 278 * @return Pointer to the new HID device structure, or NULL if an error occured. 279 */ 233 280 usbhid_dev_t *usbhid_dev_new(void) 234 281 { … … 249 296 250 297 /*----------------------------------------------------------------------------*/ 251 298 /** 299 * Properly destroys the HID device structure. 300 * 301 * @note Currently does not clean-up the used pipes, as there are no functions 302 * offering such functionality. 303 * 304 * @param hid_dev Pointer to the structure to be destroyed. 305 */ 252 306 void usbhid_dev_free(usbhid_dev_t **hid_dev) 253 307 { … … 272 326 273 327 /*----------------------------------------------------------------------------*/ 274 328 /** 329 * Initializes HID device structure. 330 * 331 * @param hid_dev HID device structure to be initialized. 332 * @param dev DDF device representing the HID device. 333 * @param poll_ep_desc Description of the polling (Interrupt In) endpoint 334 * that has to be present in the device in order to 335 * successfuly initialize the structure. 336 * 337 * @retval EOK if successful. 338 * @retval EINVAL if some argument is missing. 339 * @return Other value inherited from one of functions 340 * usb_device_connection_initialize_from_device(), 341 * usb_endpoint_pipe_initialize_default_control(), 342 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 343 * usbhid_dev_process_descriptors(). 344 * 345 * @sa usbhid_dev_process_descriptors() 346 */ 275 347 int usbhid_dev_init(usbhid_dev_t *hid_dev, ddf_dev_t *dev, 276 348 usb_endpoint_description_t *poll_ep_desc) … … 323 395 * Get descriptors, parse descriptors and save endpoints. 324 396 */ 325 usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe); 397 rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe); 398 if (rc != EOK) { 399 usb_log_error("Failed to start session on the control pipe: %s" 400 ".\n", str_error(rc)); 401 return rc; 402 } 326 403 327 404 rc = usbhid_dev_process_descriptors(hid_dev, poll_ep_desc); 328 329 usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); 330 if (rc != EOK) { 405 if (rc != EOK) { 406 /* TODO: end session?? */ 331 407 usb_log_error("Failed to process descriptors: %s.\n", 332 408 str_error(rc)); … … 334 410 } 335 411 412 rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); 413 if (rc != EOK) { 414 usb_log_warning("Failed to start session on the control pipe: " 415 "%s.\n", str_error(rc)); 416 return rc; 417 } 418 336 419 hid_dev->initialized = 1; 337 420 usb_log_info("HID device structure initialized.\n"); -
uspace/drv/usbhid/hiddev.h
rc0964800 r0c8562c 48 48 49 49 /** 50 * @brief USB/HID device type. 50 * USB/HID device type. 51 * 52 * Holds a reference to DDF device structure, and HID-specific data, such 53 * as information about used pipes (one Control pipe and one Interrupt In pipe), 54 * polling interval, assigned interface number, Report descriptor and a 55 * reference to the Report parser used to parse incoming reports and composing 56 * outgoing reports. 51 57 */ 52 58 typedef struct { 59 /** DDF device representing the controlled HID device. */ 53 60 ddf_dev_t *device; 54 61 62 /** Physical connection to the device. */ 55 63 usb_device_connection_t wire; 64 /** USB pipe corresponding to the default Control endpoint. */ 56 65 usb_endpoint_pipe_t ctrl_pipe; 66 /** USB pipe corresponding to the Interrupt In (polling) pipe. */ 57 67 usb_endpoint_pipe_t poll_pipe; 58 68 69 /** Polling interval retreived from the Interface descriptor. */ 59 70 short poll_interval; 60 71 72 /** Interface number assigned to this device. */ 61 73 uint16_t iface; 62 74 75 /** Report descriptor. */ 63 76 uint8_t *report_desc; 77 /** HID Report parser. */ 64 78 usb_hid_report_parser_t *parser; 65 79 80 /** State of the structure (for checking before use). */ 66 81 int initialized; 67 82 } usbhid_dev_t; -
uspace/drv/usbhid/hidreq.c
rc0964800 r0c8562c 46 46 47 47 /*----------------------------------------------------------------------------*/ 48 48 /** 49 * Send Set Report request to the HID device. 50 * 51 * @param hid_dev HID device to send the request to. 52 * @param type Type of the report. 53 * @param buffer Report data. 54 * @param buf_size Report data size (in bytes). 55 * 56 * @retval EOK if successful. 57 * @retval EINVAL if no HID device is given. 58 * @return Other value inherited from one of functions 59 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 60 * usb_control_request_set(). 61 */ 49 62 int usbhid_req_set_report(usbhid_dev_t *hid_dev, 50 63 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size) … … 97 110 98 111 /*----------------------------------------------------------------------------*/ 99 112 /** 113 * Send Set Protocol request to the HID device. 114 * 115 * @param hid_dev HID device to send the request to. 116 * @param protocol Protocol to set. 117 * 118 * @retval EOK if successful. 119 * @retval EINVAL if no HID device is given. 120 * @return Other value inherited from one of functions 121 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 122 * usb_control_request_set(). 123 */ 100 124 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol) 101 125 { … … 145 169 146 170 /*----------------------------------------------------------------------------*/ 147 171 /** 172 * Send Set Idle request to the HID device. 173 * 174 * @param hid_dev HID device to send the request to. 175 * @param duration Duration value (is multiplicated by 4 by the device to 176 * get real duration in miliseconds). 177 * 178 * @retval EOK if successful. 179 * @retval EINVAL if no HID device is given. 180 * @return Other value inherited from one of functions 181 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 182 * usb_control_request_set(). 183 */ 148 184 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration) 149 185 { … … 195 231 196 232 /*----------------------------------------------------------------------------*/ 197 233 /** 234 * Send Get Report request to the HID device. 235 * 236 * @param[in] hid_dev HID device to send the request to. 237 * @param[in] type Type of the report. 238 * @param[in][out] buffer Buffer for the report data. 239 * @param[in] buf_size Size of the buffer (in bytes). 240 * @param[out] actual_size Actual size of report received from the device 241 * (in bytes). 242 * 243 * @retval EOK if successful. 244 * @retval EINVAL if no HID device is given. 245 * @return Other value inherited from one of functions 246 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 247 * usb_control_request_set(). 248 */ 198 249 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 199 250 uint8_t *buffer, size_t buf_size, size_t *actual_size) … … 246 297 } 247 298 299 /*----------------------------------------------------------------------------*/ 300 /** 301 * Send Get Protocol request to the HID device. 302 * 303 * @param[in] hid_dev HID device to send the request to. 304 * @param[out] protocol Current protocol of the device. 305 * 306 * @retval EOK if successful. 307 * @retval EINVAL if no HID device is given. 308 * @return Other value inherited from one of functions 309 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 310 * usb_control_request_set(). 311 */ 248 312 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol) 249 313 { … … 303 367 } 304 368 369 /*----------------------------------------------------------------------------*/ 370 /** 371 * Send Get Idle request to the HID device. 372 * 373 * @param[in] hid_dev HID device to send the request to. 374 * @param[out] duration Duration value (multiplicate by 4 to get real duration 375 * in miliseconds). 376 * 377 * @retval EOK if successful. 378 * @retval EINVAL if no HID device is given. 379 * @return Other value inherited from one of functions 380 * usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(), 381 * usb_control_request_set(). 382 */ 305 383 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration) 306 384 { -
uspace/drv/usbhid/kbddev.c
rc0964800 r0c8562c 37 37 #include <errno.h> 38 38 #include <str_error.h> 39 #include <fibril.h>40 39 #include <stdio.h> 41 40 … … 43 42 #include <ipc/kbd.h> 44 43 #include <async.h> 44 #include <fibril.h> 45 #include <fibril_synch.h> 45 46 46 47 #include <usb/usb.h> … … 56 57 #include "layout.h" 57 58 #include "conv.h" 58 59 /*----------------------------------------------------------------------------*/ 60 59 #include "kbdrepeat.h" 60 61 /*----------------------------------------------------------------------------*/ 62 /** Default modifiers when the keyboard is initialized. */ 61 63 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; 64 65 /** Boot protocol report size (key part). */ 62 66 static const size_t BOOTP_REPORT_SIZE = 6; 67 68 /** Boot protocol total report size. */ 63 69 static const size_t BOOTP_BUFFER_SIZE = 8; 70 71 /** Boot protocol output report size. */ 64 72 static const size_t BOOTP_BUFFER_OUT_SIZE = 1; 73 74 /** Boot protocol error key code. */ 65 75 static const uint8_t BOOTP_ERROR_ROLLOVER = 1; 76 77 /** Default idle rate for keyboards. */ 66 78 static const uint8_t IDLE_RATE = 0; 79 80 /** Delay before a pressed key starts auto-repeating. */ 81 static const unsigned int DEFAULT_DELAY_BEFORE_FIRST_REPEAT = 500 * 1000; 82 83 /** Delay between two repeats of a pressed key when auto-repeating. */ 84 static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000; 67 85 68 86 /** Keyboard polling endpoint description for boot protocol class. */ … … 82 100 #define NUM_LAYOUTS 3 83 101 102 /** Keyboard layout map. */ 84 103 static layout_op_t *layout[NUM_LAYOUTS] = { 85 104 &us_qwerty_op, … … 93 112 /* Modifier constants */ 94 113 /*----------------------------------------------------------------------------*/ 95 114 /** Mapping of USB modifier key codes to generic modifier key codes. */ 96 115 static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = { 97 116 KC_LCTRL, /* USB_HID_MOD_LCTRL */ … … 114 133 }; 115 134 116 /** Default handler for IPC methods not handled by DDF. 117 * 118 * @param dev Device handling the call. 135 /** 136 * Default handler for IPC methods not handled by DDF. 137 * 138 * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it 139 * assumes the caller is the console and thus it stores IPC phone to it for 140 * later use by the driver to notify about key events. 141 * 142 * @param fun Device function handling the call. 119 143 * @param icallid Call id. 120 144 * @param icall Call data. … … 147 171 /* Key processing functions */ 148 172 /*----------------------------------------------------------------------------*/ 149 173 /** 174 * Handles turning of LED lights on and off. 175 * 176 * In case of USB keyboards, the LEDs are handled in the driver, not in the 177 * device. When there should be a change (lock key was pressed), the driver 178 * uses a Set_Report request sent to the device to set the state of the LEDs. 179 * 180 * This functions sets the LED lights according to current settings of modifiers 181 * kept in the keyboard device structure. 182 * 183 * @param kbd_dev Keyboard device structure. 184 */ 150 185 static void usbhid_kbd_set_led(usbhid_kbd_t *kbd_dev) 151 186 { … … 189 224 190 225 /*----------------------------------------------------------------------------*/ 191 192 static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, 193 unsigned int key) 226 /** 227 * Processes key events. 228 * 229 * @note This function was copied from AT keyboard driver and modified to suit 230 * USB keyboard. 231 * 232 * @note Lock keys are not sent to the console, as they are completely handled 233 * in the driver. It may, however, be required later that the driver 234 * sends also these keys to application (otherwise it cannot use those 235 * keys at all). 236 * 237 * @param kbd_dev Keyboard device structure. 238 * @param type Type of the event (press / release). Recognized values: 239 * KEY_PRESS, KEY_RELEASE 240 * @param key Key code of the key according to HID Usage Tables. 241 */ 242 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key) 194 243 { 195 244 console_event_t ev; 196 245 unsigned mod_mask; 197 246 198 // TODO: replace by our own parsing?? or are the key codes identical?? 247 /* 248 * These parts are copy-pasted from the AT keyboard driver. 249 * 250 * They definitely require some refactoring, but will keep it for later 251 * when the console and keyboard system is changed in HelenOS. 252 */ 199 253 switch (key) { 200 254 case KC_LCTRL: mod_mask = KM_LCTRL; break; … … 228 282 * up the lock state. 229 283 */ 284 unsigned int locks_old = kbd_dev->lock_keys; 285 230 286 kbd_dev->mods = 231 287 kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys); … … 233 289 234 290 /* Update keyboard lock indicator lights. */ 235 usbhid_kbd_set_led(kbd_dev); 291 if (kbd_dev->lock_keys != locks_old) { 292 usbhid_kbd_set_led(kbd_dev); 293 } 236 294 } else { 237 295 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask; … … 280 338 281 339 /*----------------------------------------------------------------------------*/ 282 340 /** 341 * Checks if modifiers were pressed or released and generates key events. 342 * 343 * @param kbd_dev Keyboard device structure. 344 * @param modifiers Bitmap of modifiers. 345 * 346 * @sa usbhid_kbd_push_ev() 347 */ 283 348 static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev, 284 349 uint8_t modifiers) … … 316 381 317 382 /*----------------------------------------------------------------------------*/ 318 383 /** 384 * Checks if some keys were pressed or released and generates key events. 385 * 386 * An event is created only when key is pressed or released. Besides handling 387 * the events (usbhid_kbd_push_ev()), the auto-repeat fibril is notified about 388 * key presses and releases (see usbhid_kbd_repeat_start() and 389 * usbhid_kbd_repeat_stop()). 390 * 391 * @param kbd_dev Keyboard device structure. 392 * @param key_codes Parsed keyboard report - codes of currently pressed keys 393 * according to HID Usage Tables. 394 * @param count Number of key codes in report (size of the report). 395 * 396 * @sa usbhid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop() 397 */ 319 398 static void usbhid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev, 320 const uint8_t *key_codes )399 const uint8_t *key_codes, size_t count) 321 400 { 322 401 unsigned int key; … … 328 407 i = 0; 329 408 // all fields should report Error Rollover 330 while (i < kbd_dev->keycode_count &&409 while (i < count && 331 410 key_codes[i] == BOOTP_ERROR_ROLLOVER) { 332 411 ++i; 333 412 } 334 if (i == kbd_dev->keycode_count) {413 if (i == count) { 335 414 usb_log_debug("Phantom state occured.\n"); 336 415 // phantom state, do nothing … … 338 417 } 339 418 340 // TODO: quite dummy right now, think of better implementation 419 /* TODO: quite dummy right now, think of better implementation */ 420 assert(count == kbd_dev->key_count); 341 421 342 422 /* 343 423 * 1) Key releases 344 424 */ 345 for (j = 0; j < kbd_dev->keycode_count; ++j) {425 for (j = 0; j < count; ++j) { 346 426 // try to find the old key in the new key list 347 427 i = 0; 348 while (i < kbd_dev->key code_count349 && key_codes[i] != kbd_dev->key codes[j]) {428 while (i < kbd_dev->key_count 429 && key_codes[i] != kbd_dev->keys[j]) { 350 430 ++i; 351 431 } 352 432 353 if (i == kbd_dev->keycode_count) {433 if (i == count) { 354 434 // not found, i.e. the key was released 355 key = usbhid_parse_scancode(kbd_dev->keycodes[j]); 435 key = usbhid_parse_scancode(kbd_dev->keys[j]); 436 usbhid_kbd_repeat_stop(kbd_dev, key); 356 437 usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 357 438 usb_log_debug2("Key released: %d\n", key); … … 364 445 * 1) Key presses 365 446 */ 366 for (i = 0; i < kbd_dev->key code_count; ++i) {447 for (i = 0; i < kbd_dev->key_count; ++i) { 367 448 // try to find the new key in the old key list 368 449 j = 0; 369 while (j < kbd_dev->keycode_count 370 && kbd_dev->keycodes[j] != key_codes[i]) { 450 while (j < count && kbd_dev->keys[j] != key_codes[i]) { 371 451 ++j; 372 452 } 373 453 374 if (j == kbd_dev->keycode_count) {454 if (j == count) { 375 455 // not found, i.e. new key pressed 376 456 key = usbhid_parse_scancode(key_codes[i]); … … 378 458 key_codes[i]); 379 459 usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key); 460 usbhid_kbd_repeat_start(kbd_dev, key); 380 461 } else { 381 462 // found, nothing happens 382 463 } 383 464 } 384 // // report all currently pressed keys 385 // for (i = 0; i < kbd_dev->keycode_count; ++i) { 386 // if (key_codes[i] != 0) { 387 // key = usbhid_parse_scancode(key_codes[i]); 388 // usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 389 // key_codes[i]); 390 // usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key); 391 // } 392 // } 393 394 memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count); 465 466 memcpy(kbd_dev->keys, key_codes, count); 395 467 396 468 usb_log_debug("New stored keycodes: %s\n", 397 usb_debug_str_buffer(kbd_dev->key codes, kbd_dev->keycode_count, 0));469 usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0)); 398 470 } 399 471 … … 401 473 /* Callbacks for parser */ 402 474 /*----------------------------------------------------------------------------*/ 403 475 /** 476 * Callback function for the HID report parser. 477 * 478 * This function is called by the HID report parser with the parsed report. 479 * The parsed report is used to check if any events occured (key was pressed or 480 * released, modifier was pressed or released). 481 * 482 * @param key_codes Parsed keyboard report - codes of currently pressed keys 483 * according to HID Usage Tables. 484 * @param count Number of key codes in report (size of the report). 485 * @param modifiers Bitmap of modifiers (Ctrl, Alt, Shift, GUI). 486 * @param arg User-specified argument. Expects pointer to the keyboard device 487 * structure representing the keyboard. 488 * 489 * @sa usbhid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes() 490 */ 404 491 static void usbhid_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 405 492 uint8_t modifiers, void *arg) … … 415 502 416 503 usb_log_debug("Got keys from parser: %s\n", 417 usb_debug_str_buffer(key_codes, kbd_dev->key code_count, 0));418 419 if (count != kbd_dev->key code_count) {504 usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0)); 505 506 if (count != kbd_dev->key_count) { 420 507 usb_log_warning("Number of received keycodes (%d) differs from" 421 " expected number (%d).\n", count, kbd_dev->key code_count);508 " expected number (%d).\n", count, kbd_dev->key_count); 422 509 return; 423 510 } 424 511 425 512 usbhid_kbd_check_modifier_changes(kbd_dev, modifiers); 426 usbhid_kbd_check_key_changes(kbd_dev, key_codes );513 usbhid_kbd_check_key_changes(kbd_dev, key_codes, count); 427 514 } 428 515 … … 430 517 /* General kbd functions */ 431 518 /*----------------------------------------------------------------------------*/ 432 519 /** 520 * Processes data received from the device in form of report. 521 * 522 * This function uses the HID report parser to translate the data received from 523 * the device into generic USB HID key codes and into generic modifiers bitmap. 524 * The parser then calls the given callback (usbhid_kbd_process_keycodes()). 525 * 526 * @note Currently, only the boot protocol is supported. 527 * 528 * @param kbd_dev Keyboard device structure (must be initialized). 529 * @param buffer Data from the keyboard (i.e. the report). 530 * @param actual_size Size of the data from keyboard (report size) in bytes. 531 * 532 * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(). 533 */ 433 534 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev, 434 535 uint8_t *buffer, size_t actual_size) … … 455 556 /* HID/KBD structure manipulation */ 456 557 /*----------------------------------------------------------------------------*/ 457 558 /** 559 * Creates a new USB/HID keyboard structure. 560 * 561 * The structure returned by this function is not initialized. Use 562 * usbhid_kbd_init() to initialize it prior to polling. 563 * 564 * @return New uninitialized structure for representing a USB/HID keyboard or 565 * NULL if not successful (memory error). 566 */ 458 567 static usbhid_kbd_t *usbhid_kbd_new(void) 459 568 { … … 481 590 482 591 /*----------------------------------------------------------------------------*/ 483 592 /** 593 * Properly destroys the USB/HID keyboard structure. 594 * 595 * @param kbd_dev Pointer to the structure to be destroyed. 596 */ 484 597 static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev) 485 598 { … … 496 609 } 497 610 611 if ((*kbd_dev)->repeat_mtx != NULL) { 612 /* TODO: replace by some check and wait */ 613 assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 614 free((*kbd_dev)->repeat_mtx); 615 } 616 498 617 free(*kbd_dev); 499 618 *kbd_dev = NULL; … … 501 620 502 621 /*----------------------------------------------------------------------------*/ 503 622 /** 623 * Initialization of the USB/HID keyboard structure. 624 * 625 * This functions initializes required structures from the device's descriptors. 626 * 627 * During initialization, the keyboard is switched into boot protocol, the idle 628 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 629 * when a key is pressed or released. Finally, the LED lights are turned on 630 * according to the default setup of lock keys. 631 * 632 * @note By default, the keyboards is initialized with Num Lock turned on and 633 * other locks turned off. 634 * 635 * @param kbd_dev Keyboard device structure to be initialized. 636 * @param dev DDF device structure of the keyboard. 637 * 638 * @retval EOK if successful. 639 * @retval EINVAL if some parameter is not given. 640 * @return Other value inherited from function usbhid_dev_init(). 641 */ 504 642 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev) 505 643 { … … 536 674 537 675 // save the size of the report (boot protocol report by default) 538 kbd_dev->key code_count = BOOTP_REPORT_SIZE;539 kbd_dev->key codes = (uint8_t *)calloc(540 kbd_dev->key code_count, sizeof(uint8_t));541 542 if (kbd_dev->key codes == NULL) {676 kbd_dev->key_count = BOOTP_REPORT_SIZE; 677 kbd_dev->keys = (uint8_t *)calloc( 678 kbd_dev->key_count, sizeof(uint8_t)); 679 680 if (kbd_dev->keys == NULL) { 543 681 usb_log_fatal("No memory!\n"); 544 return rc;682 return ENOMEM; 545 683 } 546 684 … … 549 687 kbd_dev->lock_keys = 0; 550 688 689 kbd_dev->repeat.key_new = 0; 690 kbd_dev->repeat.key_repeated = 0; 691 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 692 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 693 694 kbd_dev->repeat_mtx = (fibril_mutex_t *)( 695 malloc(sizeof(fibril_mutex_t))); 696 if (kbd_dev->repeat_mtx == NULL) { 697 usb_log_fatal("No memory!\n"); 698 free(kbd_dev->keys); 699 return ENOMEM; 700 } 701 702 fibril_mutex_initialize(kbd_dev->repeat_mtx); 703 551 704 /* 552 705 * Set boot protocol. … … 571 724 /* HID/KBD polling */ 572 725 /*----------------------------------------------------------------------------*/ 573 726 /** 727 * Main keyboard polling function. 728 * 729 * This function uses the Interrupt In pipe of the keyboard to poll for events. 730 * The keyboard is initialized in a way that it reports only when a key is 731 * pressed or released, so there is no actual need for any sleeping between 732 * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()). 733 * 734 * @param kbd_dev Initialized keyboard structure representing the device to 735 * poll. 736 * 737 * @sa usbhid_kbd_process_data() 738 */ 574 739 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev) 575 740 { … … 594 759 usb_log_warning("Failed to start a session: %s.\n", 595 760 str_error(sess_rc)); 596 continue;761 break; 597 762 } 598 763 … … 606 771 usb_log_warning("Error polling the keyboard: %s.\n", 607 772 str_error(rc)); 608 continue;773 break; 609 774 } 610 775 … … 612 777 usb_log_warning("Error closing session: %s.\n", 613 778 str_error(sess_rc)); 614 continue;779 break; 615 780 } 616 781 … … 633 798 //async_usleep(kbd_dev->hid_dev->poll_interval); 634 799 } 635 636 // not reached 637 assert(0); 638 } 639 640 /*----------------------------------------------------------------------------*/ 641 800 } 801 802 /*----------------------------------------------------------------------------*/ 803 /** 804 * Function executed by the main driver fibril. 805 * 806 * Just starts polling the keyboard for events. 807 * 808 * @param arg Initialized keyboard device structure (of type usbhid_kbd_t) 809 * representing the device. 810 * 811 * @retval EOK if the fibril finished polling the device. 812 * @retval EINVAL if no device was given in the argument. 813 * 814 * @sa usbhid_kbd_poll() 815 * 816 * @todo Change return value - only case when the fibril finishes is in case 817 * of some error, so the error should probably be propagated from function 818 * usbhid_kbd_poll() to here and up. 819 */ 642 820 static int usbhid_kbd_fibril(void *arg) 643 821 { … … 661 839 /* API functions */ 662 840 /*----------------------------------------------------------------------------*/ 663 841 /** 842 * Function for adding a new device of type USB/HID/keyboard. 843 * 844 * This functions initializes required structures from the device's descriptors 845 * and starts new fibril for polling the keyboard for events and another one for 846 * handling auto-repeat of keys. 847 * 848 * During initialization, the keyboard is switched into boot protocol, the idle 849 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 850 * when a key is pressed or released. Finally, the LED lights are turned on 851 * according to the default setup of lock keys. 852 * 853 * @note By default, the keyboards is initialized with Num Lock turned on and 854 * other locks turned off. 855 * @note Currently supports only boot-protocol keyboards. 856 * 857 * @param dev Device to add. 858 * 859 * @retval EOK if successful. 860 * @retval ENOMEM if there 861 * @return Other error code inherited from one of functions usbhid_kbd_init(), 862 * ddf_fun_bind() and ddf_fun_add_to_class(). 863 * 864 * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril() 865 */ 664 866 int usbhid_kbd_try_add_device(ddf_dev_t *dev) 665 867 { … … 683 885 "structure.\n"); 684 886 ddf_fun_destroy(kbd_fun); 685 return E INVAL; // TODO: some other code??887 return ENOMEM; // TODO: some other code?? 686 888 } 687 889 … … 732 934 } 733 935 fibril_add_ready(fid); 936 937 /* 938 * Create new fibril for auto-repeat 939 */ 940 fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev); 941 if (fid == 0) { 942 usb_log_error("Failed to start fibril for KBD auto-repeat"); 943 return ENOMEM; 944 } 945 fibril_add_ready(fid); 734 946 735 947 (void)keyboard_ops; -
uspace/drv/usbhid/kbddev.h
rc0964800 r0c8562c 39 39 #include <stdint.h> 40 40 41 #include <fibril_synch.h> 42 41 43 #include <usb/classes/hid.h> 42 44 #include <ddf/driver.h> … … 46 48 47 49 /*----------------------------------------------------------------------------*/ 50 /** 51 * Structure for keeping information needed for auto-repeat of keys. 52 */ 53 typedef struct { 54 /** Last pressed key. */ 55 unsigned int key_new; 56 /** Key to be repeated. */ 57 unsigned int key_repeated; 58 /** Delay before first repeat in microseconds. */ 59 unsigned int delay_before; 60 /** Delay between repeats in microseconds. */ 61 unsigned int delay_between; 62 } usbhid_kbd_repeat_t; 48 63 49 64 /** 50 * @brief USB/HID keyboard device type. 65 * USB/HID keyboard device type. 66 * 67 * Holds a reference to generic USB/HID device structure and keyboard-specific 68 * data, such as currently pressed keys, modifiers and lock keys. 69 * 70 * Also holds a IPC phone to the console (since there is now no other way to 71 * communicate with it). 72 * 73 * @note Storing active lock keys in this structure results in their setting 74 * being device-specific. 51 75 */ 52 76 typedef struct { 77 /** Structure holding generic USB/HID device information. */ 53 78 usbhid_dev_t *hid_dev; 54 79 55 uint8_t *keycodes; 56 size_t keycode_count; 80 /** Currently pressed keys (not translated to key codes). */ 81 uint8_t *keys; 82 /** Count of stored keys (i.e. number of keys in the report). */ 83 size_t key_count; 84 /** Currently pressed modifiers (bitmap). */ 57 85 uint8_t modifiers; 58 86 87 /** Currently active modifiers including locks. Sent to the console. */ 59 88 unsigned mods; 89 90 /** Currently active lock keys. */ 60 91 unsigned lock_keys; 61 92 93 /** IPC phone to the console device (for sending key events). */ 62 94 int console_phone; 63 95 96 /** Information for auto-repeat of keys. */ 97 usbhid_kbd_repeat_t repeat; 98 99 /** Mutex for accessing the information about auto-repeat. */ 100 fibril_mutex_t *repeat_mtx; 101 102 /** State of the structure (for checking before use). */ 64 103 int initialized; 65 104 } usbhid_kbd_t; … … 69 108 int usbhid_kbd_try_add_device(ddf_dev_t *dev); 70 109 110 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key); 111 71 112 #endif /* USBHID_KBDDEV_H_ */ 72 113 -
uspace/drv/usbhid/main.c
rc0964800 r0c8562c 47 47 48 48 /*----------------------------------------------------------------------------*/ 49 49 /** 50 * Callback for passing a new device to the driver. 51 * 52 * @note Currently, only boot-protocol keyboards are supported by this driver. 53 * 54 * @param dev Structure representing the new device. 55 * 56 * @retval EOK if successful. 57 * @retval EREFUSED if the device is not supported. 58 */ 50 59 static int usbhid_add_device(ddf_dev_t *dev) 51 60 { -
uspace/lib/block/libblock.c
rc0964800 r0c8562c 411 411 l = hash_table_find(&cache->block_hash, &key); 412 412 if (l) { 413 found: 413 414 /* 414 415 * We found the block in the cache. … … 493 494 fibril_mutex_unlock(&b->lock); 494 495 goto retry; 496 } 497 l = hash_table_find(&cache->block_hash, &key); 498 if (l) { 499 /* 500 * Someone else must have already 501 * instantiated the block while we were 502 * not holding the cache lock. 503 * Leave the recycled block on the 504 * freelist and continue as if we 505 * found the block of interest during 506 * the first try. 507 */ 508 fibril_mutex_unlock(&b->lock); 509 goto found; 495 510 } 496 511
Note:
See TracChangeset
for help on using the changeset viewer.