0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/module.h>
0019 #include <linux/usb.h>
0020 #include <linux/slab.h>
0021 #include <linux/sched.h>
0022 #include <linux/mutex.h>
0023 #include <linux/poll.h>
0024 #include <linux/usb/iowarrior.h>
0025
0026 #define DRIVER_AUTHOR "Christian Lucht <lucht@codemercs.com>"
0027 #define DRIVER_DESC "USB IO-Warrior driver"
0028
0029 #define USB_VENDOR_ID_CODEMERCS 1984
0030
0031 #define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500
0032 #define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501
0033 #define USB_DEVICE_ID_CODEMERCS_IOWPV1 0x1511
0034 #define USB_DEVICE_ID_CODEMERCS_IOWPV2 0x1512
0035
0036 #define USB_DEVICE_ID_CODEMERCS_IOW56 0x1503
0037
0038 #define USB_DEVICE_ID_CODEMERCS_IOW28 0x1504
0039 #define USB_DEVICE_ID_CODEMERCS_IOW28L 0x1505
0040 #define USB_DEVICE_ID_CODEMERCS_IOW100 0x1506
0041
0042
0043 #define USB_DEVICE_ID_CODEMERCS_IOW24SAG 0x158a
0044 #define USB_DEVICE_ID_CODEMERCS_IOW56AM 0x158b
0045
0046
0047 #ifdef CONFIG_USB_DYNAMIC_MINORS
0048 #define IOWARRIOR_MINOR_BASE 0
0049 #else
0050 #define IOWARRIOR_MINOR_BASE 208
0051 #endif
0052
0053
0054 #define MAX_INTERRUPT_BUFFER 16
0055
0056
0057
0058
0059
0060 #define MAX_WRITES_IN_FLIGHT 4
0061
0062 MODULE_AUTHOR(DRIVER_AUTHOR);
0063 MODULE_DESCRIPTION(DRIVER_DESC);
0064 MODULE_LICENSE("GPL");
0065
0066 static struct usb_driver iowarrior_driver;
0067
0068
0069
0070
0071
0072
0073 struct iowarrior {
0074 struct mutex mutex;
0075 struct usb_device *udev;
0076 struct usb_interface *interface;
0077 unsigned char minor;
0078 struct usb_endpoint_descriptor *int_out_endpoint;
0079 struct usb_endpoint_descriptor *int_in_endpoint;
0080 struct urb *int_in_urb;
0081 unsigned char *int_in_buffer;
0082 unsigned char serial_number;
0083 unsigned char *read_queue;
0084 wait_queue_head_t read_wait;
0085 wait_queue_head_t write_wait;
0086 atomic_t write_busy;
0087 atomic_t read_idx;
0088 atomic_t intr_idx;
0089 atomic_t overflow_flag;
0090 int present;
0091 int opened;
0092 char chip_serial[9];
0093 int report_size;
0094 u16 product_id;
0095 struct usb_anchor submitted;
0096 };
0097
0098
0099
0100
0101
0102 #define USB_REQ_GET_REPORT 0x01
0103
0104 static int usb_get_report(struct usb_device *dev,
0105 struct usb_host_interface *inter, unsigned char type,
0106 unsigned char id, void *buf, int size)
0107 {
0108 return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0109 USB_REQ_GET_REPORT,
0110 USB_DIR_IN | USB_TYPE_CLASS |
0111 USB_RECIP_INTERFACE, (type << 8) + id,
0112 inter->desc.bInterfaceNumber, buf, size,
0113 USB_CTRL_GET_TIMEOUT);
0114 }
0115
0116
0117 #define USB_REQ_SET_REPORT 0x09
0118
0119 static int usb_set_report(struct usb_interface *intf, unsigned char type,
0120 unsigned char id, void *buf, int size)
0121 {
0122 return usb_control_msg(interface_to_usbdev(intf),
0123 usb_sndctrlpipe(interface_to_usbdev(intf), 0),
0124 USB_REQ_SET_REPORT,
0125 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0126 (type << 8) + id,
0127 intf->cur_altsetting->desc.bInterfaceNumber, buf,
0128 size, 1000);
0129 }
0130
0131
0132
0133
0134
0135 static const struct usb_device_id iowarrior_ids[] = {
0136 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)},
0137 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)},
0138 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)},
0139 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV2)},
0140 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56)},
0141 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24SAG)},
0142 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56AM)},
0143 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28)},
0144 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28L)},
0145 {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW100)},
0146 {}
0147 };
0148 MODULE_DEVICE_TABLE(usb, iowarrior_ids);
0149
0150
0151
0152
0153 static void iowarrior_callback(struct urb *urb)
0154 {
0155 struct iowarrior *dev = urb->context;
0156 int intr_idx;
0157 int read_idx;
0158 int aux_idx;
0159 int offset;
0160 int status = urb->status;
0161 int retval;
0162
0163 switch (status) {
0164 case 0:
0165
0166 break;
0167 case -ECONNRESET:
0168 case -ENOENT:
0169 case -ESHUTDOWN:
0170 return;
0171 default:
0172 goto exit;
0173 }
0174
0175 intr_idx = atomic_read(&dev->intr_idx);
0176
0177 aux_idx = (intr_idx == 0) ? (MAX_INTERRUPT_BUFFER - 1) : (intr_idx - 1);
0178 read_idx = atomic_read(&dev->read_idx);
0179
0180
0181 if ((intr_idx != read_idx)
0182 && (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0)) {
0183
0184 offset = aux_idx * (dev->report_size + 1);
0185 if (!memcmp
0186 (dev->read_queue + offset, urb->transfer_buffer,
0187 dev->report_size)) {
0188
0189 goto exit;
0190 }
0191 }
0192
0193
0194 aux_idx = (intr_idx == (MAX_INTERRUPT_BUFFER - 1)) ? 0 : (intr_idx + 1);
0195 if (read_idx == aux_idx) {
0196
0197 read_idx = (++read_idx == MAX_INTERRUPT_BUFFER) ? 0 : read_idx;
0198 atomic_set(&dev->read_idx, read_idx);
0199 atomic_set(&dev->overflow_flag, 1);
0200 }
0201
0202
0203 offset = intr_idx * (dev->report_size + 1);
0204 memcpy(dev->read_queue + offset, urb->transfer_buffer,
0205 dev->report_size);
0206 *(dev->read_queue + offset + (dev->report_size)) = dev->serial_number++;
0207
0208 atomic_set(&dev->intr_idx, aux_idx);
0209
0210 wake_up_interruptible(&dev->read_wait);
0211
0212 exit:
0213 retval = usb_submit_urb(urb, GFP_ATOMIC);
0214 if (retval)
0215 dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
0216 __func__, retval);
0217
0218 }
0219
0220
0221
0222
0223 static void iowarrior_write_callback(struct urb *urb)
0224 {
0225 struct iowarrior *dev;
0226 int status = urb->status;
0227
0228 dev = urb->context;
0229
0230 if (status &&
0231 !(status == -ENOENT ||
0232 status == -ECONNRESET || status == -ESHUTDOWN)) {
0233 dev_dbg(&dev->interface->dev,
0234 "nonzero write bulk status received: %d\n", status);
0235 }
0236
0237 usb_free_coherent(urb->dev, urb->transfer_buffer_length,
0238 urb->transfer_buffer, urb->transfer_dma);
0239
0240 atomic_dec(&dev->write_busy);
0241 wake_up_interruptible(&dev->write_wait);
0242 }
0243
0244
0245
0246
0247 static inline void iowarrior_delete(struct iowarrior *dev)
0248 {
0249 dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor);
0250 kfree(dev->int_in_buffer);
0251 usb_free_urb(dev->int_in_urb);
0252 kfree(dev->read_queue);
0253 usb_put_intf(dev->interface);
0254 kfree(dev);
0255 }
0256
0257
0258
0259
0260
0261 static int read_index(struct iowarrior *dev)
0262 {
0263 int intr_idx, read_idx;
0264
0265 read_idx = atomic_read(&dev->read_idx);
0266 intr_idx = atomic_read(&dev->intr_idx);
0267
0268 return (read_idx == intr_idx ? -1 : read_idx);
0269 }
0270
0271
0272
0273
0274 static ssize_t iowarrior_read(struct file *file, char __user *buffer,
0275 size_t count, loff_t *ppos)
0276 {
0277 struct iowarrior *dev;
0278 int read_idx;
0279 int offset;
0280
0281 dev = file->private_data;
0282
0283
0284 if (!dev || !dev->present)
0285 return -ENODEV;
0286
0287 dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
0288 dev->minor, count);
0289
0290
0291 if ((count != dev->report_size)
0292 && (count != (dev->report_size + 1)))
0293 return -EINVAL;
0294
0295
0296 do {
0297 atomic_set(&dev->overflow_flag, 0);
0298 if ((read_idx = read_index(dev)) == -1) {
0299
0300 if (file->f_flags & O_NONBLOCK)
0301 return -EAGAIN;
0302 else {
0303
0304 int r = wait_event_interruptible(dev->read_wait,
0305 (!dev->present
0306 || (read_idx =
0307 read_index
0308 (dev)) !=
0309 -1));
0310 if (r) {
0311
0312 return -ERESTART;
0313 }
0314 if (!dev->present) {
0315
0316 return -ENODEV;
0317 }
0318 if (read_idx == -1) {
0319
0320 return 0;
0321 }
0322 }
0323 }
0324
0325 offset = read_idx * (dev->report_size + 1);
0326 if (copy_to_user(buffer, dev->read_queue + offset, count)) {
0327 return -EFAULT;
0328 }
0329 } while (atomic_read(&dev->overflow_flag));
0330
0331 read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
0332 atomic_set(&dev->read_idx, read_idx);
0333 return count;
0334 }
0335
0336
0337
0338
0339 static ssize_t iowarrior_write(struct file *file,
0340 const char __user *user_buffer,
0341 size_t count, loff_t *ppos)
0342 {
0343 struct iowarrior *dev;
0344 int retval = 0;
0345 char *buf = NULL;
0346 struct urb *int_out_urb = NULL;
0347
0348 dev = file->private_data;
0349
0350 mutex_lock(&dev->mutex);
0351
0352 if (!dev->present) {
0353 retval = -ENODEV;
0354 goto exit;
0355 }
0356 dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
0357 dev->minor, count);
0358
0359 if (count == 0) {
0360 retval = 0;
0361 goto exit;
0362 }
0363
0364 if (count != dev->report_size) {
0365 retval = -EINVAL;
0366 goto exit;
0367 }
0368 switch (dev->product_id) {
0369 case USB_DEVICE_ID_CODEMERCS_IOW24:
0370 case USB_DEVICE_ID_CODEMERCS_IOW24SAG:
0371 case USB_DEVICE_ID_CODEMERCS_IOWPV1:
0372 case USB_DEVICE_ID_CODEMERCS_IOWPV2:
0373 case USB_DEVICE_ID_CODEMERCS_IOW40:
0374
0375 buf = memdup_user(user_buffer, count);
0376 if (IS_ERR(buf)) {
0377 retval = PTR_ERR(buf);
0378 goto exit;
0379 }
0380 retval = usb_set_report(dev->interface, 2, 0, buf, count);
0381 kfree(buf);
0382 goto exit;
0383 case USB_DEVICE_ID_CODEMERCS_IOW56:
0384 case USB_DEVICE_ID_CODEMERCS_IOW56AM:
0385 case USB_DEVICE_ID_CODEMERCS_IOW28:
0386 case USB_DEVICE_ID_CODEMERCS_IOW28L:
0387 case USB_DEVICE_ID_CODEMERCS_IOW100:
0388
0389 if (atomic_read(&dev->write_busy) == MAX_WRITES_IN_FLIGHT) {
0390
0391 if (file->f_flags & O_NONBLOCK) {
0392 retval = -EAGAIN;
0393 goto exit;
0394 } else {
0395 retval = wait_event_interruptible(dev->write_wait,
0396 (!dev->present || (atomic_read (&dev-> write_busy) < MAX_WRITES_IN_FLIGHT)));
0397 if (retval) {
0398
0399 retval = -ERESTART;
0400 goto exit;
0401 }
0402 if (!dev->present) {
0403
0404 retval = -ENODEV;
0405 goto exit;
0406 }
0407 if (!dev->opened) {
0408
0409 retval = -ENODEV;
0410 goto exit;
0411 }
0412 }
0413 }
0414 atomic_inc(&dev->write_busy);
0415 int_out_urb = usb_alloc_urb(0, GFP_KERNEL);
0416 if (!int_out_urb) {
0417 retval = -ENOMEM;
0418 goto error_no_urb;
0419 }
0420 buf = usb_alloc_coherent(dev->udev, dev->report_size,
0421 GFP_KERNEL, &int_out_urb->transfer_dma);
0422 if (!buf) {
0423 retval = -ENOMEM;
0424 dev_dbg(&dev->interface->dev,
0425 "Unable to allocate buffer\n");
0426 goto error_no_buffer;
0427 }
0428 usb_fill_int_urb(int_out_urb, dev->udev,
0429 usb_sndintpipe(dev->udev,
0430 dev->int_out_endpoint->bEndpointAddress),
0431 buf, dev->report_size,
0432 iowarrior_write_callback, dev,
0433 dev->int_out_endpoint->bInterval);
0434 int_out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0435 if (copy_from_user(buf, user_buffer, count)) {
0436 retval = -EFAULT;
0437 goto error;
0438 }
0439 usb_anchor_urb(int_out_urb, &dev->submitted);
0440 retval = usb_submit_urb(int_out_urb, GFP_KERNEL);
0441 if (retval) {
0442 dev_dbg(&dev->interface->dev,
0443 "submit error %d for urb nr.%d\n",
0444 retval, atomic_read(&dev->write_busy));
0445 usb_unanchor_urb(int_out_urb);
0446 goto error;
0447 }
0448
0449 retval = count;
0450 usb_free_urb(int_out_urb);
0451 goto exit;
0452 default:
0453
0454 dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
0455 __func__, dev->product_id);
0456 retval = -EFAULT;
0457 goto exit;
0458 }
0459 error:
0460 usb_free_coherent(dev->udev, dev->report_size, buf,
0461 int_out_urb->transfer_dma);
0462 error_no_buffer:
0463 usb_free_urb(int_out_urb);
0464 error_no_urb:
0465 atomic_dec(&dev->write_busy);
0466 wake_up_interruptible(&dev->write_wait);
0467 exit:
0468 mutex_unlock(&dev->mutex);
0469 return retval;
0470 }
0471
0472
0473
0474
0475 static long iowarrior_ioctl(struct file *file, unsigned int cmd,
0476 unsigned long arg)
0477 {
0478 struct iowarrior *dev = NULL;
0479 __u8 *buffer;
0480 __u8 __user *user_buffer;
0481 int retval;
0482 int io_res;
0483
0484 dev = file->private_data;
0485 if (!dev)
0486 return -ENODEV;
0487
0488 buffer = kzalloc(dev->report_size, GFP_KERNEL);
0489 if (!buffer)
0490 return -ENOMEM;
0491
0492 mutex_lock(&dev->mutex);
0493
0494
0495 if (!dev->present) {
0496 retval = -ENODEV;
0497 goto error_out;
0498 }
0499
0500 dev_dbg(&dev->interface->dev, "minor %d, cmd 0x%.4x, arg %ld\n",
0501 dev->minor, cmd, arg);
0502
0503 retval = 0;
0504 io_res = 0;
0505 switch (cmd) {
0506 case IOW_WRITE:
0507 if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24 ||
0508 dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24SAG ||
0509 dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV1 ||
0510 dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV2 ||
0511 dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW40) {
0512 user_buffer = (__u8 __user *)arg;
0513 io_res = copy_from_user(buffer, user_buffer,
0514 dev->report_size);
0515 if (io_res) {
0516 retval = -EFAULT;
0517 } else {
0518 io_res = usb_set_report(dev->interface, 2, 0,
0519 buffer,
0520 dev->report_size);
0521 if (io_res < 0)
0522 retval = io_res;
0523 }
0524 } else {
0525 retval = -EINVAL;
0526 dev_err(&dev->interface->dev,
0527 "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n",
0528 dev->product_id);
0529 }
0530 break;
0531 case IOW_READ:
0532 user_buffer = (__u8 __user *)arg;
0533 io_res = usb_get_report(dev->udev,
0534 dev->interface->cur_altsetting, 1, 0,
0535 buffer, dev->report_size);
0536 if (io_res < 0)
0537 retval = io_res;
0538 else {
0539 io_res = copy_to_user(user_buffer, buffer, dev->report_size);
0540 if (io_res)
0541 retval = -EFAULT;
0542 }
0543 break;
0544 case IOW_GETINFO:
0545 {
0546
0547 struct iowarrior_info info;
0548
0549 struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;
0550
0551 memset(&info, 0, sizeof(info));
0552
0553 info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
0554 info.product = dev->product_id;
0555 info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
0556
0557
0558 info.speed = dev->udev->speed;
0559 info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
0560 info.report_size = dev->report_size;
0561
0562
0563 memcpy(info.serial, dev->chip_serial,
0564 sizeof(dev->chip_serial));
0565 if (cfg_descriptor == NULL) {
0566 info.power = -1;
0567 } else {
0568
0569 info.power = cfg_descriptor->bMaxPower * 2;
0570 }
0571 io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
0572 sizeof(struct iowarrior_info));
0573 if (io_res)
0574 retval = -EFAULT;
0575 break;
0576 }
0577 default:
0578
0579 retval = -ENOTTY;
0580 break;
0581 }
0582 error_out:
0583
0584 mutex_unlock(&dev->mutex);
0585 kfree(buffer);
0586 return retval;
0587 }
0588
0589
0590
0591
0592 static int iowarrior_open(struct inode *inode, struct file *file)
0593 {
0594 struct iowarrior *dev = NULL;
0595 struct usb_interface *interface;
0596 int subminor;
0597 int retval = 0;
0598
0599 subminor = iminor(inode);
0600
0601 interface = usb_find_interface(&iowarrior_driver, subminor);
0602 if (!interface) {
0603 pr_err("%s - error, can't find device for minor %d\n",
0604 __func__, subminor);
0605 return -ENODEV;
0606 }
0607
0608 dev = usb_get_intfdata(interface);
0609 if (!dev)
0610 return -ENODEV;
0611
0612 mutex_lock(&dev->mutex);
0613
0614
0615 if (dev->opened) {
0616 retval = -EBUSY;
0617 goto out;
0618 }
0619
0620
0621 if ((retval = usb_submit_urb(dev->int_in_urb, GFP_KERNEL)) < 0) {
0622 dev_err(&interface->dev, "Error %d while submitting URB\n", retval);
0623 retval = -EFAULT;
0624 goto out;
0625 }
0626
0627 ++dev->opened;
0628
0629 file->private_data = dev;
0630 retval = 0;
0631
0632 out:
0633 mutex_unlock(&dev->mutex);
0634 return retval;
0635 }
0636
0637
0638
0639
0640 static int iowarrior_release(struct inode *inode, struct file *file)
0641 {
0642 struct iowarrior *dev;
0643 int retval = 0;
0644
0645 dev = file->private_data;
0646 if (!dev)
0647 return -ENODEV;
0648
0649 dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor);
0650
0651
0652 mutex_lock(&dev->mutex);
0653
0654 if (dev->opened <= 0) {
0655 retval = -ENODEV;
0656 mutex_unlock(&dev->mutex);
0657 } else {
0658 dev->opened = 0;
0659 retval = 0;
0660 if (dev->present) {
0661
0662
0663
0664
0665 usb_kill_urb(dev->int_in_urb);
0666 wake_up_interruptible(&dev->read_wait);
0667 wake_up_interruptible(&dev->write_wait);
0668 mutex_unlock(&dev->mutex);
0669 } else {
0670
0671 mutex_unlock(&dev->mutex);
0672 iowarrior_delete(dev);
0673 }
0674 }
0675 return retval;
0676 }
0677
0678 static __poll_t iowarrior_poll(struct file *file, poll_table * wait)
0679 {
0680 struct iowarrior *dev = file->private_data;
0681 __poll_t mask = 0;
0682
0683 if (!dev->present)
0684 return EPOLLERR | EPOLLHUP;
0685
0686 poll_wait(file, &dev->read_wait, wait);
0687 poll_wait(file, &dev->write_wait, wait);
0688
0689 if (!dev->present)
0690 return EPOLLERR | EPOLLHUP;
0691
0692 if (read_index(dev) != -1)
0693 mask |= EPOLLIN | EPOLLRDNORM;
0694
0695 if (atomic_read(&dev->write_busy) < MAX_WRITES_IN_FLIGHT)
0696 mask |= EPOLLOUT | EPOLLWRNORM;
0697 return mask;
0698 }
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709 static const struct file_operations iowarrior_fops = {
0710 .owner = THIS_MODULE,
0711 .write = iowarrior_write,
0712 .read = iowarrior_read,
0713 .unlocked_ioctl = iowarrior_ioctl,
0714 .open = iowarrior_open,
0715 .release = iowarrior_release,
0716 .poll = iowarrior_poll,
0717 .llseek = noop_llseek,
0718 };
0719
0720 static char *iowarrior_devnode(struct device *dev, umode_t *mode)
0721 {
0722 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
0723 }
0724
0725
0726
0727
0728
0729 static struct usb_class_driver iowarrior_class = {
0730 .name = "iowarrior%d",
0731 .devnode = iowarrior_devnode,
0732 .fops = &iowarrior_fops,
0733 .minor_base = IOWARRIOR_MINOR_BASE,
0734 };
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745 static int iowarrior_probe(struct usb_interface *interface,
0746 const struct usb_device_id *id)
0747 {
0748 struct usb_device *udev = interface_to_usbdev(interface);
0749 struct iowarrior *dev = NULL;
0750 struct usb_host_interface *iface_desc;
0751 int retval = -ENOMEM;
0752 int res;
0753
0754
0755 dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
0756 if (!dev)
0757 return retval;
0758
0759 mutex_init(&dev->mutex);
0760
0761 atomic_set(&dev->intr_idx, 0);
0762 atomic_set(&dev->read_idx, 0);
0763 atomic_set(&dev->overflow_flag, 0);
0764 init_waitqueue_head(&dev->read_wait);
0765 atomic_set(&dev->write_busy, 0);
0766 init_waitqueue_head(&dev->write_wait);
0767
0768 dev->udev = udev;
0769 dev->interface = usb_get_intf(interface);
0770
0771 iface_desc = interface->cur_altsetting;
0772 dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
0773
0774 init_usb_anchor(&dev->submitted);
0775
0776 res = usb_find_last_int_in_endpoint(iface_desc, &dev->int_in_endpoint);
0777 if (res) {
0778 dev_err(&interface->dev, "no interrupt-in endpoint found\n");
0779 retval = res;
0780 goto error;
0781 }
0782
0783 if ((dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56) ||
0784 (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56AM) ||
0785 (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW28) ||
0786 (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW28L) ||
0787 (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW100)) {
0788 res = usb_find_last_int_out_endpoint(iface_desc,
0789 &dev->int_out_endpoint);
0790 if (res) {
0791 dev_err(&interface->dev, "no interrupt-out endpoint found\n");
0792 retval = res;
0793 goto error;
0794 }
0795 }
0796
0797
0798 dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);
0799
0800
0801
0802
0803
0804 if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
0805 switch (dev->product_id) {
0806 case USB_DEVICE_ID_CODEMERCS_IOW56:
0807 case USB_DEVICE_ID_CODEMERCS_IOW56AM:
0808 dev->report_size = 7;
0809 break;
0810
0811 case USB_DEVICE_ID_CODEMERCS_IOW28:
0812 case USB_DEVICE_ID_CODEMERCS_IOW28L:
0813 dev->report_size = 4;
0814 break;
0815
0816 case USB_DEVICE_ID_CODEMERCS_IOW100:
0817 dev->report_size = 13;
0818 break;
0819 }
0820 }
0821
0822
0823 dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
0824 if (!dev->int_in_urb)
0825 goto error;
0826 dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL);
0827 if (!dev->int_in_buffer)
0828 goto error;
0829 usb_fill_int_urb(dev->int_in_urb, dev->udev,
0830 usb_rcvintpipe(dev->udev,
0831 dev->int_in_endpoint->bEndpointAddress),
0832 dev->int_in_buffer, dev->report_size,
0833 iowarrior_callback, dev,
0834 dev->int_in_endpoint->bInterval);
0835
0836 dev->read_queue =
0837 kmalloc_array(dev->report_size + 1, MAX_INTERRUPT_BUFFER,
0838 GFP_KERNEL);
0839 if (!dev->read_queue)
0840 goto error;
0841
0842 memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
0843 usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial,
0844 sizeof(dev->chip_serial));
0845 if (strlen(dev->chip_serial) != 8)
0846 memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
0847
0848
0849 if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
0850 usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
0851 0x0A,
0852 USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
0853 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
0854 }
0855
0856 dev->present = 1;
0857
0858
0859 usb_set_intfdata(interface, dev);
0860
0861 retval = usb_register_dev(interface, &iowarrior_class);
0862 if (retval) {
0863
0864 dev_err(&interface->dev, "Not able to get a minor for this device.\n");
0865 goto error;
0866 }
0867
0868 dev->minor = interface->minor;
0869
0870
0871 dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
0872 "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
0873 iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
0874 return retval;
0875
0876 error:
0877 iowarrior_delete(dev);
0878 return retval;
0879 }
0880
0881
0882
0883
0884
0885
0886 static void iowarrior_disconnect(struct usb_interface *interface)
0887 {
0888 struct iowarrior *dev = usb_get_intfdata(interface);
0889 int minor = dev->minor;
0890
0891 usb_deregister_dev(interface, &iowarrior_class);
0892
0893 mutex_lock(&dev->mutex);
0894
0895
0896 dev->present = 0;
0897
0898 if (dev->opened) {
0899
0900
0901
0902
0903 usb_kill_urb(dev->int_in_urb);
0904 usb_kill_anchored_urbs(&dev->submitted);
0905 wake_up_interruptible(&dev->read_wait);
0906 wake_up_interruptible(&dev->write_wait);
0907 mutex_unlock(&dev->mutex);
0908 } else {
0909
0910 mutex_unlock(&dev->mutex);
0911 iowarrior_delete(dev);
0912 }
0913
0914 dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
0915 minor - IOWARRIOR_MINOR_BASE);
0916 }
0917
0918
0919 static struct usb_driver iowarrior_driver = {
0920 .name = "iowarrior",
0921 .probe = iowarrior_probe,
0922 .disconnect = iowarrior_disconnect,
0923 .id_table = iowarrior_ids,
0924 };
0925
0926 module_usb_driver(iowarrior_driver);