aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2013-02-18 06:15:55 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-18 13:53:50 -0500
commit951348b377385475aa256c27e1c9e2564c9ec160 (patch)
treecc6d70195338393e4362e24da879e2ac7b9421a5
parent6b07b30892ad972286871787079ed68d07779ba4 (diff)
staging: comedi: vmk80xx: wait for URBs to complete
For Velleman K8055 (aka VM110), `vmk80xx_read_packet()` and `vmk8055_write_packet()` send an URB asynchronously and do not wait for it complete. However, callers of `vmk80xx_read_packet()` are assuming the contents of the data buffer `devpriv->usb_rx_buf` are valid immediately after that function returns. For Velleman K8061 (aka VM140), `vmk80xx_read_packet()` and `vmk80xx_write_packet()` punt the requests to `vmk80xx_do_bulk_msg()` which *does* wait for the URBs to complete (albeit with no error checking!). Change `vmk80xx_read_packet()` and `vmk80xx_write_packet()` to use `usb_interrupt_msg()` for the K8055, so the callers of `vmk80xx_read_packet()` can assume the data buffer contents are valid (if no error occurred). Remove all the code for checking for transfers in progress and busy waiting, as it's no longer needed. Pretty much all the callers of `vmk80xx_read_packet()` and `vmk80xx_write_packet()` hold the same semaphore anyway, and the only caller that doesn't (`vmk80xx_reset_device()` called during initialization of the device) doesn't really matter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 7984e036c041..2be5087414f6 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -100,16 +100,9 @@ enum {
100#define VMK8061_CMD_RD_AO 0x0f 100#define VMK8061_CMD_RD_AO 0x0f
101#define VMK8061_CMD_RD_PWM 0x10 101#define VMK8061_CMD_RD_PWM 0x10
102 102
103#define TRANS_OUT_BUSY 1
104#define TRANS_IN_BUSY 2
105#define TRANS_IN_RUNNING 3
106
107#define IC3_VERSION (1 << 0) 103#define IC3_VERSION (1 << 0)
108#define IC6_VERSION (1 << 1) 104#define IC6_VERSION (1 << 1)
109 105
110#define URB_RCV_FLAG (1 << 0)
111#define URB_SND_FLAG (1 << 1)
112
113enum vmk80xx_model { 106enum vmk80xx_model {
114 VMK8055_MODEL, 107 VMK8055_MODEL,
115 VMK8061_MODEL 108 VMK8061_MODEL
@@ -170,60 +163,13 @@ struct vmk80xx_private {
170 struct usb_interface *intf; 163 struct usb_interface *intf;
171 struct usb_endpoint_descriptor *ep_rx; 164 struct usb_endpoint_descriptor *ep_rx;
172 struct usb_endpoint_descriptor *ep_tx; 165 struct usb_endpoint_descriptor *ep_tx;
173 struct usb_anchor rx_anchor;
174 struct usb_anchor tx_anchor;
175 struct firmware_version fw; 166 struct firmware_version fw;
176 struct semaphore limit_sem; 167 struct semaphore limit_sem;
177 wait_queue_head_t read_wait;
178 wait_queue_head_t write_wait;
179 unsigned char *usb_rx_buf; 168 unsigned char *usb_rx_buf;
180 unsigned char *usb_tx_buf; 169 unsigned char *usb_tx_buf;
181 unsigned long flags;
182 enum vmk80xx_model model; 170 enum vmk80xx_model model;
183}; 171};
184 172
185static void vmk80xx_tx_callback(struct urb *urb)
186{
187 struct vmk80xx_private *devpriv = urb->context;
188 unsigned long *flags = &devpriv->flags;
189
190 if (!test_bit(TRANS_OUT_BUSY, flags))
191 return;
192
193 clear_bit(TRANS_OUT_BUSY, flags);
194
195 wake_up_interruptible(&devpriv->write_wait);
196}
197
198static void vmk80xx_rx_callback(struct urb *urb)
199{
200 struct vmk80xx_private *devpriv = urb->context;
201 unsigned long *flags = &devpriv->flags;
202 int stat = urb->status;
203
204 switch (stat) {
205 case 0:
206 break;
207 case -ENOENT:
208 case -ECONNRESET:
209 case -ESHUTDOWN:
210 break;
211 default:
212 /* Try to resubmit the urb */
213 if (test_bit(TRANS_IN_RUNNING, flags) && devpriv->intf) {
214 usb_anchor_urb(urb, &devpriv->rx_anchor);
215
216 if (usb_submit_urb(urb, GFP_KERNEL))
217 usb_unanchor_urb(urb);
218 }
219 break;
220 }
221
222 clear_bit(TRANS_IN_BUSY, flags);
223
224 wake_up_interruptible(&devpriv->read_wait);
225}
226
227static int vmk80xx_check_data_link(struct vmk80xx_private *devpriv) 173static int vmk80xx_check_data_link(struct vmk80xx_private *devpriv)
228{ 174{
229 struct usb_device *usb = devpriv->usb; 175 struct usb_device *usb = devpriv->usb;
@@ -277,50 +223,15 @@ static void vmk80xx_read_eeprom(struct vmk80xx_private *devpriv, int flag)
277 strncpy(devpriv->fw.ic6_vers, rx + 25, 24); 223 strncpy(devpriv->fw.ic6_vers, rx + 25, 24);
278} 224}
279 225
280static void vmk80xx_build_int_urb(struct urb *urb, int flag)
281{
282 struct vmk80xx_private *devpriv = urb->context;
283 struct usb_device *usb = devpriv->usb;
284 __u8 rx_addr;
285 __u8 tx_addr;
286 unsigned int pipe;
287 unsigned char *buf;
288 size_t size;
289 void (*callback) (struct urb *);
290 int ival;
291
292 if (flag & URB_RCV_FLAG) {
293 rx_addr = devpriv->ep_rx->bEndpointAddress;
294 pipe = usb_rcvintpipe(usb, rx_addr);
295 buf = devpriv->usb_rx_buf;
296 size = le16_to_cpu(devpriv->ep_rx->wMaxPacketSize);
297 callback = vmk80xx_rx_callback;
298 ival = devpriv->ep_rx->bInterval;
299 } else { /* URB_SND_FLAG */
300 tx_addr = devpriv->ep_tx->bEndpointAddress;
301 pipe = usb_sndintpipe(usb, tx_addr);
302 buf = devpriv->usb_tx_buf;
303 size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize);
304 callback = vmk80xx_tx_callback;
305 ival = devpriv->ep_tx->bInterval;
306 }
307
308 usb_fill_int_urb(urb, usb, pipe, buf, size, callback, devpriv, ival);
309}
310
311static void vmk80xx_do_bulk_msg(struct vmk80xx_private *devpriv) 226static void vmk80xx_do_bulk_msg(struct vmk80xx_private *devpriv)
312{ 227{
313 struct usb_device *usb = devpriv->usb; 228 struct usb_device *usb = devpriv->usb;
314 unsigned long *flags = &devpriv->flags;
315 __u8 tx_addr; 229 __u8 tx_addr;
316 __u8 rx_addr; 230 __u8 rx_addr;
317 unsigned int tx_pipe; 231 unsigned int tx_pipe;
318 unsigned int rx_pipe; 232 unsigned int rx_pipe;
319 size_t size; 233 size_t size;
320 234
321 set_bit(TRANS_IN_BUSY, flags);
322 set_bit(TRANS_OUT_BUSY, flags);
323
324 tx_addr = devpriv->ep_tx->bEndpointAddress; 235 tx_addr = devpriv->ep_tx->bEndpointAddress;
325 rx_addr = devpriv->ep_rx->bEndpointAddress; 236 rx_addr = devpriv->ep_rx->bEndpointAddress;
326 tx_pipe = usb_sndbulkpipe(usb, tx_addr); 237 tx_pipe = usb_sndbulkpipe(usb, tx_addr);
@@ -335,102 +246,52 @@ static void vmk80xx_do_bulk_msg(struct vmk80xx_private *devpriv)
335 usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, 246 usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf,
336 size, NULL, devpriv->ep_tx->bInterval); 247 size, NULL, devpriv->ep_tx->bInterval);
337 usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10); 248 usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10);
338
339 clear_bit(TRANS_OUT_BUSY, flags);
340 clear_bit(TRANS_IN_BUSY, flags);
341} 249}
342 250
343static int vmk80xx_read_packet(struct vmk80xx_private *devpriv) 251static int vmk80xx_read_packet(struct vmk80xx_private *devpriv)
344{ 252{
345 unsigned long *flags = &devpriv->flags; 253 struct usb_device *usb;
346 struct urb *urb; 254 struct usb_endpoint_descriptor *ep;
347 int retval; 255 unsigned int pipe;
348 256
349 if (!devpriv->intf) 257 if (!devpriv->intf)
350 return -ENODEV; 258 return -ENODEV;
351 259
352 /* Only useful for interrupt transfers */
353 if (test_bit(TRANS_IN_BUSY, flags))
354 if (wait_event_interruptible(devpriv->read_wait,
355 !test_bit(TRANS_IN_BUSY, flags)))
356 return -ERESTART;
357
358 if (devpriv->model == VMK8061_MODEL) { 260 if (devpriv->model == VMK8061_MODEL) {
359 vmk80xx_do_bulk_msg(devpriv); 261 vmk80xx_do_bulk_msg(devpriv);
360
361 return 0; 262 return 0;
362 } 263 }
363 264
364 urb = usb_alloc_urb(0, GFP_KERNEL); 265 usb = devpriv->usb;
365 if (!urb) 266 ep = devpriv->ep_rx;
366 return -ENOMEM; 267 pipe = usb_rcvintpipe(usb, ep->bEndpointAddress);
367 268 return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf,
368 urb->context = devpriv; 269 le16_to_cpu(ep->wMaxPacketSize), NULL,
369 vmk80xx_build_int_urb(urb, URB_RCV_FLAG); 270 HZ * 10);
370
371 set_bit(TRANS_IN_RUNNING, flags);
372 set_bit(TRANS_IN_BUSY, flags);
373
374 usb_anchor_urb(urb, &devpriv->rx_anchor);
375
376 retval = usb_submit_urb(urb, GFP_KERNEL);
377 if (!retval)
378 goto exit;
379
380 clear_bit(TRANS_IN_RUNNING, flags);
381 usb_unanchor_urb(urb);
382
383exit:
384 usb_free_urb(urb);
385
386 return retval;
387} 271}
388 272
389static int vmk80xx_write_packet(struct vmk80xx_private *devpriv, int cmd) 273static int vmk80xx_write_packet(struct vmk80xx_private *devpriv, int cmd)
390{ 274{
391 unsigned long *flags = &devpriv->flags; 275 struct usb_device *usb;
392 struct urb *urb; 276 struct usb_endpoint_descriptor *ep;
393 int retval; 277 unsigned int pipe;
394 278
395 if (!devpriv->intf) 279 if (!devpriv->intf)
396 return -ENODEV; 280 return -ENODEV;
397 281
398 if (test_bit(TRANS_OUT_BUSY, flags)) 282 devpriv->usb_tx_buf[0] = cmd;
399 if (wait_event_interruptible(devpriv->write_wait,
400 !test_bit(TRANS_OUT_BUSY, flags)))
401 return -ERESTART;
402 283
403 if (devpriv->model == VMK8061_MODEL) { 284 if (devpriv->model == VMK8061_MODEL) {
404 devpriv->usb_tx_buf[0] = cmd;
405 vmk80xx_do_bulk_msg(devpriv); 285 vmk80xx_do_bulk_msg(devpriv);
406
407 return 0; 286 return 0;
408 } 287 }
409 288
410 urb = usb_alloc_urb(0, GFP_KERNEL); 289 usb = devpriv->usb;
411 if (!urb) 290 ep = devpriv->ep_tx;
412 return -ENOMEM; 291 pipe = usb_sndintpipe(usb, ep->bEndpointAddress);
413 292 return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf,
414 urb->context = devpriv; 293 le16_to_cpu(ep->wMaxPacketSize), NULL,
415 vmk80xx_build_int_urb(urb, URB_SND_FLAG); 294 HZ * 10);
416
417 set_bit(TRANS_OUT_BUSY, flags);
418
419 usb_anchor_urb(urb, &devpriv->tx_anchor);
420
421 devpriv->usb_tx_buf[0] = cmd;
422
423 retval = usb_submit_urb(urb, GFP_KERNEL);
424 if (!retval)
425 goto exit;
426
427 clear_bit(TRANS_OUT_BUSY, flags);
428 usb_unanchor_urb(urb);
429
430exit:
431 usb_free_urb(urb);
432
433 return retval;
434} 295}
435 296
436static int vmk80xx_reset_device(struct vmk80xx_private *devpriv) 297static int vmk80xx_reset_device(struct vmk80xx_private *devpriv)
@@ -447,25 +308,6 @@ static int vmk80xx_reset_device(struct vmk80xx_private *devpriv)
447 return vmk80xx_write_packet(devpriv, VMK8055_CMD_WRT_AD); 308 return vmk80xx_write_packet(devpriv, VMK8055_CMD_WRT_AD);
448} 309}
449 310
450#define DIR_IN 1
451#define DIR_OUT 2
452
453static int rudimentary_check(struct vmk80xx_private *devpriv, int dir)
454{
455 if (!devpriv)
456 return -EFAULT;
457 if (dir & DIR_IN) {
458 if (test_bit(TRANS_IN_BUSY, &devpriv->flags))
459 return -EBUSY;
460 }
461 if (dir & DIR_OUT) {
462 if (test_bit(TRANS_OUT_BUSY, &devpriv->flags))
463 return -EBUSY;
464 }
465
466 return 0;
467}
468
469static int vmk80xx_ai_insn_read(struct comedi_device *dev, 311static int vmk80xx_ai_insn_read(struct comedi_device *dev,
470 struct comedi_subdevice *s, 312 struct comedi_subdevice *s,
471 struct comedi_insn *insn, 313 struct comedi_insn *insn,
@@ -476,10 +318,6 @@ static int vmk80xx_ai_insn_read(struct comedi_device *dev,
476 int reg[2]; 318 int reg[2];
477 int n; 319 int n;
478 320
479 n = rudimentary_check(devpriv, DIR_IN);
480 if (n)
481 return n;
482
483 down(&devpriv->limit_sem); 321 down(&devpriv->limit_sem);
484 chan = CR_CHAN(insn->chanspec); 322 chan = CR_CHAN(insn->chanspec);
485 323
@@ -529,10 +367,6 @@ static int vmk80xx_ao_insn_write(struct comedi_device *dev,
529 int reg; 367 int reg;
530 int n; 368 int n;
531 369
532 n = rudimentary_check(devpriv, DIR_OUT);
533 if (n)
534 return n;
535
536 down(&devpriv->limit_sem); 370 down(&devpriv->limit_sem);
537 chan = CR_CHAN(insn->chanspec); 371 chan = CR_CHAN(insn->chanspec);
538 372
@@ -573,10 +407,6 @@ static int vmk80xx_ao_insn_read(struct comedi_device *dev,
573 int reg; 407 int reg;
574 int n; 408 int n;
575 409
576 n = rudimentary_check(devpriv, DIR_IN);
577 if (n)
578 return n;
579
580 down(&devpriv->limit_sem); 410 down(&devpriv->limit_sem);
581 chan = CR_CHAN(insn->chanspec); 411 chan = CR_CHAN(insn->chanspec);
582 412
@@ -606,10 +436,6 @@ static int vmk80xx_di_insn_bits(struct comedi_device *dev,
606 int reg; 436 int reg;
607 int retval; 437 int retval;
608 438
609 retval = rudimentary_check(devpriv, DIR_IN);
610 if (retval)
611 return retval;
612
613 down(&devpriv->limit_sem); 439 down(&devpriv->limit_sem);
614 440
615 rx_buf = devpriv->usb_rx_buf; 441 rx_buf = devpriv->usb_rx_buf;
@@ -646,16 +472,10 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
646{ 472{
647 struct vmk80xx_private *devpriv = dev->private; 473 struct vmk80xx_private *devpriv = dev->private;
648 unsigned char *rx_buf, *tx_buf; 474 unsigned char *rx_buf, *tx_buf;
649 int dir, reg, cmd; 475 int reg, cmd;
650 int retval; 476 int retval;
651 477
652 dir = 0;
653
654 if (data[0])
655 dir |= DIR_OUT;
656
657 if (devpriv->model == VMK8061_MODEL) { 478 if (devpriv->model == VMK8061_MODEL) {
658 dir |= DIR_IN;
659 reg = VMK8061_DO_REG; 479 reg = VMK8061_DO_REG;
660 cmd = VMK8061_CMD_DO; 480 cmd = VMK8061_CMD_DO;
661 } else { /* VMK8055_MODEL */ 481 } else { /* VMK8055_MODEL */
@@ -663,10 +483,6 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
663 cmd = VMK8055_CMD_WRT_AD; 483 cmd = VMK8055_CMD_WRT_AD;
664 } 484 }
665 485
666 retval = rudimentary_check(devpriv, dir);
667 if (retval)
668 return retval;
669
670 down(&devpriv->limit_sem); 486 down(&devpriv->limit_sem);
671 487
672 rx_buf = devpriv->usb_rx_buf; 488 rx_buf = devpriv->usb_rx_buf;
@@ -712,10 +528,6 @@ static int vmk80xx_cnt_insn_read(struct comedi_device *dev,
712 int reg[2]; 528 int reg[2];
713 int n; 529 int n;
714 530
715 n = rudimentary_check(devpriv, DIR_IN);
716 if (n)
717 return n;
718
719 down(&devpriv->limit_sem); 531 down(&devpriv->limit_sem);
720 chan = CR_CHAN(insn->chanspec); 532 chan = CR_CHAN(insn->chanspec);
721 533
@@ -762,10 +574,6 @@ static int vmk80xx_cnt_insn_config(struct comedi_device *dev,
762 int reg; 574 int reg;
763 int n; 575 int n;
764 576
765 n = rudimentary_check(devpriv, DIR_OUT);
766 if (n)
767 return n;
768
769 insn_cmd = data[0]; 577 insn_cmd = data[0];
770 if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET) 578 if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET)
771 return -EINVAL; 579 return -EINVAL;
@@ -809,10 +617,6 @@ static int vmk80xx_cnt_insn_write(struct comedi_device *dev,
809 int cmd; 617 int cmd;
810 int n; 618 int n;
811 619
812 n = rudimentary_check(devpriv, DIR_OUT);
813 if (n)
814 return n;
815
816 down(&devpriv->limit_sem); 620 down(&devpriv->limit_sem);
817 chan = CR_CHAN(insn->chanspec); 621 chan = CR_CHAN(insn->chanspec);
818 622
@@ -856,10 +660,6 @@ static int vmk80xx_pwm_insn_read(struct comedi_device *dev,
856 int reg[2]; 660 int reg[2];
857 int n; 661 int n;
858 662
859 n = rudimentary_check(devpriv, DIR_IN);
860 if (n)
861 return n;
862
863 down(&devpriv->limit_sem); 663 down(&devpriv->limit_sem);
864 664
865 tx_buf = devpriv->usb_tx_buf; 665 tx_buf = devpriv->usb_tx_buf;
@@ -893,10 +693,6 @@ static int vmk80xx_pwm_insn_write(struct comedi_device *dev,
893 int cmd; 693 int cmd;
894 int n; 694 int n;
895 695
896 n = rudimentary_check(devpriv, DIR_OUT);
897 if (n)
898 return n;
899
900 down(&devpriv->limit_sem); 696 down(&devpriv->limit_sem);
901 697
902 tx_buf = devpriv->usb_tx_buf; 698 tx_buf = devpriv->usb_tx_buf;
@@ -1106,11 +902,6 @@ static int vmk80xx_auto_attach(struct comedi_device *dev,
1106 return ret; 902 return ret;
1107 903
1108 sema_init(&devpriv->limit_sem, 8); 904 sema_init(&devpriv->limit_sem, 8);
1109 init_waitqueue_head(&devpriv->read_wait);
1110 init_waitqueue_head(&devpriv->write_wait);
1111
1112 init_usb_anchor(&devpriv->rx_anchor);
1113 init_usb_anchor(&devpriv->tx_anchor);
1114 905
1115 usb_set_intfdata(intf, devpriv); 906 usb_set_intfdata(intf, devpriv);
1116 907
@@ -1141,9 +932,6 @@ static void vmk80xx_detach(struct comedi_device *dev)
1141 932
1142 usb_set_intfdata(devpriv->intf, NULL); 933 usb_set_intfdata(devpriv->intf, NULL);
1143 934
1144 usb_kill_anchored_urbs(&devpriv->rx_anchor);
1145 usb_kill_anchored_urbs(&devpriv->tx_anchor);
1146
1147 kfree(devpriv->usb_rx_buf); 935 kfree(devpriv->usb_rx_buf);
1148 kfree(devpriv->usb_tx_buf); 936 kfree(devpriv->usb_tx_buf);
1149 937