Ejemplo n.º 1
0
/*
 *  This is our function to emulate USBH_SendCtrlMsg() but give us enough
 *  access to make aborts/resets work
 */
static int  usb_stor_control_msg(UMAS_DATA_T *umas, uint32_t pipe,
                                 uint8_t request, uint8_t requesttype, uint16_t value,
                                 uint16_t index, void *data, uint16_t size)
{
    URB_T       *urb = umas->current_urb;
    int         status;
    volatile int t0;
    DEV_REQ_T   dr;

    /* fill in the structure */
    dr.requesttype = requesttype;
    dr.request = request;
    dr.value = value;
    dr.index = index;
    dr.length = size;

    /* fill the URB */
    FILL_CONTROL_URB(urb, umas->pusb_dev, pipe, (uint8_t *)&dr, data, size,
                     usb_stor_blocking_completion, NULL);
    urb->actual_length = 0;
    urb->error_count = 0;
    urb->transfer_flags = USB_ASYNC_UNLINK;

    _UmasUrbComplete = 0;

    /* submit the URB */
    status = USBH_SubmitUrb(urb);
    if(status)
        return status;

    /* wait for the completion of the URB */
#if 1
    for(t0 = 0; t0 < 0x8000000; t0++)
    {
        if(is_urb_completed())
            break;
    }
    if(t0 >= 0x8000000)
#else
    t0 = umas_get_ticks();
    while(umas_get_ticks() - t0 < 300)
    {
        if(is_urb_completed())
            break;
    }

    if(umas_get_ticks() - t0 >= 300)
#endif
    {
        UMAS_DEBUG("usb_stor_control_msg time-out failed!\n");
        return USB_ERR_TIMEOUT;
    }

    /* return the actual length of the data transferred if no error*/
    status = urb->status;
    if(status >= 0)
        status = urb->actual_length;

    return status;
}
Ejemplo n.º 2
0
/*
 *  This is our function to emulate usb_bulk_msg() but give us enough
 *  access to make aborts/resets work
 */
