summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c252
1 files changed, 20 insertions, 232 deletions
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 7984e03..2be5087 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);