diff options
-rw-r--r-- | drivers/staging/comedi/drivers/vmk80xx.c | 252 |
1 files changed, 20 insertions, 232 deletions
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 7984e036c041..2be5087414f6 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -100,16 +100,9 @@ enum { #define VMK8061_CMD_RD_AO 0x0f #define VMK8061_CMD_RD_PWM 0x10 -#define TRANS_OUT_BUSY 1 -#define TRANS_IN_BUSY 2 -#define TRANS_IN_RUNNING 3 - #define IC3_VERSION (1 << 0) #define IC6_VERSION (1 << 1) -#define URB_RCV_FLAG (1 << 0) -#define URB_SND_FLAG (1 << 1) - enum vmk80xx_model { VMK8055_MODEL, VMK8061_MODEL @@ -170,60 +163,13 @@ struct vmk80xx_private { struct usb_interface *intf; struct usb_endpoint_descriptor *ep_rx; struct usb_endpoint_descriptor *ep_tx; - struct usb_anchor rx_anchor; - struct usb_anchor tx_anchor; struct firmware_version fw; struct semaphore limit_sem; - wait_queue_head_t read_wait; - wait_queue_head_t write_wait; unsigned char *usb_rx_buf; unsigned char *usb_tx_buf; - unsigned long flags; enum vmk80xx_model model; }; -static void vmk80xx_tx_callback(struct urb *urb) -{ - struct vmk80xx_private *devpriv = urb->context; - unsigned long *flags = &devpriv->flags; - - if (!test_bit(TRANS_OUT_BUSY, flags)) - return; - - clear_bit(TRANS_OUT_BUSY, flags); - - wake_up_interruptible(&devpriv->write_wait); -} - -static void vmk80xx_rx_callback(struct urb *urb) -{ - struct vmk80xx_private *devpriv = urb->context; - unsigned long *flags = &devpriv->flags; - int stat = urb->status; - - switch (stat) { - case 0: - break; - case -ENOENT: - case -ECONNRESET: - case -ESHUTDOWN: - break; - default: - /* Try to resubmit the urb */ - if (test_bit(TRANS_IN_RUNNING, flags) && devpriv->intf) { - usb_anchor_urb(urb, &devpriv->rx_anchor); - - if (usb_submit_urb(urb, GFP_KERNEL)) - usb_unanchor_urb(urb); - } - break; - } - - clear_bit(TRANS_IN_BUSY, flags); - - wake_up_interruptible(&devpriv->read_wait); -} - static int vmk80xx_check_data_link(struct vmk80xx_private *devpriv) { struct usb_device *usb = devpriv->usb; @@ -277,50 +223,15 @@ static void vmk80xx_read_eeprom(struct vmk80xx_private *devpriv, int flag) strncpy(devpriv->fw.ic6_vers, rx + 25, 24); } -static void vmk80xx_build_int_urb(struct urb *urb, int flag) -{ - struct vmk80xx_private *devpriv = urb->context; - struct usb_device *usb = devpriv->usb; - __u8 rx_addr; - __u8 tx_addr; - unsigned int pipe; - unsigned char *buf; - size_t size; - void (*callback) (struct urb *); - int ival; - - if (flag & URB_RCV_FLAG) { - rx_addr = devpriv->ep_rx->bEndpointAddress; - pipe = usb_rcvintpipe(usb, rx_addr); - buf = devpriv->usb_rx_buf; - size = le16_to_cpu(devpriv->ep_rx->wMaxPacketSize); - callback = vmk80xx_rx_callback; - ival = devpriv->ep_rx->bInterval; - } else { /* URB_SND_FLAG */ - tx_addr = devpriv->ep_tx->bEndpointAddress; - pipe = usb_sndintpipe(usb, tx_addr); - buf = devpriv->usb_tx_buf; - size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize); - callback = vmk80xx_tx_callback; - ival = devpriv->ep_tx->bInterval; - } - - usb_fill_int_urb(urb, usb, pipe, buf, size, callback, devpriv, ival); -} - static void vmk80xx_do_bulk_msg(struct vmk80xx_private *devpriv) { struct usb_device *usb = devpriv->usb; - unsigned long *flags = &devpriv->flags; __u8 tx_addr; __u8 rx_addr; unsigned int tx_pipe; unsigned int rx_pipe; size_t size; - set_bit(TRANS_IN_BUSY, flags); - set_bit(TRANS_OUT_BUSY, flags); - tx_addr = devpriv->ep_tx->bEndpointAddress; rx_addr = devpriv->ep_rx->bEndpointAddress; tx_pipe = usb_sndbulkpipe(usb, tx_addr); @@ -335,102 +246,52 @@ static void vmk80xx_do_bulk_msg(struct vmk80xx_private *devpriv) usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, size, NULL, devpriv->ep_tx->bInterval); usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10); - - clear_bit(TRANS_OUT_BUSY, flags); - clear_bit(TRANS_IN_BUSY, flags); } static int vmk80xx_read_packet(struct vmk80xx_private *devpriv) { - unsigned long *flags = &devpriv->flags; - struct urb *urb; - int retval; + struct usb_device *usb; + struct usb_endpoint_descriptor *ep; + unsigned int pipe; if (!devpriv->intf) return -ENODEV; - /* Only useful for interrupt transfers */ - if (test_bit(TRANS_IN_BUSY, flags)) - if (wait_event_interruptible(devpriv->read_wait, - !test_bit(TRANS_IN_BUSY, flags))) - return -ERESTART; - if (devpriv->model == VMK8061_MODEL) { vmk80xx_do_bulk_msg(devpriv); - return 0; } - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - return -ENOMEM; - - urb->context = devpriv; - vmk80xx_build_int_urb(urb, URB_RCV_FLAG); - - set_bit(TRANS_IN_RUNNING, flags); - set_bit(TRANS_IN_BUSY, flags); - - usb_anchor_urb(urb, &devpriv->rx_anchor); - - retval = usb_submit_urb(urb, GFP_KERNEL); - if (!retval) - goto exit; - - clear_bit(TRANS_IN_RUNNING, flags); - usb_unanchor_urb(urb); - -exit: - usb_free_urb(urb); - - return retval; + usb = devpriv->usb; + ep = devpriv->ep_rx; + pipe = usb_rcvintpipe(usb, ep->bEndpointAddress); + return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf, + le16_to_cpu(ep->wMaxPacketSize), NULL, + HZ * 10); } static int vmk80xx_write_packet(struct vmk80xx_private *devpriv, int cmd) { - unsigned long *flags = &devpriv->flags; - struct urb *urb; - int retval; + struct usb_device *usb; + struct usb_endpoint_descriptor *ep; + unsigned int pipe; if (!devpriv->intf) return -ENODEV; - if (test_bit(TRANS_OUT_BUSY, flags)) - if (wait_event_interruptible(devpriv->write_wait, - !test_bit(TRANS_OUT_BUSY, flags))) - return -ERESTART; + devpriv->usb_tx_buf[0] = cmd; if (devpriv->model == VMK8061_MODEL) { - devpriv->usb_tx_buf[0] = cmd; vmk80xx_do_bulk_msg(devpriv); - return 0; } - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - return -ENOMEM; - - urb->context = devpriv; - vmk80xx_build_int_urb(urb, URB_SND_FLAG); - - set_bit(TRANS_OUT_BUSY, flags); - - usb_anchor_urb(urb, &devpriv->tx_anchor); - - devpriv->usb_tx_buf[0] = cmd; - - retval = usb_submit_urb(urb, GFP_KERNEL); - if (!retval) - goto exit; - - clear_bit(TRANS_OUT_BUSY, flags); - usb_unanchor_urb(urb); - -exit: - usb_free_urb(urb); - - return retval; + usb = devpriv->usb; + ep = devpriv->ep_tx; + pipe = usb_sndintpipe(usb, ep->bEndpointAddress); + return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf, + le16_to_cpu(ep->wMaxPacketSize), NULL, + HZ * 10); } static int vmk80xx_reset_device(struct vmk80xx_private *devpriv) @@ -447,25 +308,6 @@ static int vmk80xx_reset_device(struct vmk80xx_private *devpriv) return vmk80xx_write_packet(devpriv, VMK8055_CMD_WRT_AD); } -#define DIR_IN 1 -#define DIR_OUT 2 - -static int rudimentary_check(struct vmk80xx_private *devpriv, int dir) -{ - if (!devpriv) - return -EFAULT; - if (dir & DIR_IN) { - if (test_bit(TRANS_IN_BUSY, &devpriv->flags)) - return -EBUSY; - } - if (dir & DIR_OUT) { - if (test_bit(TRANS_OUT_BUSY, &devpriv->flags)) - return -EBUSY; - } - - return 0; -} - static int vmk80xx_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -476,10 +318,6 @@ static int vmk80xx_ai_insn_read(struct comedi_device *dev, int reg[2]; int n; - n = rudimentary_check(devpriv, DIR_IN); - if (n) - return n; - down(&devpriv->limit_sem); chan = CR_CHAN(insn->chanspec); @@ -529,10 +367,6 @@ static int vmk80xx_ao_insn_write(struct comedi_device *dev, int reg; int n; - n = rudimentary_check(devpriv, DIR_OUT); - if (n) - return n; - down(&devpriv->limit_sem); chan = CR_CHAN(insn->chanspec); @@ -573,10 +407,6 @@ static int vmk80xx_ao_insn_read(struct comedi_device *dev, int reg; int n; - n = rudimentary_check(devpriv, DIR_IN); - if (n) - return n; - down(&devpriv->limit_sem); chan = CR_CHAN(insn->chanspec); @@ -606,10 +436,6 @@ static int vmk80xx_di_insn_bits(struct comedi_device *dev, int reg; int retval; - retval = rudimentary_check(devpriv, DIR_IN); - if (retval) - return retval; - down(&devpriv->limit_sem); rx_buf = devpriv->usb_rx_buf; @@ -646,16 +472,10 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev, { struct vmk80xx_private *devpriv = dev->private; unsigned char *rx_buf, *tx_buf; - int dir, reg, cmd; + int reg, cmd; int retval; - dir = 0; - - if (data[0]) - dir |= DIR_OUT; - if (devpriv->model == VMK8061_MODEL) { - dir |= DIR_IN; reg = VMK8061_DO_REG; cmd = VMK8061_CMD_DO; } else { /* VMK8055_MODEL */ @@ -663,10 +483,6 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev, cmd = VMK8055_CMD_WRT_AD; } - retval = rudimentary_check(devpriv, dir); - if (retval) - return retval; - down(&devpriv->limit_sem); rx_buf = devpriv->usb_rx_buf; @@ -712,10 +528,6 @@ static int vmk80xx_cnt_insn_read(struct comedi_device *dev, int reg[2]; int n; - n = rudimentary_check(devpriv, DIR_IN); - if (n) - return n; - down(&devpriv->limit_sem); chan = CR_CHAN(insn->chanspec); @@ -762,10 +574,6 @@ static int vmk80xx_cnt_insn_config(struct comedi_device *dev, int reg; int n; - n = rudimentary_check(devpriv, DIR_OUT); - if (n) - return n; - insn_cmd = data[0]; if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET) return -EINVAL; @@ -809,10 +617,6 @@ static int vmk80xx_cnt_insn_write(struct comedi_device *dev, int cmd; int n; - n = rudimentary_check(devpriv, DIR_OUT); - if (n) - return n; - down(&devpriv->limit_sem); chan = CR_CHAN(insn->chanspec); @@ -856,10 +660,6 @@ static int vmk80xx_pwm_insn_read(struct comedi_device *dev, int reg[2]; int n; - n = rudimentary_check(devpriv, DIR_IN); - if (n) - return n; - down(&devpriv->limit_sem); tx_buf = devpriv->usb_tx_buf; @@ -893,10 +693,6 @@ static int vmk80xx_pwm_insn_write(struct comedi_device *dev, int cmd; int n; - n = rudimentary_check(devpriv, DIR_OUT); - if (n) - return n; - down(&devpriv->limit_sem); tx_buf = devpriv->usb_tx_buf; @@ -1106,11 +902,6 @@ static int vmk80xx_auto_attach(struct comedi_device *dev, return ret; sema_init(&devpriv->limit_sem, 8); - init_waitqueue_head(&devpriv->read_wait); - init_waitqueue_head(&devpriv->write_wait); - - init_usb_anchor(&devpriv->rx_anchor); - init_usb_anchor(&devpriv->tx_anchor); usb_set_intfdata(intf, devpriv); @@ -1141,9 +932,6 @@ static void vmk80xx_detach(struct comedi_device *dev) usb_set_intfdata(devpriv->intf, NULL); - usb_kill_anchored_urbs(&devpriv->rx_anchor); - usb_kill_anchored_urbs(&devpriv->tx_anchor); - kfree(devpriv->usb_rx_buf); kfree(devpriv->usb_tx_buf); |