Changes in uspace/lib/usbdev/src/recognise.c [77ad86c:162726b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/recognise.c
r77ad86c r162726b 33 33 * Functions for recognition of attached devices. 34 34 */ 35 36 35 #include <sys/types.h> 37 36 #include <fibril_synch.h> 38 #include <usb/debug.h>39 #include <usb/dev/hub.h>40 37 #include <usb/dev/pipes.h> 41 38 #include <usb/dev/recognise.h> … … 47 44 #include <assert.h> 48 45 46 /** Index to append after device name for uniqueness. */ 47 static size_t device_name_index = 0; 48 /** Mutex guard for device_name_index. */ 49 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 50 49 51 /** DDF operations of child devices. */ 50 staticddf_dev_ops_t child_ops = {52 ddf_dev_ops_t child_ops = { 51 53 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 52 54 }; … … 62 64 #define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a)) 63 65 66 /* FIXME: make this dynamic */ 67 #define MATCH_STRING_MAX 256 68 64 69 /** Add formatted match id. 65 70 * … … 70 75 */ 71 76 static int usb_add_match_id(match_id_list_t *matches, int score, 72 const char * match_str)77 const char *format, ...) 73 78 { 74 assert(matches); 75 76 match_id_t *match_id = create_match_id(); 79 char *match_str = NULL; 80 match_id_t *match_id = NULL; 81 int rc; 82 83 match_str = malloc(MATCH_STRING_MAX + 1); 84 if (match_str == NULL) { 85 rc = ENOMEM; 86 goto failure; 87 } 88 89 /* 90 * FIXME: replace with dynamic allocation of exact size 91 */ 92 va_list args; 93 va_start(args, format ); 94 vsnprintf(match_str, MATCH_STRING_MAX, format, args); 95 match_str[MATCH_STRING_MAX] = 0; 96 va_end(args); 97 98 match_id = create_match_id(); 77 99 if (match_id == NULL) { 78 return ENOMEM; 100 rc = ENOMEM; 101 goto failure; 79 102 } 80 103 … … 84 107 85 108 return EOK; 109 110 failure: 111 if (match_str != NULL) { 112 free(match_str); 113 } 114 if (match_id != NULL) { 115 match_id->id = NULL; 116 delete_match_id(match_id); 117 } 118 119 return rc; 86 120 } 87 121 … … 95 129 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \ 96 130 do { \ 97 char *str = NULL; \ 98 int __rc = asprintf(&str, format, ##__VA_ARGS__); \ 99 if (__rc > 0) { \ 100 __rc = usb_add_match_id((match_ids), (score), str); \ 101 } \ 131 int __rc = usb_add_match_id((match_ids), (score), \ 132 format, ##__VA_ARGS__); \ 102 133 if (__rc != EOK) { \ 103 free(str); \104 134 return __rc; \ 105 135 } \ … … 120 150 match_id_list_t *matches) 121 151 { 122 if (desc_interface == NULL || matches == NULL) { 152 if (desc_interface == NULL) { 153 return EINVAL; 154 } 155 if (matches == NULL) { 123 156 return EINVAL; 124 157 } … … 281 314 match_id_list_t *matches) 282 315 { 283 assert(ctrl_pipe);284 316 int rc; 285 317 /* … … 304 336 /** Probe for device kind and register it in devman. 305 337 * 306 * @param[in] ctrl_pipe Control pipe to the device. 338 * @param[in] address Address of the (unknown) attached device. 339 * @param[in] hc_handle Handle of the host controller. 307 340 * @param[in] parent Parent device. 308 * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.341 * @param[in] dev_ops Child device ops. 309 342 * @param[in] dev_data Arbitrary pointer to be stored in the child 310 343 * as @c driver_data. … … 312 345 * will be written. 313 346 * @return Error code. 314 * 315 */ 316 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe, 317 ddf_dev_t *parent, ddf_dev_ops_t *dev_ops, void *dev_data, 318 ddf_fun_t **child_fun) 347 */ 348 int usb_device_register_child_in_devman(usb_address_t address, 349 devman_handle_t hc_handle, ddf_dev_t *parent, 350 ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun) 319 351 { 320 if (child_fun == NULL || ctrl_pipe == NULL) 321 return EINVAL; 322 323 if (!dev_ops && dev_data) { 324 usb_log_warning("Using standard fun ops with arbitrary " 325 "driver data. This does not have to work.\n"); 326 } 327 328 /** Index to append after device name for uniqueness. */ 329 static atomic_t device_name_index = {0}; 330 const size_t this_device_name_index = 331 (size_t) atomic_preinc(&device_name_index); 332 352 size_t this_device_name_index; 353 354 fibril_mutex_lock(&device_name_index_mutex); 355 this_device_name_index = device_name_index; 356 device_name_index++; 357 fibril_mutex_unlock(&device_name_index_mutex); 358 333 359 ddf_fun_t *child = NULL; 360 char *child_name = NULL; 334 361 int rc; 335 362 usb_device_connection_t dev_connection; 363 usb_pipe_t ctrl_pipe; 364 365 rc = usb_device_connection_initialize(&dev_connection, hc_handle, address); 366 if (rc != EOK) { 367 goto failure; 368 } 369 370 rc = usb_pipe_initialize_default_control(&ctrl_pipe, 371 &dev_connection); 372 if (rc != EOK) { 373 goto failure; 374 } 375 rc = usb_pipe_probe_default_control(&ctrl_pipe); 376 if (rc != EOK) { 377 goto failure; 378 } 379 336 380 /* 337 381 * TODO: Once the device driver framework support persistent 338 382 * naming etc., something more descriptive could be created. 339 383 */ 340 char child_name[12]; /* The format is: "usbAB_aXYZ", length 11 */ 341 rc = snprintf(child_name, sizeof(child_name), 342 "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address); 384 rc = asprintf(&child_name, "usb%02zu_a%d", 385 this_device_name_index, address); 343 386 if (rc < 0) { 344 387 goto failure; 345 388 } 346 389 347 390 child = ddf_fun_create(parent, fun_inner, child_name); 348 391 if (child == NULL) { … … 350 393 goto failure; 351 394 } 352 353 if (dev_ops != NULL) 395 396 if (dev_ops != NULL) { 354 397 child->ops = dev_ops; 355 else398 } else { 356 399 child->ops = &child_ops; 357 400 } 401 358 402 child->driver_data = dev_data; 359 /* 360 * Store the attached device in fun 361 * driver data if there is no other data 362 */ 363 if (!dev_data) { 364 usb_hub_attached_device_t *new_device = ddf_fun_data_alloc( 365 child, sizeof(usb_hub_attached_device_t)); 366 if (!new_device) { 367 rc = ENOMEM; 368 goto failure; 369 } 370 371 new_device->address = ctrl_pipe->wire->address; 372 new_device->fun = child; 373 } 374 375 rc = usb_device_create_match_ids(ctrl_pipe, &child->match_ids); 376 if (rc != EOK) 377 goto failure; 378 403 404 rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids); 405 if (rc != EOK) { 406 goto failure; 407 } 408 379 409 rc = ddf_fun_bind(child); 380 if (rc != EOK) 381 goto failure; 382 383 *child_fun = child; 410 if (rc != EOK) { 411 goto failure; 412 } 413 414 if (child_fun != NULL) { 415 *child_fun = child; 416 } 417 384 418 return EOK; 385 419 386 420 failure: 387 421 if (child != NULL) { 388 /* We know nothing about the data if it came from outside. */ 389 if (dev_data) 390 child->driver_data = NULL; 391 422 child->name = NULL; 392 423 /* This takes care of match_id deallocation as well. */ 393 424 ddf_fun_destroy(child); 394 425 } 395 426 if (child_name != NULL) { 427 free(child_name); 428 } 429 396 430 return rc; 397 431 } 398 432 433 399 434 /** 400 435 * @}
Note:
See TracChangeset
for help on using the changeset viewer.