00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define DEBUG
00022
00023
00024
00025
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) },
00041 { USB_DEVICE(0xff8, 0x001) },
00042 { }
00043 };
00044 MODULE_DEVICE_TABLE (usb, urbtc_table);
00045
00046 #define USB_URBTC_MINOR_BASE 100
00047
00048
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
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;
00075 unsigned short readbuf_last_read;
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
00111
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
00127 kref_get(&dev->kref);
00128
00129
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
00149 kref_put(&dev->kref, urbtc_delete);
00150 return 0;
00151 }
00152
00153
00154 static void urbtc_read_bulk_callback(struct urb *urb)
00155 {
00156 struct usb_urbtc *dev = (struct usb_urbtc *)urb->context;
00157 int res;
00158
00159
00160 if (urb->status &&
00161 !(urb->status == -ENOENT ||
00162 urb->status == -ECONNRESET ||
00163 urb->status == -ESHUTDOWN)) {
00164
00165
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
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
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
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
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
00255 retval = -EINVAL;
00256 break;
00257 }
00258 out:
00259 return retval;
00260 }
00261
00262
00263 static void urbtc_write_bulk_callback(struct urb *urb)
00264 {
00265 struct usb_urbtc *dev = (struct usb_urbtc *)urb->context;
00266
00267
00268 if (urb->status &&
00269 !(urb->status == -ENOENT ||
00270 urb->status == -ECONNRESET ||
00271 urb->status == -ESHUTDOWN)) {
00272
00273
00274 }
00275
00276
00277
00278
00279 usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma);
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
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
00318 if (down_interruptible(&dev->limit_sem)) {
00319 retval = -ERESTARTSYS;
00320 goto exit;
00321 }
00322
00323
00324 urb = usb_alloc_urb(0, GFP_KERNEL);
00325 if (!urb) {
00326 retval = -ENOMEM;
00327 goto error;
00328 }
00329
00330
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
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
00349 retval = usb_submit_urb(urb, GFP_KERNEL);
00350 if (retval) {
00351
00352 goto error;
00353 }
00354
00355
00356 usb_free_urb(urb);
00357
00358 exit:
00359 return writesize;
00360
00361 error:
00362
00363 usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
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
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
00384 return -EINVAL;
00385 }
00386 }
00387
00388
00389
00390
00391 static long
00392 urbtc_ioctl(struct file *file,
00393 unsigned int cmd, unsigned long arg)
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
00457 .unlocked_ioctl = urbtc_ioctl,
00458 .open = urbtc_open,
00459 .release = urbtc_release,
00460 };
00461
00462
00463
00464
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
00482 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
00483 if (dev == NULL) {
00484
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
00491 sema_init(&dev->readbuf_sem,1);
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
00509
00510
00511
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
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
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
00537 goto error;
00538 }
00539 dev->readbuf_buffered = kmalloc(buffer_size, GFP_KERNEL);
00540 if (!dev->readbuf_buffered) {
00541
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
00565 goto error;
00566 }
00567 break;
00568 case EP_SCMD:
00569 default:
00570 break;
00571 }
00572 }
00573 }
00574
00575
00576 usb_set_intfdata(interface, dev);
00577
00578
00579 retval = usb_register_dev(interface, &urbtc_class);
00580 if (retval) {
00581
00582
00583 usb_set_intfdata(interface, NULL);
00584 goto error;
00585 }
00586
00587
00588
00589
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
00614
00615
00616 dev = usb_get_intfdata(interface);
00617 usb_set_intfdata(interface, NULL);
00618
00619
00620 usb_deregister_dev(interface, &urbtc_class);
00621
00622
00623
00624
00625 kref_put(&dev->kref, urbtc_delete);
00626 wake_up(&dev->readbuf_wait);
00627
00628
00629
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
00645 result = usb_register(&urbtc_driver);
00646 if (result){}
00647
00648
00649 return result;
00650 }
00651
00652 static void __exit usb_urbtc_exit(void)
00653 {
00654
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
00664
00665
00666