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