首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux 2.6下编译usb驱动和arm板进行数据通信(5)

linux 2.6下编译usb驱动和arm板进行数据通信(5)

/*
* usb class driver info in order to get a minor number from the usb core,
* and to have the device registered with the driver core
*/

static struct usb_class_driver lcd_class = {
        .name =         "gliethttp_flash%d",
        .fops =         &lcd_fops,
        .minor_base =   USBLCD_MINOR,
};

static int lcd_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
    struct usb_lcd *dev = NULL;
    struct usb_host_interface *iface_desc;
    struct usb_endpoint_descriptor *endpoint;
    size_t buffer_size;
    int i;
    int retval = -ENOMEM;

    /* allocate memory for our device state and initialize it */
    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (dev == NULL) {
        err("Out of memory");
        goto error;
    }
    kref_init(&dev->kref);
    sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);

    dev->udev = usb_get_dev(interface_to_usbdev(interface));
    dev->interface = interface;

/*
    //gliethttp_20080527
    if (le16_to_cpu(dev->udev->descriptor.idProduct) != 0x0001) {
        warn(KERN_INFO "USBLCD model not supported.");
        return -ENODEV;
    }
*/

   
    /* set up the endpoint information */
    /* use only the first bulk-in and bulk-out endpoints */
    iface_desc = interface->cur_altsetting;
    for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
        endpoint = &iface_desc->endpoint[i].desc;

        if (!dev->bulk_in_endpointAddr &&
            usb_endpoint_is_bulk_in(endpoint)) {
            /* we found a bulk in endpoint */
            buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
            dev->bulk_in_size = buffer_size;
            dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
            dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
            if (!dev->bulk_in_buffer) {
                err("Could not allocate bulk_in_buffer");
                goto error;
            }
        }

        if (!dev->bulk_out_endpointAddr &&
            usb_endpoint_is_bulk_out(endpoint)) {
            /* we found a bulk out endpoint */
            dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
        }
    }
    if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
        err("Could not find both bulk-in and bulk-out endpoints");
        goto error;
    }

    /* save our data pointer in this interface device */
    usb_set_intfdata(interface, dev);

    /* we can register the device now, as it is ready */
    retval = usb_register_dev(interface, &lcd_class);
    if (retval) {
        /* something prevented us from registering this driver */
        err("Not able to get a minor for this device.");
        usb_set_intfdata(interface, NULL);
        goto error;
    }

    i = le16_to_cpu(dev->udev->descriptor.bcdDevice);

    info("USBLCD Version %1d%1d.%1d%1d found at address %d",
        (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF),
        dev->udev->devnum);

    /* let the user know what node this device is now attached to */
    info("USB LCD device now attached to USBLCD-%d", interface->minor);
    return 0;

error:
    if (dev)
        kref_put(&dev->kref, lcd_delete);
    return retval;
}
继承事业,薪火相传
返回列表