static int  usb_stor_bulk_msg(UMAS_DATA_T *umas, void *data, int pipe,
                              uint32_t len, uint32_t *act_len)
{
    URB_T   *urb = umas->current_urb;
    volatile int  t0;
    int     status;

    /* fill the URB */
    FILL_BULK_URB(urb, umas->pusb_dev, pipe, data, len,
                  usb_stor_blocking_completion, NULL);
    urb->actual_length = 0;
    urb->error_count = 0;
    urb->transfer_flags = USB_ASYNC_UNLINK;

    _UmasUrbComplete = 0;

    /* submit the URB */
    status = USBH_SubmitUrb(urb);
    if(status)
        return status;

#if 1
    for(t0 = 0; t0 < 0x1000000; t0++)
    {
        if(is_urb_completed())
            break;
    }
    if(t0 >= 0x8000000)
#else
    t0 = umas_get_ticks();
    while(umas_get_ticks() - t0 < 500)
    {
        if(is_urb_completed())
            break;
    }
    if(umas_get_ticks() - t0 >= 500)
#endif
    {
        UMAS_DEBUG("usb_stor_bulk_msg time-out failed!\n");
        return USB_ERR_TIMEOUT;
    }

    /* return the actual length of the data transferred */
    *act_len = urb->actual_length;

    return urb->status;
}
Ejemplo n.º 3
0
static int usb_hub_configure(USB_HUB_T *hub, EP_INFO_T *ep_info)
{
    USB_DEV_T           *dev = hub->dev;
    USB_HUB_STATUS_T    hubstatus;
    uint32_t            pipe;
    int                 maxp, ret;

    USB_info("[HUB] Enter usb_hub_configure()... hub:%d\n", hub->dev->devnum);

    /* Request the entire hub descriptor. */
    ret = usb_get_hub_descriptor(dev, &hub->descriptor, sizeof(USB_HUB_DESC_T));

    /* <hub->descriptor> is large enough for a hub with 127 ports;
     * the hub can/will return fewer bytes here. */
    if(ret < 0)
    {
        USB_error("Erro - Unable to get hub descriptor (err = %d)\n", ret);
        return ret;
    }

    dev->maxchild = hub->descriptor.bNbrPorts;

#ifdef USB_VERBOSE_DEBUG
    USB_info("%d port%s detected\n", hub->descriptor.bNbrPorts, (hub->descriptor.bNbrPorts == 1) ? "" : "s");

    /* D2: Identifying a Compound Device */
    if(hub->descriptor.wHubCharacteristics & HUB_CHAR_COMPOUND)
    {
        USB_info("part of a compound device\n");
    }
    else
    {
        USB_info("standalone hub\n");
    }

    /* D1..D0: Logical Power Switching Mode */
    switch(hub->descriptor.wHubCharacteristics & HUB_CHAR_LPSM)
    {
        case 0x00:
            USB_info("ganged power switching\n");
            break;
        case 0x01:
            USB_info("individual port power switching\n");
            break;
        case 0x02:
        case 0x03:
            USB_info("unknown reserved power switching mode\n");
            break;
    }

    /* D4..D3: Over-current Protection Mode */
    switch(hub->descriptor.wHubCharacteristics & HUB_CHAR_OCPM)
    {
        case 0x00:
            USB_info("global over-current protection\n");
            break;
        case 0x08:
            USB_info("individual port over-current protection\n");
            break;
        case 0x10:
        case 0x18:
            USB_info("no over-current protection\n");
            break;
    }

    switch(dev->descriptor.bDeviceProtocol)
    {
        case 0:
            break;
        case 1:
            USB_debug("Single TT, ");
            break;
        case 2:
            USB_debug("TT per port, ");
            break;
        default:
            USB_debug("Unrecognized hub protocol %d", dev->descriptor.bDeviceProtocol);
            break;
    }

    USB_info("power on to power good time: %dms\n", hub->descriptor.bPwrOn2PwrGood * 2);
    USB_info("hub controller current requirement: %dmA\n", hub->descriptor.bHubContrCurrent);
#endif

    ret = usb_get_hub_status(dev, &hubstatus);
    if(ret < 0)
    {
        USB_error("Unable to get hub %d status (err = %d)\n", hub->dev->devnum, ret);
        return ret;
    }

    hubstatus.wHubStatus = USB_SWAP16(hubstatus.wHubStatus);

#ifdef USB_VERBOSE_DEBUG
    /* Hub status bit 0, Local Power Source */
    if(hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER)
    {
        USB_info("local power source is lost (inactive)\n");
    }
    else
    {
        USB_info("local power source is good\n");
    }

    /* Hub status bit 1, Over-current Indicator */
    if(hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT)
    {
        USB_info("!! over-current\n");
    }
    else
    {
        USB_info("No over-current.\n");
    }
#endif

    /* Start the interrupt endpoint */
    pipe = usb_rcvintpipe(dev, ep_info->bEndpointAddress);
    maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

    if(maxp > sizeof(hub->buffer))
        maxp = sizeof(hub->buffer);

    hub->urb = USBH_AllocUrb();
    if(!hub->urb)
    {
        USB_error("Error - couldn't allocate interrupt urb");
        return USB_ERR_NOMEM;
    }

#if 1   /* YCHuang 2012.06.01 */
    if(ep_info->bInterval < 16)
        ep_info->bInterval = 16;
#endif
    FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
                 hub, ep_info->bInterval);
    ret = USBH_SubmitUrb(hub->urb);
    if(ret)
    {
        USB_error("Error - USBH_SubmitUrb failed (%d)", ret);
        USBH_FreeUrb(hub->urb);
        return ret;
    }

    if(g_ohci_bus.root_hub != hub->dev)
        usb_hub_power_on(hub);
    return 0;
}