Changeset f76153ce in mainline
- Timestamp:
- 2011-04-10T17:57:23Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1cbb4b7
- Parents:
- 62bd8d3
- Location:
- uspace/drv/usbhid
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/subdrivers.c
r62bd8d3 rf76153ce 41 41 { 42 42 path_kbd, 43 1, 43 44 USB_HID_PATH_COMPARE_END 44 45 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, … … 53 54 54 55 }, 55 {NULL, 0, NULL, NULL, {NULL, NULL, NULL, NULL}}56 {NULL, 0, 0, NULL, NULL, {NULL, NULL, NULL, NULL}} 56 57 }; 57 58 -
uspace/drv/usbhid/subdrivers.h
r62bd8d3 rf76153ce 49 49 /*----------------------------------------------------------------------------*/ 50 50 51 /* TODO: This mapping must contain some other information to get the proper 52 * interface. 53 */ 51 54 typedef struct usb_hid_subdriver_mapping { 52 55 const usb_hid_subdriver_usage_t *usage_path; 56 int path_size; 53 57 int compare; 54 58 const char *vendor_id; -
uspace/drv/usbhid/usbhid.c
r62bd8d3 rf76153ce 42 42 #include <usb/classes/hidreq.h> 43 43 #include <errno.h> 44 #include <str_error.h> 44 45 45 46 #include "usbhid.h" … … 60 61 }; 61 62 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 62 65 /*----------------------------------------------------------------------------*/ 63 66 … … 144 147 hid_dev->subdrivers[0].deinit = NULL; 145 148 149 // set subdriver count 150 hid_dev->subdriver_count = 1; 151 146 152 return EOK; 147 153 } … … 149 155 /*----------------------------------------------------------------------------*/ 150 156 157 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev, 158 const usb_hid_subdriver_mapping_t *mapping) 159 { 160 return false; 161 } 162 163 /*----------------------------------------------------------------------------*/ 164 165 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 166 const usb_hid_subdriver_usage_t *path, int path_size, int compare) 167 { 168 assert(hid_dev != NULL); 169 assert(path != NULL); 170 171 usb_hid_report_path_t *usage_path = usb_hid_report_path(); 172 if (usage_path == NULL) { 173 return false; 174 } 175 int i; 176 for (i = 0; i < path_size; ++i) { 177 if (usb_hid_report_path_append_item(usage_path, 178 path[i].usage_page, path[i].usage) != EOK) { 179 usb_hid_report_path_free(usage_path); 180 return false; 181 } 182 } 183 184 bool matches = (usb_hid_report_input_length(hid_dev->parser, usage_path, 185 compare) > 0); 186 187 usb_hid_report_path_free(usage_path); 188 189 return matches; 190 } 191 192 /*----------------------------------------------------------------------------*/ 193 194 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 195 const usb_hid_subdriver_t **subdrivers, int count) 196 { 197 int i; 198 199 if (count <= 0) { 200 hid_dev->subdriver_count = 0; 201 hid_dev->subdrivers = NULL; 202 return EOK; 203 } 204 205 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count * 206 sizeof(usb_hid_subdriver_t)); 207 if (hid_dev->subdrivers == NULL) { 208 return ENOMEM; 209 } 210 211 for (i = 0; i < count; ++i) { 212 hid_dev->subdrivers[i].init = subdrivers[i]->init; 213 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit; 214 hid_dev->subdrivers[i].poll = subdrivers[i]->poll; 215 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 216 } 217 218 hid_dev->subdriver_count = count; 219 220 return EOK; 221 } 222 223 /*----------------------------------------------------------------------------*/ 224 151 225 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 152 226 { 153 return EOK; 227 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 228 229 int i = 0, count = 0; 230 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; 231 232 while (count < USB_HID_MAX_SUBDRIVERS && 233 (mapping->usage_path != NULL 234 || mapping->vendor_id != NULL 235 || mapping->product_id != NULL)) { 236 // check the vendor & product ID 237 if (mapping->vendor_id != NULL && mapping->product_id == NULL) { 238 usb_log_warning("Missing Product ID for Vendor ID %s\n", 239 mapping->vendor_id); 240 return EINVAL; 241 } 242 if (mapping->product_id != NULL && mapping->vendor_id == NULL) { 243 usb_log_warning("Missing Vendor ID for Product ID %s\n", 244 mapping->product_id); 245 return EINVAL; 246 } 247 248 if (mapping->vendor_id != NULL) { 249 assert(mapping->product_id != NULL); 250 usb_log_debug("Comparing device against vendor ID %s" 251 " and product ID %s.\n", mapping->vendor_id, 252 mapping->product_id); 253 if (usb_hid_ids_match(hid_dev, mapping)) { 254 usb_log_debug("Matched.\n"); 255 subdrivers[count++] = &mapping->subdriver; 256 // skip the checking of usage path 257 goto next; 258 } 259 } 260 261 if (mapping->usage_path != NULL) { 262 if (usb_hid_path_matches(hid_dev, 263 mapping->usage_path, mapping->path_size, 264 mapping->compare)) { 265 subdrivers[count++] = &mapping->subdriver; 266 } 267 } 268 next: 269 mapping = &usb_hid_subdrivers[++i]; 270 } 271 272 // we have all subdrivers determined, save them into the hid device 273 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 154 274 } 155 275 … … 158 278 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 159 279 { 160 // first try to find subdrivers that may want to handle this device 161 int rc = usb_hid_find_subdrivers(hid_dev); 280 int rc = EOK; 162 281 163 282 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 164 283 usb_log_debug("Found keyboard endpoint.\n"); 165 166 284 // save the pipe index 167 285 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 168 169 // if no subdrivers registered, use the boot kbd subdriver170 if (hid_dev->subdriver_count == 0) {171 rc = usb_hid_set_boot_kbd_subdriver(hid_dev);172 }173 286 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 174 287 usb_log_debug("Found mouse endpoint.\n"); 175 176 288 // save the pipe index 177 289 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 178 //hid_dev->device_type = USB_HID_PROTOCOL_MOUSE;179 180 // if no subdrivers registered, use the boot kbd subdriver181 if (hid_dev->subdriver_count == 0) {182 rc = usb_hid_set_boot_mouse_subdriver(hid_dev);183 }184 290 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 185 291 usb_log_debug("Found generic HID endpoint.\n"); 186 187 292 // save the pipe index 188 293 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 189 190 if (hid_dev->subdriver_count == 0) {191 usb_log_warning("Found no subdriver for handling this"192 " HID device. Setting generic HID subdriver.\n");193 usb_hid_set_generic_hid_subdriver(hid_dev);194 return EOK;195 }196 294 } else { 197 295 usb_log_error("None of supported endpoints found - probably" 198 296 " not a supported device.\n"); 199 297 rc = ENOTSUP; 200 }201 202 return rc;203 }204 205 /*----------------------------------------------------------------------------*/206 207 static int usb_hid_init_parser(usb_hid_dev_t *hid_dev)208 {209 /* Initialize the report parser. */210 int rc = usb_hid_parser_init(hid_dev->parser);211 if (rc != EOK) {212 usb_log_error("Failed to initialize report parser.\n");213 return rc;214 }215 216 /* Get the report descriptor and parse it. */217 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,218 hid_dev->parser);219 220 // TODO: remove the hack221 if (rc != EOK || hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO) {222 usb_log_warning("Could not process report descriptor.\n");223 224 if (hid_dev->poll_pipe_index == USB_HID_KBD_POLL_EP_NO) {225 usb_log_warning("Falling back to boot protocol.\n");226 rc = usb_kbd_set_boot_protocol(hid_dev);227 } else if (hid_dev->poll_pipe_index228 == USB_HID_MOUSE_POLL_EP_NO) {229 usb_log_warning("Falling back to boot protocol.\n");230 rc = usb_mouse_set_boot_protocol(hid_dev);231 }232 298 } 233 299 … … 255 321 } 256 322 323 hid_dev->poll_pipe_index = -1; 324 257 325 return hid_dev; 258 326 } … … 283 351 rc = usb_hid_check_pipes(hid_dev, dev); 284 352 if (rc != EOK) { 353 usb_hid_free(&hid_dev); 285 354 return rc; 286 355 } 287 356 288 rc = usb_hid_init_parser(hid_dev); 357 /* Initialize the report parser. */ 358 rc = usb_hid_parser_init(hid_dev->parser); 289 359 if (rc != EOK) { 290 usb_log_error("Failed to initialize HID parser.\n"); 360 usb_log_error("Failed to initialize report parser.\n"); 361 usb_hid_free(&hid_dev); 291 362 return rc; 292 363 } 293 364 294 for (i = 0; i < hid_dev->subdriver_count; ++i) { 295 if (hid_dev->subdrivers[i].init != NULL) { 296 rc = hid_dev->subdrivers[i].init(hid_dev); 297 if (rc != EOK) { 298 usb_log_warning("Failed to initialize HID" 299 " subdriver structure.\n"); 365 /* Get the report descriptor and parse it. */ 366 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 367 hid_dev->parser); 368 369 bool fallback = false; 370 371 if (rc == EOK) { 372 // try to find subdrivers that may want to handle this device 373 rc = usb_hid_find_subdrivers(hid_dev); 374 if (rc != EOK || hid_dev->subdriver_count == 0) { 375 // try to fall back to the boot protocol if available 376 usb_log_info("No subdrivers found to handle this" 377 " device.\n"); 378 fallback = true; 379 } 380 } else { 381 usb_log_error("Failed to parse Report descriptor.\n"); 382 // try to fall back to the boot protocol if available 383 fallback = true; 384 } 385 386 // TODO: remove the mouse hack 387 if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO || 388 fallback) { 389 // fall back to boot protocol 390 switch (hid_dev->poll_pipe_index) { 391 case USB_HID_KBD_POLL_EP_NO: 392 usb_log_info("Falling back to kbd boot protocol.\n"); 393 rc = usb_kbd_set_boot_protocol(hid_dev); 394 if (rc == EOK) { 395 rc = usb_hid_set_boot_kbd_subdriver(hid_dev); 300 396 } 301 } 397 break; 398 case USB_HID_MOUSE_POLL_EP_NO: 399 usb_log_info("Falling back to mouse boot protocol.\n"); 400 rc = usb_mouse_set_boot_protocol(hid_dev); 401 if (rc == EOK) { 402 rc = usb_hid_set_boot_mouse_subdriver(hid_dev); 403 } 404 break; 405 default: 406 assert(hid_dev->poll_pipe_index 407 == USB_HID_GENERIC_POLL_EP_NO); 408 409 /* TODO: this has no meaning if the report descriptor 410 is not parsed */ 411 usb_log_info("Falling back to generic HID driver.\n"); 412 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 413 } 414 } 415 416 if (rc != EOK) { 417 usb_log_error("No subdriver for handling this device could be" 418 " initialized: %s.\n", str_error(rc)); 419 usb_hid_free(&hid_dev); 420 } else { 421 bool ok = false; 422 423 usb_log_debug("Subdriver count: %d\n", 424 hid_dev->subdriver_count); 425 426 for (i = 0; i < hid_dev->subdriver_count; ++i) { 427 if (hid_dev->subdrivers[i].init != NULL) { 428 usb_log_debug("Initializing subdriver %d.\n",i); 429 rc = hid_dev->subdrivers[i].init(hid_dev); 430 if (rc != EOK) { 431 usb_log_warning("Failed to initialize" 432 " HID subdriver structure.\n"); 433 } else { 434 // at least one subdriver initialized 435 ok = true; 436 } 437 } else { 438 ok = true; 439 } 440 } 441 442 rc = (ok) ? EOK : -1; // what error to report 302 443 } 303 444 … … 400 541 } 401 542 543 assert((*hid_dev)->subdrivers != NULL 544 || (*hid_dev)->subdriver_count == 0); 545 402 546 for (i = 0; i < (*hid_dev)->subdriver_count; ++i) { 403 547 if ((*hid_dev)->subdrivers[i].deinit != NULL) { … … 405 549 } 406 550 } 551 552 // free the subdrivers info 553 if ((*hid_dev)->subdrivers != NULL) { 554 free(subdrivers); 555 } 407 556 408 557 // destroy the parser
Note:
See TracChangeset
for help on using the changeset viewer.