Changeset 8e423a2d in mainline
- Timestamp:
- 2010-11-26T21:51:36Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ef75332
- Parents:
- da55d5b (diff), 08f747e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
rda55d5b r8e423a2d 42 42 #define USB_MAX_PAYLOAD_SIZE 1020 43 43 44 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 45 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 46 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 49 50 /** Remote USB interface operations. */ 50 51 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 51 &remote_usbhc_get_buffer, 52 &remote_usbhc_interrupt_out, 53 &remote_usbhc_interrupt_in 52 remote_usbhc_get_address, 53 remote_usbhc_get_buffer, 54 remote_usbhc_interrupt_out, 55 remote_usbhc_interrupt_in 54 56 }; 55 57 … … 68 70 } async_transaction_t; 69 71 72 void remote_usbhc_get_address(device_t *device, void *iface, 73 ipc_callid_t callid, ipc_call_t *call) 74 { 75 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 76 77 if (!usb_iface->tell_address) { 78 ipc_answer_0(callid, ENOTSUP); 79 return; 80 } 81 82 devman_handle_t handle = IPC_GET_ARG1(*call); 83 84 usb_address_t address; 85 int rc = usb_iface->tell_address(device, handle, &address); 86 if (rc != EOK) { 87 ipc_answer_0(callid, rc); 88 } else { 89 ipc_answer_1(callid, EOK, address); 90 } 91 } 70 92 71 93 void remote_usbhc_get_buffer(device_t *device, void *iface, -
uspace/lib/drv/include/usbhc_iface.h
rda55d5b r8e423a2d 92 92 */ 93 93 typedef enum { 94 /** Tell USB address assigned to device. 95 * Parameters: 96 * - devman handle id 97 * Answer: 98 * - EINVAL - unknown handle or handle not managed by this driver 99 * - ENOTSUP - operation not supported by HC (shall not happen) 100 * - arbitrary error code if returned by remote implementation 101 * - EOK - handle found, first parameter contains the USB address 102 */ 103 IPC_M_USBHC_GET_ADDRESS, 104 94 105 /** Asks for data buffer. 95 106 * See explanation at usb_iface_funcs_t. … … 157 168 /** USB devices communication interface. */ 158 169 typedef struct { 170 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 159 171 int (*interrupt_out)(device_t *, usb_target_t, 160 172 void *, size_t, -
uspace/lib/usb/include/usb/hcdhubd.h
rda55d5b r8e423a2d 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
rda55d5b r8e423a2d 414 414 * @return Error code. 415 415 */ 416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) { 416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) 417 { 418 char *id; 419 int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 420 if (rc <= 0) { 421 return rc; 422 } 423 424 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id); 425 if (rc != EOK) { 426 free(id); 427 } 428 429 return rc; 430 } 431 432 /** Info about child device. */ 433 struct child_device_info { 434 device_t *parent; 435 const char *name; 436 const char *match_id; 437 }; 438 439 /** Adds a child device fibril worker. */ 440 static int fibril_add_child_device(void *arg) 441 { 442 struct child_device_info *child_info 443 = (struct child_device_info *) arg; 417 444 int rc; 418 445 419 /* 420 * Announce presence of child device. 421 */ 422 device_t *hub = NULL; 446 device_t *child = create_device(); 423 447 match_id_t *match_id = NULL; 424 448 425 hub = create_device(); 426 if (hub == NULL) { 449 if (child == NULL) { 427 450 rc = ENOMEM; 428 451 goto failure; 429 452 } 430 hub->name = USB_HUB_DEVICE_NAME;453 child->name = child_info->name; 431 454 432 455 match_id = create_match_id(); … … 435 458 goto failure; 436 459 } 437 438 char *id; 439 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 440 if (rc <= 0) { 441 rc = ENOMEM; 442 goto failure; 443 } 444 445 match_id->id = id; 446 match_id->score = 30; 447 448 add_match_id(&hub->match_ids, match_id); 449 450 rc = child_device_register(hub, dev->generic); 460 match_id->id = child_info->match_id; 461 match_id->score = 10; 462 printf("adding child device with match \"%s\"\n", match_id->id); 463 add_match_id(&child->match_ids, match_id); 464 465 rc = child_device_register(child, child_info->parent); 451 466 if (rc != EOK) { 452 467 goto failure; 453 468 } 454 469 455 printf("%s: registered root hub\n", dev->generic->name); 470 goto leave; 471 472 failure: 473 if (child != NULL) { 474 child->name = NULL; 475 delete_device(child); 476 } 477 478 if (match_id != NULL) { 479 match_id->id = NULL; 480 delete_match_id(match_id); 481 } 482 483 leave: 484 free(arg); 485 return rc; 486 } 487 488 /** Adds a child. 489 * Due to deadlock in devman when parent registers child that oughts to be 490 * driven by the same task, the child adding is done in separate fibril. 491 * Not optimal, but it works. 492 * 493 * @param parent Parent device. 494 * @param name Device name. 495 * @param match_id Match id. 496 * @return Error code. 497 */ 498 int usb_hc_add_child_device(device_t *parent, const char *name, 499 const char *match_id) 500 { 501 struct child_device_info *child_info 502 = malloc(sizeof(struct child_device_info)); 503 504 child_info->parent = parent; 505 child_info->name = name; 506 child_info->match_id = match_id; 507 508 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 509 if (!fibril) { 510 return ENOMEM; 511 } 512 fibril_add_ready(fibril); 513 456 514 return EOK; 457 458 failure:459 if (hub != NULL) {460 hub->name = NULL;461 delete_device(hub);462 }463 delete_match_id(match_id);464 465 return rc;466 515 } 467 516 -
uspace/lib/usb/src/usbdrv.c
rda55d5b r8e423a2d 64 64 * Call parent hub to obtain device handle of respective HC. 65 65 */ 66 return ENOTSUP; 66 67 /* 68 * FIXME: currently we connect always to virtual host controller. 69 */ 70 int rc; 71 devman_handle_t handle; 72 73 rc = devman_device_get_handle("/vhc", &handle, 0); 74 if (rc != EOK) { 75 return rc; 76 } 77 78 int phone = devman_device_connect(handle, 0); 79 80 return phone; 67 81 } 68 82 … … 75 89 usb_address_t usb_drv_get_my_address(int phone, device_t *dev) 76 90 { 77 return ENOTSUP; 91 ipcarg_t address; 92 int rc = async_req_1_1(phone, IPC_M_USBHC_GET_ADDRESS, 93 dev->handle, &address); 94 95 if (rc != EOK) { 96 return rc; 97 } 98 99 return (usb_address_t) address; 78 100 } 79 101
Note:
See TracChangeset
for help on using the changeset viewer.