Ejemplo n.º 1
0
/**
 * @brief  set  address request
 *
 * @author  liao_zhijun
 * @date    2010-07-27
 * @param dev_addr [in]: address to be set for device
 * @return  T_BOOL
 */
T_BOOL usb_host_std_set_address(T_U32 dev_addr)
{
    T_URB urb;
    T_URB_HANDLE hURB = AK_NULL;
    T_UsbDevReq dev_req;

    dev_req.bmRequestType = USB_STD_DIR_HOST2DEV | USB_STD_REQTYPE_STD | USB_STD_REC_DEVICE;
    dev_req.bRequest = USB_STD_SETADDRESS;
    dev_req.wValue = dev_addr;
    dev_req.wIndex = 0;
    dev_req.wLength = 0;

    fill_urb(&urb, &dev_req, AK_NULL, 0);
    
    hURB = usb_bus_commit_urb(&urb);
    if(AK_NULL == hURB)
    {
        return AK_FALSE;
    }

    if(usb_bus_wait_completion(hURB) < 0)
    {
        return AK_FALSE;
    }
    
    usb_host_set_address(dev_addr);
    
    return AK_TRUE;
}
static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
{
    struct usbdevfs_urb *urb;
    AsyncURB *aurb;
    int ret, value, index;

    /* 
     * Process certain standard device requests.
     * These are infrequent and are processed synchronously.
     */
    value = le16_to_cpu(s->ctrl.req.wValue);
    index = le16_to_cpu(s->ctrl.req.wIndex);

    dprintf("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
        s->ctrl.req.bRequestType, s->ctrl.req.bRequest, value, index, 
        s->ctrl.len);

    if (s->ctrl.req.bRequestType == 0) {
        switch (s->ctrl.req.bRequest) {
        case USB_REQ_SET_ADDRESS:
            return usb_host_set_address(s, value);

        case USB_REQ_SET_CONFIGURATION:
            return usb_host_set_config(s, value & 0xff);
        }
    }

    if (s->ctrl.req.bRequestType == 1 &&
                  s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE)
        return usb_host_set_interface(s, index, value);

    /* The rest are asynchronous */

    aurb = async_alloc();
    if (!aurb) {
        dprintf("husb: async malloc failed\n");
        return USB_RET_NAK;
    }
    aurb->hdev   = s;
    aurb->packet = p;

    /* 
     * Setup ctrl transfer.
     *
     * s->ctrl is layed out such that data buffer immediately follows
     * 'req' struct which is exactly what usbdevfs expects.
     */ 
    urb = &aurb->urb;

    urb->type     = USBDEVFS_URB_TYPE_CONTROL;
    urb->endpoint = p->devep;

    urb->buffer        = &s->ctrl.req;
    urb->buffer_length = 8 + s->ctrl.len;

    urb->usercontext = s;

    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);

    dprintf("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);

    if (ret < 0) {
        dprintf("husb: submit failed. errno %d\n", errno);
        async_free(aurb);

        switch(errno) {
        case ETIMEDOUT:
            return USB_RET_NAK;
        case EPIPE:
        default:
            return USB_RET_STALL;
        }
    }

    usb_defer_packet(p, async_cancel, aurb);
    return USB_RET_ASYNC;
}