Changeset e4dbfda in mainline
- Timestamp:
- 2010-11-26T21:26:15Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 08f747e
- Parents:
- 172c1682
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/hcdhubd.h
r172c1682 re4dbfda 175 175 int usb_hc_async_wait_for(usb_handle_t); 176 176 177 int usb_hc_add_child_device(device_t *, const char *, const char *); 177 178 178 179 #endif -
uspace/lib/usb/src/hcdhubd.c
r172c1682 re4dbfda 263 263 int usb_hcd_add_root_hub(usb_hc_device_t *dev) 264 264 { 265 char *id; 266 int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 267 if (rc <= 0) { 268 return rc; 269 } 270 271 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id); 272 if (rc != EOK) { 273 free(id); 274 } 275 276 return rc; 277 } 278 279 /** Info about child device. */ 280 struct child_device_info { 281 device_t *parent; 282 const char *name; 283 const char *match_id; 284 }; 285 286 /** Adds a child device fibril worker. */ 287 static int fibril_add_child_device(void *arg) 288 { 289 struct child_device_info *child_info 290 = (struct child_device_info *) arg; 265 291 int rc; 266 292 267 /* 268 * Announce presence of child device. 269 */ 270 device_t *hub = NULL; 293 device_t *child = create_device(); 271 294 match_id_t *match_id = NULL; 272 295 273 hub = create_device(); 274 if (hub == NULL) { 296 if (child == NULL) { 275 297 rc = ENOMEM; 276 298 goto failure; 277 299 } 278 hub->name = USB_HUB_DEVICE_NAME;300 child->name = child_info->name; 279 301 280 302 match_id = create_match_id(); … … 283 305 goto failure; 284 306 } 285 286 char *id; 287 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 288 if (rc <= 0) { 289 rc = ENOMEM; 307 match_id->id = child_info->match_id; 308 match_id->score = 10; 309 printf("adding child device with match \"%s\"\n", match_id->id); 310 add_match_id(&child->match_ids, match_id); 311 312 rc = child_device_register(child, child_info->parent); 313 if (rc != EOK) { 290 314 goto failure; 291 315 } 292 316 293 match_id->id = id; 294 match_id->score = 30; 295 296 add_match_id(&hub->match_ids, match_id); 297 298 rc = child_device_register(hub, dev->generic); 299 if (rc != EOK) { 300 goto failure; 301 } 302 303 printf("%s: registered root hub\n", dev->generic->name); 317 goto leave; 318 319 failure: 320 if (child != NULL) { 321 child->name = NULL; 322 delete_device(child); 323 } 324 325 if (match_id != NULL) { 326 match_id->id = NULL; 327 delete_match_id(match_id); 328 } 329 330 leave: 331 free(arg); 332 return rc; 333 } 334 335 /** Adds a child. 336 * Due to deadlock in devman when parent registers child that oughts to be 337 * driven by the same task, the child adding is done in separate fibril. 338 * Not optimal, but it works. 339 * 340 * @param parent Parent device. 341 * @param name Device name. 342 * @param match_id Match id. 343 * @return Error code. 344 */ 345 int usb_hc_add_child_device(device_t *parent, const char *name, 346 const char *match_id) 347 { 348 struct child_device_info *child_info 349 = malloc(sizeof(struct child_device_info)); 350 351 child_info->parent = parent; 352 child_info->name = name; 353 child_info->match_id = match_id; 354 355 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 356 if (!fibril) { 357 return ENOMEM; 358 } 359 fibril_add_ready(fibril); 360 304 361 return EOK; 305 306 failure:307 if (hub != NULL) {308 hub->name = NULL;309 delete_device(hub);310 }311 delete_match_id(match_id);312 313 return rc;314 362 } 315 363
Note:
See TracChangeset
for help on using the changeset viewer.