⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osrfx2.c~

📁 一个对cy7c68013芯片实现控制传输和批量传输的linux下的驱动
💻 C~
📖 第 1 页 / 共 2 页
字号:
    flags = (file->f_flags & O_ACCMODE);    if ((flags == O_WRONLY) || (flags == O_RDWR))        atomic_inc( &fx2dev->bulk_write_available );    if ((flags == O_RDONLY) || (flags == O_RDWR))         atomic_inc( &fx2dev->bulk_read_available );    /*      *  Decrement the ref-count on the device instance.     */    kref_put(&fx2dev->kref, osrfx2_delete);        return 0;}/*****************************************************************************//*                                                                           *//*****************************************************************************/static ssize_t osrfx2_read(struct file * file, char * buffer,                            size_t count, loff_t * ppos){    struct osrfx2 * fx2dev;    int retval = 0;    int bytes_read;    int pipe;    fx2dev = (struct osrfx2 *)file->private_data;    pipe = usb_rcvbulkpipe(fx2dev->udev, fx2dev->bulk_in_endpointAddr),    /*      *  Do a blocking bulk read to get data from the device      */    retval = usb_bulk_msg( fx2dev->udev,                            pipe,                           fx2dev->bulk_in_buffer,                           min(fx2dev->bulk_in_size, count),                           &bytes_read,                            10000 );    /*      *  If the read was successful, copy the data to userspace      */    if (!retval) {        if (copy_to_user(buffer, fx2dev->bulk_in_buffer, bytes_read)) {            retval = -EFAULT;        }        else {            retval = bytes_read;        }                /*         *  Increment the pending_data counter by the byte count received.         */        fx2dev->pending_data -= retval;    }    return retval;}/*****************************************************************************//*                                                                           *//*****************************************************************************/static void write_bulk_backend(struct urb * urb, struct pt_regs * regs){    struct osrfx2 * fx2dev = (struct osrfx2 *)urb->context;    /*      *  Filter sync and async unlink events as non-errors.     */    if (urb->status &&         !(urb->status == -ENOENT ||           urb->status == -ECONNRESET ||          urb->status == -ESHUTDOWN)) {        dev_err(&fx2dev->interface->dev,                 "%s - non-zero status received: %d\n",                __FUNCTION__, urb->status);    }    /*      *  Free the spent buffer.     */    usb_buffer_free( urb->dev,                      urb->transfer_buffer_length,                      urb->transfer_buffer,                      urb->transfer_dma );}/*****************************************************************************//*                                                                           *//*****************************************************************************/static ssize_t osrfx2_write(struct file * file, const char * user_buffer,                             size_t count, loff_t * ppos){    struct osrfx2 * fx2dev;    struct urb * urb = NULL;    char * buf = NULL;    int pipe;    int retval = 0;    fx2dev = (struct osrfx2 *)file->private_data;    if (count == 0)        return count;    /*      *  Create a urb, and a buffer for it, and copy the data to the urb.     */    urb = usb_alloc_urb(0, GFP_KERNEL);    if (!urb) {        retval = -ENOMEM;        goto error;    }    buf = usb_buffer_alloc( fx2dev->udev,                             count,                             GFP_KERNEL,                             &urb->transfer_dma );    if (!buf) {        retval = -ENOMEM;        goto error;    }    if (copy_from_user(buf, user_buffer, count)) {        retval = -EFAULT;        goto error;    }    /*      *  Initialize the urb properly.     */    pipe = usb_sndbulkpipe( fx2dev->udev, fx2dev->bulk_out_endpointAddr );    usb_fill_bulk_urb( urb,                        fx2dev->udev,                       pipe,                       buf,                        count,                        write_bulk_backend,                        fx2dev );    urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;    /*      *  Send the data out the bulk port     */    retval = usb_submit_urb(urb, GFP_KERNEL);    if (retval) {        dev_err(&fx2dev->interface->dev, "%s - usb_submit_urb failed: %d\n",                __FUNCTION__, retval);        goto error;    }    /*     *  Increment the pending_data counter by the byte count sent.     */    fx2dev->pending_data += count;    /*      *  Release the reference to this urb, the USB core     *  will eventually free it entirely.     */    usb_free_urb(urb);    return count;error:    usb_buffer_free(fx2dev->udev, count, buf, urb->transfer_dma);    usb_free_urb(urb);    return retval;}/*****************************************************************************//*                                                                           *//*****************************************************************************/static unsigned int osrfx2_poll(struct file * file, poll_table * wait){    struct osrfx2 * fx2dev = (struct osrfx2 *)file->private_data;    unsigned int mask = 0;    int retval = 0;    retval = down_interruptible( &fx2dev->sem );        poll_wait(file, &fx2dev->FieldEventQueue, wait);    if ( fx2dev->notify == TRUE ) {        fx2dev->notify = FALSE;        mask |= POLLPRI;    }    if ( fx2dev->pending_data > 0) {        mask |= POLLIN | POLLRDNORM;    }    up( &fx2dev->sem );        return mask;}/*****************************************************************************//* This fills-in the driver-supported file_operations fields.                *//*****************************************************************************/static struct file_operations osrfx2_file_ops = {    .owner   = THIS_MODULE,    .open    = osrfx2_open,    .release = osrfx2_release,    .read    = osrfx2_read,    .write   = osrfx2_write,    .poll    = osrfx2_poll,}; /*****************************************************************************//* Usb class driver info in order to get a minor number from the usb core,   *//* and to have the device registered with devfs and the driver core.         *//*****************************************************************************/static struct usb_class_driver osrfx2_class = {    .name       = "device/osrfx2_%d",    .fops       = &osrfx2_file_ops,    .minor_base = DEVICE_MINOR_BASE,#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)    .mode       = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,#endif};/*****************************************************************************//* Event: un-bound device instance is querying for suitable owner driver.    *//*****************************************************************************/static int osrfx2_probe(struct usb_interface * interface,                         const struct usb_device_id * id){    struct usb_device * udev = interface_to_usbdev(interface);    struct osrfx2 * fx2dev = NULL;    int retval;    fx2dev = kmalloc(sizeof(struct osrfx2), GFP_KERNEL);    if (fx2dev == NULL) {        retval = -ENOMEM;        goto error;    }    memset(fx2dev, 0, sizeof(*fx2dev));    kref_init( &fx2dev->kref );    fx2dev->udev = usb_get_dev(udev);    fx2dev->interface = interface;    fx2dev->suspended = FALSE;    fx2dev->bulk_write_available = (atomic_t) ATOMIC_INIT(1);    fx2dev->bulk_read_available  = (atomic_t) ATOMIC_INIT(1);    usb_set_intfdata(interface, fx2dev);    //device_create_file(&interface->dev, &dev_attr_switches);    device_create_file(&interface->dev, &dev_attr_start);    //device_create_file(&interface->dev, &dev_attr_7segment);    retval = find_endpoints( fx2dev );    if (retval != 0)         goto error;        /*retval = init_interrupts( fx2dev );    if (retval != 0)        goto error;*/    retval = init_bulks( fx2dev );    if (retval != 0)        goto error;    retval = usb_register_dev(interface, &osrfx2_class);    if (retval != 0) {        usb_set_intfdata(interface, NULL);    }    dev_info(&interface->dev, "OSR USB-FX2 device now attached.\n");    return 0;error:    dev_err(&interface->dev, "OSR USB-FX2 device probe failed: %d.\n", retval);    if (fx2dev) {        kref_put( &fx2dev->kref, osrfx2_delete );    }    return retval;}/*****************************************************************************//* Event: device instance is being disconnected (deleted)                    *//*****************************************************************************/static void osrfx2_disconnect(struct usb_interface * interface){    struct osrfx2 * fx2dev;    lock_kernel();    fx2dev = usb_get_intfdata(interface);    //usb_kill_urb(fx2dev->int_in_urb);        usb_set_intfdata(interface, NULL);    //device_remove_file(&interface->dev, &dev_attr_switches);    device_remove_file(&interface->dev, &dev_attr_start);    //device_remove_file(&interface->dev, &dev_attr_7segment);    usb_deregister_dev(interface, &osrfx2_class);    unlock_kernel();    kref_put( &fx2dev->kref, osrfx2_delete );    dev_info(&interface->dev, "OSR USB-FX2 now disconnected.\n");}#if 0/*****************************************************************************//* Event: device is being suspended.                                         *//*****************************************************************************/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)static int osrfx2_suspend(struct usb_interface * intf, pm_message_t message)#else static int osrfx2_suspend(struct usb_interface * intf, pm_message_t state)#endif{    struct osrfx2 * fx2dev = usb_get_intfdata(intf);    dev_info(&intf->dev, "%s - entry\n", __FUNCTION__);    if (down_interruptible(&fx2dev->sem)) {        return -ERESTARTSYS;    }    fx2dev->suspended = TRUE;    /*      *  Stop the interrupt pipe read urb.     */    //usb_kill_urb(fx2dev->int_in_urb);    up(&fx2dev->sem);    return 0;}#endif#if 0/*****************************************************************************//* Event: device is being resumed                                            *//*****************************************************************************/static int osrfx2_resume(struct usb_interface * intf){    int retval;    struct osrfx2 * fx2dev = usb_get_intfdata(intf);    dev_info(&intf->dev, "%s - entry\n", __FUNCTION__);    if (down_interruptible(&fx2dev->sem)) {        return -ERESTARTSYS;    }        fx2dev->suspended = FALSE;    /*      *  Re-start the interrupt pipe read urb.     */    //retval = usb_submit_urb( fx2dev->int_in_urb, GFP_KERNEL );		retval = 0;        if (retval) {        dev_err(&intf->dev, "%s - usb_submit_urb failed %d\n",                __FUNCTION__, retval);        switch (retval) {        case -EHOSTUNREACH:            dev_err(&intf->dev, "%s - EHOSTUNREACH probably cause: "                    "parent hub/port still suspended.\n",                     __FUNCTION__);            break;        default:            break;        }    }        up(&fx2dev->sem);    return 0;}#endif/*****************************************************************************//* This driver's usb_driver structure: ref-ed by osrfx2_init and osrfx2_exit *//*****************************************************************************/static struct usb_driver osrfx2_driver = {    .name        = "osrfx2",    .probe       = osrfx2_probe,    .disconnect  = osrfx2_disconnect,    //.suspend     = osrfx2_suspend,    //.resume      = osrfx2_resume,    .id_table    = id_table,#if 0 /* Fedora Core-5 seems to have a problem with .owner so just remove it */    .owner       = THIS_MODULE,#endif};/*****************************************************************************//* This driver's commission routine: just register with USB subsystem.       *//*****************************************************************************/static int __init osrfx2_init(void){    int retval;    retval = usb_register(&osrfx2_driver);    return retval;}/*****************************************************************************//* This driver's decommission routine: just deregister with USB subsystem.   *//*****************************************************************************/static void __exit osrfx2_exit(void){    usb_deregister( &osrfx2_driver );}/*****************************************************************************//* Advertise this driver's init and exit routines                            *//*****************************************************************************/module_init( osrfx2_init );module_exit( osrfx2_exit );MODULE_AUTHOR("Yunxiang Liu");MODULE_DESCRIPTION("A driver for the FCUSB-CY7C68013-128 board");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -