Changeset 60c0573 in mainline for uspace/drv/usbhid/usbhid.c
- Timestamp:
- 2011-04-10T15:17:22Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ba358ed
- Parents:
- dc4c19e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/usbhid.c
rdc4c19e r60c0573 51 51 /*----------------------------------------------------------------------------*/ 52 52 53 typedef struct usb_hid_callback_mapping { 54 usb_hid_report_path_t *path; 55 char *vendor_id; 56 char *product_id; 57 } usb_hid_callback_mapping; 58 59 /*----------------------------------------------------------------------------*/ 60 53 61 /* Array of endpoints expected on the device, NULL terminated. */ 54 62 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = { … … 61 69 /*----------------------------------------------------------------------------*/ 62 70 71 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 72 { 73 assert(hid_dev->subdriver_count == 0); 74 75 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 76 sizeof(usb_hid_subdriver_t)); 77 if (hid_dev->subdrivers == NULL) { 78 return ENOMEM; 79 } 80 81 // set the init callback 82 hid_dev->subdrivers[0].init = usb_kbd_init; 83 84 // set the polling callback 85 hid_dev->subdrivers[0].poll = usb_kbd_polling_callback; 86 87 // set the polling ended callback 88 hid_dev->subdrivers[0].poll_end = NULL; 89 90 // set the deinit callback 91 hid_dev->subdrivers[0].deinit = usb_kbd_deinit; 92 93 // set subdriver count 94 hid_dev->subdriver_count = 1; 95 96 return EOK; 97 } 98 99 /*----------------------------------------------------------------------------*/ 100 101 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 102 { 103 assert(hid_dev->subdriver_count == 0); 104 105 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 106 sizeof(usb_hid_subdriver_t)); 107 if (hid_dev->subdrivers == NULL) { 108 return ENOMEM; 109 } 110 111 // set the init callback 112 hid_dev->subdrivers[0].init = usb_mouse_init; 113 114 // set the polling callback 115 hid_dev->subdrivers[0].poll = usb_mouse_polling_callback; 116 117 // set the polling ended callback 118 hid_dev->subdrivers[0].poll_end = NULL; 119 120 // set the deinit callback 121 hid_dev->subdrivers[0].deinit = usb_mouse_deinit; 122 123 // set subdriver count 124 hid_dev->subdriver_count = 1; 125 126 return EOK; 127 } 128 129 /*----------------------------------------------------------------------------*/ 130 131 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 132 { 133 assert(hid_dev->subdriver_count == 0); 134 135 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 136 sizeof(usb_hid_subdriver_t)); 137 if (hid_dev->subdrivers == NULL) { 138 return ENOMEM; 139 } 140 141 // set the init callback 142 hid_dev->subdrivers[0].init = NULL; 143 144 // set the polling callback 145 hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback; 146 147 // set the polling ended callback 148 hid_dev->subdrivers[0].poll_end = NULL; 149 150 // set the deinit callback 151 hid_dev->subdrivers[0].deinit = NULL; 152 153 return EOK; 154 } 155 156 /*----------------------------------------------------------------------------*/ 157 158 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 159 { 160 return EOK; 161 } 162 163 /*----------------------------------------------------------------------------*/ 164 165 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 166 { 167 // first try to find subdrivers that may want to handle this device 168 int rc = usb_hid_find_subdrivers(hid_dev); 169 170 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 171 usb_log_debug("Found keyboard endpoint.\n"); 172 173 // save the pipe index 174 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 175 176 // if no subdrivers registered, use the boot kbd subdriver 177 if (hid_dev->subdriver_count == 0) { 178 rc = usb_hid_set_boot_kbd_subdriver(hid_dev); 179 } 180 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 181 usb_log_debug("Found mouse endpoint.\n"); 182 183 // save the pipe index 184 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 185 //hid_dev->device_type = USB_HID_PROTOCOL_MOUSE; 186 187 // if no subdrivers registered, use the boot kbd subdriver 188 if (hid_dev->subdriver_count == 0) { 189 rc = usb_hid_set_boot_mouse_subdriver(hid_dev); 190 } 191 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 192 usb_log_debug("Found generic HID endpoint.\n"); 193 194 // save the pipe index 195 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 196 197 if (hid_dev->subdriver_count == 0) { 198 usb_log_warning("Found no subdriver for handling this" 199 " HID device. Setting generic HID subdriver.\n"); 200 usb_hid_set_generic_hid_subdriver(hid_dev); 201 return EOK; 202 } 203 } else { 204 usb_log_error("None of supported endpoints found - probably" 205 " not a supported device.\n"); 206 rc = ENOTSUP; 207 } 208 209 return rc; 210 } 211 212 /*----------------------------------------------------------------------------*/ 213 214 static int usb_hid_init_parser(usb_hid_dev_t *hid_dev) 215 { 216 /* Initialize the report parser. */ 217 int rc = usb_hid_parser_init(hid_dev->parser); 218 if (rc != EOK) { 219 usb_log_error("Failed to initialize report parser.\n"); 220 return rc; 221 } 222 223 /* Get the report descriptor and parse it. */ 224 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 225 hid_dev->parser); 226 227 // TODO: remove the hack 228 if (rc != EOK || hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO) { 229 usb_log_warning("Could not process report descriptor.\n"); 230 231 if (hid_dev->poll_pipe_index == USB_HID_KBD_POLL_EP_NO) { 232 usb_log_warning("Falling back to boot protocol.\n"); 233 rc = usb_kbd_set_boot_protocol(hid_dev); 234 } else if (hid_dev->poll_pipe_index 235 == USB_HID_MOUSE_POLL_EP_NO) { 236 usb_log_warning("Falling back to boot protocol.\n"); 237 rc = usb_mouse_set_boot_protocol(hid_dev); 238 } 239 } 240 241 return rc; 242 } 243 244 /*----------------------------------------------------------------------------*/ 245 63 246 usb_hid_dev_t *usb_hid_new(void) 64 247 { … … 84 267 /*----------------------------------------------------------------------------*/ 85 268 86 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)87 {88 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {89 usb_log_debug("Found keyboard endpoint.\n");90 91 // save the pipe index and device type92 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;93 hid_dev->device_type = USB_HID_PROTOCOL_KEYBOARD;94 95 // set the polling callback96 hid_dev->poll_callback = usb_kbd_polling_callback;97 98 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {99 usb_log_debug("Found mouse endpoint.\n");100 101 // save the pipe index and device type102 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;103 hid_dev->device_type = USB_HID_PROTOCOL_MOUSE;104 105 // set the polling callback106 hid_dev->poll_callback = usb_mouse_polling_callback;107 108 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {109 usb_log_debug("Found generic HID endpoint.\n");110 111 // save the pipe index and device type112 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;113 hid_dev->device_type = USB_HID_PROTOCOL_NONE;114 115 // set the polling callback116 hid_dev->poll_callback = usb_hid_polling_callback;117 118 } else {119 usb_log_warning("None of supported endpoints found - probably"120 " not a supported device.\n");121 return ENOTSUP;122 }123 124 return EOK;125 }126 127 /*----------------------------------------------------------------------------*/128 129 static int usb_hid_init_parser(usb_hid_dev_t *hid_dev)130 {131 /* Initialize the report parser. */132 int rc = usb_hid_parser_init(hid_dev->parser);133 if (rc != EOK) {134 usb_log_error("Failed to initialize report parser.\n");135 return rc;136 }137 138 /* Get the report descriptor and parse it. */139 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,140 hid_dev->parser);141 142 if (rc != EOK || hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) {143 usb_log_warning("Could not process report descriptor.\n");144 145 if (hid_dev->device_type == USB_HID_PROTOCOL_KEYBOARD) {146 usb_log_warning("Falling back to boot protocol.\n");147 rc = usb_kbd_set_boot_protocol(hid_dev);148 } else if (hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) {149 usb_log_warning("Falling back to boot protocol.\n");150 rc = usb_mouse_set_boot_protocol(hid_dev);151 }152 }153 154 return rc;155 }156 157 /*----------------------------------------------------------------------------*/158 159 269 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 160 270 { 161 int rc ;271 int rc, i; 162 272 163 273 usb_log_debug("Initializing HID structure...\n"); … … 189 299 } 190 300 191 switch (hid_dev->device_type) { 192 case USB_HID_PROTOCOL_KEYBOARD: 193 // initialize the keyboard structure 194 rc = usb_kbd_init(hid_dev); 195 if (rc != EOK) { 196 usb_log_warning("Failed to initialize KBD structure." 197 "\n"); 198 } 199 break; 200 case USB_HID_PROTOCOL_MOUSE: 201 rc = usb_mouse_init(hid_dev); 202 if (rc != EOK) { 203 usb_log_warning("Failed to initialize Mouse structure." 204 "\n"); 205 } 206 break; 207 default: 208 break; 301 for (i = 0; i < hid_dev->subdriver_count; ++i) { 302 if (hid_dev->subdrivers[i].init != NULL) { 303 rc = hid_dev->subdrivers[i].init(hid_dev); 304 if (rc != EOK) { 305 usb_log_warning("Failed to initialize HID" 306 " subdriver structure.\n"); 307 } 308 } 209 309 } 210 310 211 311 return rc; 312 } 313 314 /*----------------------------------------------------------------------------*/ 315 316 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 317 size_t buffer_size, void *arg) 318 { 319 int i; 320 321 if (dev == NULL || arg == NULL || buffer == NULL) { 322 usb_log_error("Missing arguments to polling callback.\n"); 323 return false; 324 } 325 326 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 327 328 bool cont = false; 329 330 // continue if at least one of the subdrivers want to continue 331 for (i = 0; i < hid_dev->subdriver_count; ++i) { 332 if (hid_dev->subdrivers[i].poll != NULL 333 && hid_dev->subdrivers[i].poll(hid_dev, buffer, 334 buffer_size)) { 335 cont = true; 336 } 337 } 338 339 return cont; 212 340 } 213 341 … … 217 345 void *arg) 218 346 { 347 int i; 348 219 349 if (dev == NULL || arg == NULL) { 220 350 return; … … 223 353 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 224 354 355 for (i = 0; i < hid_dev->subdriver_count; ++i) { 356 if (hid_dev->subdrivers[i].poll_end != NULL) { 357 hid_dev->subdrivers[i].poll_end(hid_dev, reason); 358 } 359 } 360 225 361 usb_hid_free(&hid_dev); 226 362 } … … 228 364 /*----------------------------------------------------------------------------*/ 229 365 230 const char *usb_hid_get_function_name( usb_hid_iface_protocol_t device_type)231 { 232 switch ( device_type) {233 case USB_HID_ PROTOCOL_KEYBOARD:366 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev) 367 { 368 switch (hid_dev->poll_pipe_index) { 369 case USB_HID_KBD_POLL_EP_NO: 234 370 return HID_KBD_FUN_NAME; 235 371 break; 236 case USB_HID_ PROTOCOL_MOUSE:372 case USB_HID_MOUSE_POLL_EP_NO: 237 373 return HID_MOUSE_FUN_NAME; 238 374 break; … … 244 380 /*----------------------------------------------------------------------------*/ 245 381 246 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type) 247 { 248 switch (device_type) { 249 case USB_HID_PROTOCOL_KEYBOARD: 382 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev) 383 { 384 // this means that only boot protocol keyboards will be connected 385 // to the console; there is probably no better way to do this 386 387 switch (hid_dev->poll_pipe_index) { 388 case USB_HID_KBD_POLL_EP_NO: 250 389 return HID_KBD_CLASS_NAME; 251 390 break; 252 case USB_HID_ PROTOCOL_MOUSE:391 case USB_HID_MOUSE_POLL_EP_NO: 253 392 return HID_MOUSE_CLASS_NAME; 254 393 break; … … 262 401 void usb_hid_free(usb_hid_dev_t **hid_dev) 263 402 { 403 int i; 404 264 405 if (hid_dev == NULL || *hid_dev == NULL) { 265 406 return; 266 407 } 267 408 268 switch ((*hid_dev)->device_type) { 269 case USB_HID_PROTOCOL_KEYBOARD: 270 usb_kbd_deinit(*hid_dev); 271 break; 272 case USB_HID_PROTOCOL_MOUSE: 273 usb_mouse_deinit(*hid_dev); 274 break; 275 default: 276 break; 409 for (i = 0; i < (*hid_dev)->subdriver_count; ++i) { 410 if ((*hid_dev)->subdrivers[i].deinit != NULL) { 411 (*hid_dev)->subdrivers[i].deinit(*hid_dev); 412 } 277 413 } 278 414
Note:
See TracChangeset
for help on using the changeset viewer.