Changes in uspace/lib/usbdev/src/recognise.c [c01987c:feeac0d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/recognise.c
rc01987c rfeeac0d 34 34 */ 35 35 36 /** XXX Fix this */ 37 #define _DDF_DATA_IMPLANT 38 39 #include <sys/types.h> 40 #include <fibril_synch.h> 41 #include <usb/debug.h> 42 #include <usb/dev/hub.h> 36 43 #include <usb/dev/pipes.h> 37 44 #include <usb/dev/recognise.h> 45 #include <usb/ddfiface.h> 38 46 #include <usb/dev/request.h> 39 47 #include <usb/classes/classes.h> 40 48 #include <stdio.h> 49 #include <errno.h> 41 50 #include <assert.h> 42 #include <errno.h> 43 #include <stdio.h> 44 #include <sys/types.h> 51 52 /** DDF operations of child devices. */ 53 static ddf_dev_ops_t child_ops = { 54 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 55 }; 45 56 46 57 /** Get integer part from BCD coded number. */ … … 234 245 (int) device_descriptor->product_id, 235 246 BCD_ARGS(device_descriptor->device_version)); 236 247 237 248 /* Next, without release number. */ 238 249 ADD_MATCHID_OR_RETURN(matches, 90, … … 240 251 (int) device_descriptor->vendor_id, 241 252 (int) device_descriptor->product_id); 242 } 243 244 /* Class match id */ 245 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s", 246 usb_str_class(device_descriptor->device_class)); 247 253 } 254 255 /* 256 * If the device class points to interface we skip adding 257 * class directly but we add a multi interface device. 258 */ 259 if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) { 260 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s", 261 usb_str_class(device_descriptor->device_class)); 262 } else { 263 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid"); 264 } 265 248 266 /* As a last resort, try fallback driver. */ 249 267 ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback"); … … 287 305 } 288 306 307 /** Probe for device kind and register it in devman. 308 * 309 * @param[in] ctrl_pipe Control pipe to the device. 310 * @param[in] parent Parent device. 311 * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL. 312 * @param[in] dev_data Arbitrary pointer to be stored in the child 313 * as @c driver_data. 314 * @param[out] child_fun Storage where pointer to allocated child function 315 * will be written. 316 * @return Error code. 317 * 318 */ 319 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe, 320 ddf_dev_t *parent, ddf_dev_ops_t *dev_ops, void *dev_data, 321 ddf_fun_t **child_fun) 322 { 323 if (child_fun == NULL || ctrl_pipe == NULL) 324 return EINVAL; 325 326 if (!dev_ops && dev_data) { 327 usb_log_warning("Using standard fun ops with arbitrary " 328 "driver data. This does not have to work.\n"); 329 } 330 331 /** Index to append after device name for uniqueness. */ 332 static atomic_t device_name_index = {0}; 333 const size_t this_device_name_index = 334 (size_t) atomic_preinc(&device_name_index); 335 336 ddf_fun_t *child = NULL; 337 int rc; 338 339 /* 340 * TODO: Once the device driver framework support persistent 341 * naming etc., something more descriptive could be created. 342 */ 343 char child_name[12]; /* The format is: "usbAB_aXYZ", length 11 */ 344 rc = snprintf(child_name, sizeof(child_name), 345 "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address); 346 if (rc < 0) { 347 goto failure; 348 } 349 350 child = ddf_fun_create(parent, fun_inner, child_name); 351 if (child == NULL) { 352 rc = ENOMEM; 353 goto failure; 354 } 355 356 if (dev_ops != NULL) 357 ddf_fun_set_ops(child, dev_ops); 358 else 359 ddf_fun_set_ops(child, &child_ops); 360 361 ddf_fun_data_implant(child, dev_data); 362 363 /* 364 * Store the attached device in fun 365 * driver data if there is no other data 366 */ 367 if (!dev_data) { 368 usb_hub_attached_device_t *new_device = ddf_fun_data_alloc( 369 child, sizeof(usb_hub_attached_device_t)); 370 if (!new_device) { 371 rc = ENOMEM; 372 goto failure; 373 } 374 375 new_device->address = ctrl_pipe->wire->address; 376 new_device->fun = child; 377 } 378 379 match_id_list_t match_ids; 380 init_match_ids(&match_ids); 381 rc = usb_device_create_match_ids(ctrl_pipe, &match_ids); 382 if (rc != EOK) 383 goto failure; 384 385 list_foreach(match_ids.ids, link, match_id_t, match_id) { 386 rc = ddf_fun_add_match_id(child, match_id->id, match_id->score); 387 if (rc != EOK) { 388 clean_match_ids(&match_ids); 389 goto failure; 390 } 391 } 392 393 clean_match_ids(&match_ids); 394 395 rc = ddf_fun_bind(child); 396 if (rc != EOK) 397 goto failure; 398 399 *child_fun = child; 400 return EOK; 401 402 failure: 403 if (child != NULL) { 404 /* This takes care of match_id deallocation as well. */ 405 ddf_fun_destroy(child); 406 } 407 408 return rc; 409 } 410 289 411 /** 290 412 * @}
Note:
See TracChangeset
for help on using the changeset viewer.