Changes in / [da55d5b:8e423a2d] in mainline


Ignore:
Location:
uspace/lib
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/remote_usbhc.c

    rda55d5b r8e423a2d  
    4242#define USB_MAX_PAYLOAD_SIZE 1020
    4343
     44static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4445static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4546static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    4950/** Remote USB interface operations. */
    5051static 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
    5456};
    5557
     
    6870} async_transaction_t;
    6971
     72void 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}
    7092
    7193void remote_usbhc_get_buffer(device_t *device, void *iface,
  • uspace/lib/drv/include/usbhc_iface.h

    rda55d5b r8e423a2d  
    9292 */
    9393typedef 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
    94105        /** Asks for data buffer.
    95106         * See explanation at usb_iface_funcs_t.
     
    157168/** USB devices communication interface. */
    158169typedef struct {
     170        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
    159171        int (*interrupt_out)(device_t *, usb_target_t,
    160172            void *, size_t,
  • uspace/lib/usb/include/usb/hcdhubd.h

    rda55d5b r8e423a2d  
    175175int usb_hc_async_wait_for(usb_handle_t);
    176176
     177int usb_hc_add_child_device(device_t *, const char *, const char *);
    177178
    178179#endif
  • uspace/lib/usb/src/hcdhubd.c

    rda55d5b r8e423a2d  
    414414 * @return Error code.
    415415 */
    416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) {
     416int 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. */
     433struct 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. */
     440static int fibril_add_child_device(void *arg)
     441{
     442        struct child_device_info *child_info
     443            = (struct child_device_info *) arg;
    417444        int rc;
    418445
    419         /*
    420          * Announce presence of child device.
    421          */
    422         device_t *hub = NULL;
     446        device_t *child = create_device();
    423447        match_id_t *match_id = NULL;
    424448
    425         hub = create_device();
    426         if (hub == NULL) {
     449        if (child == NULL) {
    427450                rc = ENOMEM;
    428451                goto failure;
    429452        }
    430         hub->name = USB_HUB_DEVICE_NAME;
     453        child->name = child_info->name;
    431454
    432455        match_id = create_match_id();
     
    435458                goto failure;
    436459        }
    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);
    451466        if (rc != EOK) {
    452467                goto failure;
    453468        }
    454469
    455         printf("%s: registered root hub\n", dev->generic->name);
     470        goto leave;
     471
     472failure:
     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
     483leave:
     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 */
     498int 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
    456514        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;
    466515}
    467516
  • uspace/lib/usb/src/usbdrv.c

    rda55d5b r8e423a2d  
    6464         * Call parent hub to obtain device handle of respective HC.
    6565         */
    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;
    6781}
    6882
     
    7589usb_address_t usb_drv_get_my_address(int phone, device_t *dev)
    7690{
    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;
    78100}
    79101
Note: See TracChangeset for help on using the changeset viewer.