urbtc.c
Go to the documentation of this file.
00001 /*
00002  * USB H8 based motor controller driver 
00003  *
00004  * based on USB Skeleton driver.
00005  */
00006 /*
00007  * USB Skeleton driver - 2.0
00008  *
00009  * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
00010  *
00011  *      This program is free software; you can redistribute it and/or
00012  *      modify it under the terms of the GNU General Public License as
00013  *      published by the Free Software Foundation, version 2.
00014  *
00015  * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c 
00016  * but has been rewritten to be easy to read and use, as no locks are now
00017  * needed anymore.
00018  *
00019  */
00020 
00021 #define DEBUG
00022 
00023 //#include <linux/config.h>
00024 //#include <linux/autoconf.h>                   //chg t.miyo
00025 //#include "/usr/src/linux-headers-3.2.0-4-amd64/include/generated/autoconf.h"
00026 #include "/usr/src/linux-headers-3.13.0-34-generic/include/generated/autoconf.h"
00027 #include <linux/kernel.h>
00028 #include <linux/errno.h>
00029 #include <linux/init.h>
00030 #include <linux/slab.h>
00031 #include <linux/module.h>
00032 #include <linux/kref.h>
00033 #include <asm/uaccess.h>
00034 #include <linux/usb.h>
00035 
00036 #include "urbtc.h"
00037 #include "urobotc.h"
00038 
00039 static struct usb_device_id urbtc_table [] = {
00040         { USB_DEVICE(0x8da, 0xfc00) },  /* base version */
00041         { USB_DEVICE(0xff8, 0x001) },   /* iXs Reserch version */
00042         { }                                     /* Terminating entry */
00043 };
00044 MODULE_DEVICE_TABLE (usb, urbtc_table);
00045 
00046 #define USB_URBTC_MINOR_BASE    100
00047 
00048 /* our private defines. if this grows any larger, use your own .h file */
00049 #define MAX_TRANSFER            (PAGE_SIZE - 512)
00050 #define WRITES_IN_FLIGHT        8
00051 
00052 #define EP_READREQ      1
00053 #define EP_SCMD         2
00054 #define EP_READ         5
00055 #define EP_CCMD         6
00056 
00057 /* Structure to hold all of our device specific stuff */
00058 struct usb_urbtc {
00059         struct usb_device *udev;
00060         struct usb_interface *interface;
00061         struct semaphore limit_sem;
00062 
00063         int read_status;
00064         unsigned char *readreq_buffer;
00065         size_t readreq_size;
00066 
00067         int readbuf_enabled;
00068         wait_queue_head_t readbuf_wait;
00069         struct urb *readbuf_urb;
00070         struct uin *readbuf_work;
00071         struct semaphore readbuf_sem;
00072         struct uin *readbuf_buffered;
00073         size_t readbuf_size;
00074         unsigned short readbuf_last_buffered; /* same to uin.time */
00075         unsigned short readbuf_last_read; /* same to uin.time */
00076 
00077         int write_status;
00078         unsigned char *write_counter_buffer;
00079         size_t write_counter_size;
00080 
00081         struct kref             kref;
00082 };
00083 #define to_urbtc_dev(d) container_of(d, struct usb_urbtc, kref)
00084 
00085 static struct usb_driver urbtc_driver;
00086 
00087 static void urbtc_delete(struct kref *kref)
00088 {       
00089         struct usb_urbtc *dev = to_urbtc_dev(kref);
00090 
00091         usb_put_dev(dev->udev);
00092         kfree (dev->readreq_buffer);
00093         usb_free_urb(dev->readbuf_urb);
00094         kfree (dev->readbuf_work);
00095         kfree (dev->readbuf_buffered);
00096         kfree (dev);
00097 }
00098 
00099 static int urbtc_open(struct inode *inode, struct file *file)
00100 {
00101         struct usb_urbtc *dev;
00102         struct usb_interface *interface;
00103         int subminor;
00104         int retval = 0;
00105 
00106         subminor = iminor(inode);
00107 
00108         interface = usb_find_interface(&urbtc_driver, subminor);
00109         if (!interface) {
00110                 /* err ("%s - error, can't find device for minor %d", */
00111                 /*      __FUNCTION__, subminor); */
00112                 retval = -ENODEV;
00113                 goto exit;
00114         }
00115 
00116         dev = usb_get_intfdata(interface);
00117         if (!dev) {
00118                 retval = -ENODEV;
00119                 goto exit;
00120         }
00121 
00122         dev->read_status = URBTC_STATUS_READ_REQUEST;
00123         dev->readbuf_enabled = 0;
00124         dev->write_status = URBTC_STATUS_WRITE_DESIRE;
00125 
00126         /* increment our usage count for the device */
00127         kref_get(&dev->kref);
00128 
00129         /* save our object in the file's private structure */
00130         file->private_data = dev;
00131 
00132 exit:
00133         return retval;
00134 }
00135 
00136 static int urbtc_release(struct inode *inode, struct file *file)
00137 {
00138         struct usb_urbtc *dev = (struct usb_urbtc *)file->private_data;
00139 
00140         if (dev == NULL)
00141                 return -ENODEV;
00142 
00143         if (dev->interface) {
00144                 if (dev->readbuf_enabled)
00145                         usb_kill_urb(dev->readbuf_urb);
00146         }
00147                 
00148         /* decrement the count on our device */
00149         kref_put(&dev->kref, urbtc_delete);
00150         return 0;
00151 }
00152 
00153 //static void urbtc_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
00154 static void urbtc_read_bulk_callback(struct urb *urb)                   //chg t.miyo
00155 {
00156         struct usb_urbtc *dev = (struct usb_urbtc *)urb->context;
00157         int res;
00158 
00159         /* sync/async unlink faults aren't errors */
00160         if (urb->status && 
00161             !(urb->status == -ENOENT || 
00162               urb->status == -ECONNRESET ||
00163               urb->status == -ESHUTDOWN)) {
00164                 /* dbg("%s - nonzero read bulk status received: %d", */
00165                 /*     __FUNCTION__, urb->status); */
00166                 dev->readbuf_enabled = 0;
00167                 return;
00168         }
00169         if (urb->actual_length > 0) {
00170                 if (down_trylock(&dev->readbuf_sem) == 0) {
00171                         memcpy(dev->readbuf_buffered, dev->readbuf_work, urb->actual_length);
00172                         dev->readbuf_last_buffered = dev->readbuf_work->time;
00173                         up(&dev->readbuf_sem);
00174                         wake_up(&dev->readbuf_wait);
00175                 }
00176         }
00177         if (dev->readbuf_enabled) {
00178                 usb_fill_bulk_urb(dev->readbuf_urb, dev->udev,
00179                                   usb_rcvbulkpipe(dev->udev, EP_READ),
00180                                   dev->readbuf_urb->transfer_buffer,
00181                                   dev->readbuf_urb->transfer_buffer_length,
00182                                   urbtc_read_bulk_callback, dev);
00183                 if ((res = usb_submit_urb(dev->readbuf_urb, GFP_ATOMIC))) {
00184                         dev->readbuf_enabled = 0;
00185                 }
00186         }
00187 }
00188 
00189 static ssize_t urbtc_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
00190 {
00191         struct usb_urbtc *dev = (struct usb_urbtc *)file->private_data;
00192         int retval = 0;
00193         int bytes_read;
00194         
00195         if (count != sizeof(struct uin))
00196                 return -EINVAL;
00197 
00198         switch (dev->read_status) {
00199         case URBTC_STATUS_READ_REQUEST:
00200                 /* do a blocking bulk read to get data from the device */
00201                 retval = usb_bulk_msg(dev->udev,
00202                                       usb_rcvbulkpipe(dev->udev, EP_READREQ),
00203                                       dev->readreq_buffer,
00204                                       min(dev->readreq_size, count),
00205                                       &bytes_read, 10000);
00206 
00207                 /* if the read was successful, copy the data to userspace */
00208                 if (!retval) {
00209                         if (copy_to_user(buffer, dev->readreq_buffer, bytes_read))
00210                                 retval = -EFAULT;
00211                         else
00212                                 retval = bytes_read;
00213                 }
00214                 break;
00215         case URBTC_STATUS_READ_CONTINUOUS:
00216                 if (dev->readbuf_enabled) {
00217                         wait_event_interruptible(dev->readbuf_wait,
00218                                                  dev->readbuf_last_read != dev->readbuf_last_buffered || !dev->udev);
00219                         if (signal_pending(current)) {
00220                                 retval = -EINTR;
00221                                 goto out;
00222                         }
00223                         if (!dev->udev) {
00224                                 retval = -ENODEV;
00225                                 goto out;
00226                         }
00227                         dev->readbuf_last_read = dev->readbuf_last_buffered;
00228                         down(&dev->readbuf_sem);
00229                         if (copy_to_user(buffer, dev->readbuf_buffered, dev->readbuf_size))
00230                                 retval = -EFAULT;
00231                         else
00232                                 retval = dev->readbuf_size;
00233                         up(&dev->readbuf_sem);
00234                 } else {
00235                         /* do a blocking bulk read to get data from the device */
00236                         down(&dev->readbuf_sem);
00237                         retval = usb_bulk_msg(dev->udev,
00238                                               usb_rcvbulkpipe(dev->udev, EP_READ),
00239                                               dev->readbuf_buffered,
00240                                               min(dev->readbuf_size, count),
00241                                               &bytes_read, 10000);
00242 
00243                         /* if the read was successful, copy the data to userspace */
00244                         if (!retval) {
00245                                 if (copy_to_user(buffer, dev->readbuf_buffered, bytes_read))
00246                                         retval = -EFAULT;
00247                                 else
00248                                         retval = bytes_read;
00249                         }
00250                         up(&dev->readbuf_sem);
00251                 }
00252                 break;
00253         default:
00254                 /* should not occur */
00255                 retval = -EINVAL;
00256                 break;
00257         }
00258 out:
00259         return retval;
00260 }
00261 
00262 //static void urbtc_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
00263 static void urbtc_write_bulk_callback(struct urb *urb)                  //chg t.miyo
00264 {
00265         struct usb_urbtc *dev = (struct usb_urbtc *)urb->context;
00266 
00267         /* sync/async unlink faults aren't errors */
00268         if (urb->status && 
00269             !(urb->status == -ENOENT || 
00270               urb->status == -ECONNRESET ||
00271               urb->status == -ESHUTDOWN)) {
00272                 /* dbg("%s - nonzero write bulk status received: %d", */
00273                 /*     __FUNCTION__, urb->status); */
00274         }
00275 
00276         /* free up our allocated buffer */
00277         /*usb_buffer_free(urb->dev, urb->transfer_buffer_length, 
00278                         urb->transfer_buffer, urb->transfer_dma);*/
00279         usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma);                      //chg t.miyo
00280         up(&dev->limit_sem);
00281 }
00282 
00283 static ssize_t urbtc_write_sync(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
00284 {
00285         struct usb_urbtc *dev = (struct usb_urbtc *)file->private_data;
00286         int retval = 0;
00287         size_t writesize = min(count, dev->write_counter_size);
00288         int bytes_written;
00289 
00290         if (copy_from_user(dev->write_counter_buffer, user_buffer, writesize)) {
00291                 retval = -EFAULT;
00292                 goto error;
00293         }
00294 
00295         /* do a blocking bulk write to the device */
00296         retval = usb_bulk_msg(dev->udev,
00297                               usb_sndbulkpipe(dev->udev, EP_CCMD),
00298                               dev->write_counter_buffer,
00299                               writesize,
00300                               &bytes_written, 10000);
00301 
00302         if (!retval)
00303                 retval = bytes_written;
00304 
00305 error:
00306         return retval;
00307 }
00308 
00309 static ssize_t urbtc_write_async(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
00310 {
00311         struct usb_urbtc *dev = (struct usb_urbtc *)file->private_data;
00312         int retval = 0;
00313         struct urb *urb = NULL;
00314         char *buf = NULL;
00315         size_t writesize = min(count, (size_t)MAX_TRANSFER);
00316 
00317         /* limit the number of URBs in flight to stop a user from using up all RAM */
00318         if (down_interruptible(&dev->limit_sem)) {
00319                 retval = -ERESTARTSYS;
00320                 goto exit;
00321         }
00322 
00323         /* create a urb, and a buffer for it, and copy the data to the urb */
00324         urb = usb_alloc_urb(0, GFP_KERNEL);
00325         if (!urb) {
00326                 retval = -ENOMEM;
00327                 goto error;
00328         }
00329 
00330         //buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
00331         buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
00332         if (!buf) {
00333                 retval = -ENOMEM;
00334                 goto error;
00335         }
00336 
00337         if (copy_from_user(buf, user_buffer, writesize)) {
00338                 retval = -EFAULT;
00339                 goto error;
00340         }
00341 
00342         /* initialize the urb properly */
00343         usb_fill_bulk_urb(urb, dev->udev,
00344                           usb_sndbulkpipe(dev->udev, EP_SCMD),
00345                           buf, writesize, urbtc_write_bulk_callback, dev);
00346         urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
00347 
00348         /* send the data out the bulk port */
00349         retval = usb_submit_urb(urb, GFP_KERNEL);
00350         if (retval) {
00351                 /* err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); */
00352                 goto error;
00353         }
00354 
00355         /* release our reference to this urb, the USB core will eventually free it entirely */
00356         usb_free_urb(urb);
00357 
00358 exit:
00359         return writesize;
00360 
00361 error:
00362         //usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
00363         usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);                        //chg t.miyo
00364         usb_free_urb(urb);
00365         up(&dev->limit_sem);
00366         return retval;
00367 }
00368 
00369 static ssize_t urbtc_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
00370 {
00371         struct usb_urbtc *dev = (struct usb_urbtc *)file->private_data;
00372 
00373         /* verify that we actually have some data to write */
00374         if (count == 0)
00375                 return 0;
00376 
00377         switch (dev->write_status) {
00378         case URBTC_STATUS_WRITE_COUNTER:
00379                 return urbtc_write_sync(file, user_buffer, count, ppos);
00380         case URBTC_STATUS_WRITE_DESIRE:
00381                 return urbtc_write_async(file, user_buffer, count, ppos);
00382         default:
00383                 /* should not occur */
00384                 return -EINVAL;
00385         }
00386 }
00387 
00388 /*static int
00389 urbtc_ioctl(struct inode *inode, struct file *file,
00390             unsigned int cmd, unsigned long arg)*/
00391 static long
00392 urbtc_ioctl(struct file *file,
00393             unsigned int cmd, unsigned long arg)                        //chg t.miyo
00394 {
00395         struct usb_urbtc *dev = (struct usb_urbtc *)file->private_data;
00396         struct usb_device *udev = dev->udev;
00397         int retval = 0;
00398 
00399         switch(cmd) {
00400         case URBTC_GET_VENDOR:
00401                 if(copy_to_user((int*)arg, &udev->descriptor.idVendor, sizeof(int)))
00402                         return -EFAULT;
00403                 break;
00404         case URBTC_GET_PRODUCT:
00405                 if(copy_to_user((int*)arg, &udev->descriptor.idProduct, sizeof(int)))
00406                         return -EFAULT;
00407                 break;
00408         case URBTC_REQUEST_READ:
00409                 dev->read_status = URBTC_STATUS_READ_REQUEST;
00410                 break;
00411         case URBTC_CONTINUOUS_READ:
00412                 dev->read_status = URBTC_STATUS_READ_CONTINUOUS;
00413                 break;
00414         case URBTC_BUFREAD:
00415                 if (dev->read_status != URBTC_STATUS_READ_CONTINUOUS)
00416                         return -EINVAL;
00417                 if (!dev->readbuf_enabled) {
00418                         usb_fill_bulk_urb(dev->readbuf_urb, dev->udev,
00419                                           usb_rcvbulkpipe(dev->udev, EP_READ),
00420                                           dev->readbuf_urb->transfer_buffer,
00421                                           dev->readbuf_urb->transfer_buffer_length,
00422                                           urbtc_read_bulk_callback, dev);
00423                         if (!(retval = usb_submit_urb(dev->readbuf_urb, GFP_KERNEL)))
00424                                 dev->readbuf_enabled = 1;
00425                 }
00426                 break;
00427         case URBTC_WAITREAD:
00428                 dev->readbuf_enabled = 0;
00429                 break;
00430         case URBTC_GET_READ_STATUS:
00431                 if (copy_to_user((int*)arg, &dev->read_status, sizeof(int)))
00432                         return -EFAULT;
00433                 break;
00434 
00435         case URBTC_COUNTER_SET:
00436                 dev->write_status = URBTC_STATUS_WRITE_COUNTER;
00437                 break;
00438         case URBTC_DESIRE_SET:
00439                 dev->write_status = URBTC_STATUS_WRITE_DESIRE;
00440                 break;
00441         case URBTC_GET_WRITE_STATUS:
00442                 if (copy_to_user((int*)arg, &dev->write_status, sizeof(int)))
00443                         return -EFAULT;
00444                 break;
00445         default:
00446                 return -ENOIOCTLCMD;
00447         }
00448 
00449         return retval;
00450 }
00451 
00452 static struct file_operations urbtc_fops = {
00453         .owner =        THIS_MODULE,
00454         .read =         urbtc_read,
00455         .write =        urbtc_write,
00456         //.ioctl =      urbtc_ioctl,
00457         .unlocked_ioctl =       urbtc_ioctl,            //chg t.miyo
00458         .open =         urbtc_open,
00459         .release =      urbtc_release,
00460 };
00461 
00462 /* 
00463  * usb class driver info in order to get a minor number from the usb core,
00464  * and to have the device registered with the driver core
00465  */
00466 static struct usb_class_driver urbtc_class = {
00467         .name =         "urbtc%d",
00468         .fops =         &urbtc_fops,
00469         .minor_base =   USB_URBTC_MINOR_BASE,
00470 };
00471 
00472 static int urbtc_probe(struct usb_interface *interface, const struct usb_device_id *id)
00473 {
00474         struct usb_urbtc *dev = NULL;
00475         struct usb_host_interface *iface_desc;
00476         struct usb_endpoint_descriptor *endpoint;
00477         size_t buffer_size;
00478         int i;
00479         int retval = -ENOMEM;
00480 
00481         /* allocate memory for our device state and initialize it */
00482         dev = kmalloc(sizeof(*dev), GFP_KERNEL);
00483         if (dev == NULL) {
00484                 /* err("Out of memory"); */
00485                 goto error;
00486         }
00487         memset(dev, 0, sizeof(*dev));
00488         kref_init(&dev->kref);
00489         sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
00490         //init_MUTEX(&dev->readbuf_sem);
00491         sema_init(&dev->readbuf_sem,1);                 //chg t.miyo
00492         init_waitqueue_head(&dev->readbuf_wait);
00493 
00494         dev->udev = usb_get_dev(interface_to_usbdev(interface));
00495         dev->interface = interface;
00496 
00497         dev->readreq_buffer = NULL;
00498         dev->readbuf_urb = NULL;
00499         dev->readbuf_work = NULL;
00500         dev->readbuf_buffered = NULL;
00501         dev->readbuf_last_read = 0;
00502         dev->readbuf_last_buffered = 0;
00503 
00504         iface_desc = interface->cur_altsetting;
00505         for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
00506                 endpoint = &iface_desc->endpoint[i].desc;
00507 
00508                 /* dbg("endpoint %d(%d) %s", */
00509                 /*     endpoint->bEndpointAddress, */
00510                 /*     endpoint->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK, */
00511                 /*     endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK? "in": "out"); */
00512                 if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
00513                      == USB_DIR_IN) &&
00514                     ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
00515                      == USB_ENDPOINT_XFER_BULK)) {
00516                         switch (endpoint->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK) {
00517                         case EP_READREQ:
00518                                 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
00519                                 dev->readreq_size = buffer_size;
00520                                 dev->readreq_buffer = kmalloc(buffer_size, GFP_KERNEL);
00521                                 if (!dev->readreq_buffer) {
00522                                         /* err("Could not allocate readreq_buffer"); */
00523                                         goto error;
00524                                 }
00525                                 break;
00526                         case EP_READ:
00527                                 buffer_size = sizeof(struct uin);
00528                                 dev->readbuf_urb = usb_alloc_urb(0, GFP_KERNEL);
00529                                 if (!dev->readbuf_urb) {
00530                                         /* err("Could not allocate readbuf_urb"); */
00531                                         goto error;
00532                                 }
00533                                 dev->readbuf_size = buffer_size;
00534                                 dev->readbuf_work = kmalloc(buffer_size, GFP_KERNEL);
00535                                 if (!dev->readbuf_work) {
00536                                         /* err("Could not allocate readbuf_work"); */
00537                                         goto error;
00538                                 }
00539                                 dev->readbuf_buffered = kmalloc(buffer_size, GFP_KERNEL);
00540                                 if (!dev->readbuf_buffered) {
00541                                         /* err("Could not allocate readbuf_buffer"); */
00542                                         goto error;
00543                                 }
00544                                 usb_fill_bulk_urb(dev->readbuf_urb, dev->udev,
00545                                                   usb_rcvbulkpipe(dev->udev, endpoint->bEndpointAddress),
00546                                                   dev->readbuf_work, dev->readbuf_size,
00547                                                   urbtc_read_bulk_callback, dev);
00548                                 break;
00549                         default:
00550                                 break;
00551                         }
00552                 }
00553 
00554                 if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
00555                      == USB_DIR_OUT) &&
00556                     ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
00557                      == USB_ENDPOINT_XFER_BULK)) {
00558                         switch (endpoint->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK) {
00559                         case EP_CCMD:
00560                                 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
00561                                 dev->write_counter_size = buffer_size;
00562                                 dev->write_counter_buffer = kmalloc(buffer_size, GFP_KERNEL);
00563                                 if (!dev->write_counter_buffer) {
00564                                         /* err("Could not allocate write_counter_buffer"); */
00565                                         goto error;
00566                                 }
00567                                 break;
00568                         case EP_SCMD:
00569                         default:
00570                                 break;
00571                         }
00572                 }
00573         }
00574 
00575         /* save our data pointer in this interface device */
00576         usb_set_intfdata(interface, dev);
00577 
00578         /* we can register the device now, as it is ready */
00579         retval = usb_register_dev(interface, &urbtc_class);
00580         if (retval) {
00581                 /* something prevented us from registering this driver */
00582                 /* err("Not able to get a minor for this device."); */
00583                 usb_set_intfdata(interface, NULL);
00584                 goto error;
00585         }
00586 
00587         /* let the user know what node this device is now attached to */
00588         //info("USB Robot device now attached to urbtc - %d", interface->minor);
00589         //chg t.miyo
00590         dev_info(&interface->dev,"USB Robot device now attached to urbtc - %d", interface->minor);
00591         return 0;
00592 
00593 error:
00594         if (dev) {
00595                 if (dev->readreq_buffer)
00596                         kfree(dev->readreq_buffer);
00597                 if (dev->readbuf_urb)
00598                         usb_free_urb(dev->readbuf_urb);
00599                 if (dev->readbuf_work)
00600                         kfree(dev->readbuf_work);
00601                 if (dev->readbuf_buffered)
00602                         kfree(dev->readbuf_buffered);
00603                 kref_put(&dev->kref, urbtc_delete);
00604         }
00605         return retval;
00606 }
00607 
00608 static void urbtc_disconnect(struct usb_interface *interface)
00609 {
00610         struct usb_urbtc *dev;
00611         int minor = interface->minor;
00612 
00613         /* prevent urbtc_open() from racing urbtc_disconnect() */
00614         //lock_kernel();                //debug t.miyo
00615 
00616         dev = usb_get_intfdata(interface);
00617         usb_set_intfdata(interface, NULL);
00618 
00619         /* give back our minor */
00620         usb_deregister_dev(interface, &urbtc_class);
00621 
00622         //unlock_kernel();              //debug t.miyo
00623 
00624         /* decrement our usage count */
00625         kref_put(&dev->kref, urbtc_delete);
00626         wake_up(&dev->readbuf_wait);
00627 
00628         //info("USB Robot #%d now disconnected", minor);
00629         //chg t.miyo
00630         dev_info(&interface->dev,"USB Robot #%d now disconnected", minor);
00631 }
00632 
00633 static struct usb_driver urbtc_driver = {
00634         .name =         "urbtc",
00635         .probe =        urbtc_probe,
00636         .disconnect =   urbtc_disconnect,
00637         .id_table =     urbtc_table,
00638 };
00639 
00640 static int __init usb_urbtc_init(void)
00641 {
00642         int result;
00643 
00644         /* register this driver with the USB subsystem */
00645         result = usb_register(&urbtc_driver);
00646         if (result){}
00647                 /* err("usb_register failed. Error number %d", result); */
00648 
00649         return result;
00650 }
00651 
00652 static void __exit usb_urbtc_exit(void)
00653 {
00654         /* deregister this driver with the USB subsystem */
00655         usb_deregister(&urbtc_driver);
00656 }
00657 
00658 module_init (usb_urbtc_init);
00659 module_exit (usb_urbtc_exit);
00660 
00661 MODULE_LICENSE("GPL");
00662 /*
00663   Local Variables:
00664   c-file-style: "linux"
00665   End:
00666 */


cirkit_unit03_driver
Author(s): CIR-KIT
autogenerated on Thu Jun 6 2019 21:08:20