aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c36
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h2
2 files changed, 25 insertions, 13 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index bf1de04dc9f..ccdf81ebc4f 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -411,7 +411,7 @@ static void int_urb_complete(struct urb *urb)
411 case -ENOENT: 411 case -ENOENT:
412 case -ECONNRESET: 412 case -ECONNRESET:
413 case -EPIPE: 413 case -EPIPE:
414 goto kfree; 414 return;
415 default: 415 default:
416 goto resubmit; 416 goto resubmit;
417 } 417 }
@@ -443,12 +443,11 @@ static void int_urb_complete(struct urb *urb)
443resubmit: 443resubmit:
444 r = usb_submit_urb(urb, GFP_ATOMIC); 444 r = usb_submit_urb(urb, GFP_ATOMIC);
445 if (r) { 445 if (r) {
446 dev_dbg_f(urb_dev(urb), "resubmit urb %p\n", urb); 446 dev_dbg_f(urb_dev(urb), "error: resubmit urb %p err code %d\n",
447 goto kfree; 447 urb, r);
448 /* TODO: add worker to reset intr->urb */
448 } 449 }
449 return; 450 return;
450kfree:
451 kfree(urb->transfer_buffer);
452} 451}
453 452
454static inline int int_urb_interval(struct usb_device *udev) 453static inline int int_urb_interval(struct usb_device *udev)
@@ -479,9 +478,8 @@ static inline int usb_int_enabled(struct zd_usb *usb)
479int zd_usb_enable_int(struct zd_usb *usb) 478int zd_usb_enable_int(struct zd_usb *usb)
480{ 479{
481 int r; 480 int r;
482 struct usb_device *udev; 481 struct usb_device *udev = zd_usb_to_usbdev(usb);
483 struct zd_usb_interrupt *intr = &usb->intr; 482 struct zd_usb_interrupt *intr = &usb->intr;
484 void *transfer_buffer = NULL;
485 struct urb *urb; 483 struct urb *urb;
486 484
487 dev_dbg_f(zd_usb_dev(usb), "\n"); 485 dev_dbg_f(zd_usb_dev(usb), "\n");
@@ -502,20 +500,21 @@ int zd_usb_enable_int(struct zd_usb *usb)
502 intr->urb = urb; 500 intr->urb = urb;
503 spin_unlock_irq(&intr->lock); 501 spin_unlock_irq(&intr->lock);
504 502
505 /* TODO: make it a DMA buffer */
506 r = -ENOMEM; 503 r = -ENOMEM;
507 transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_KERNEL); 504 intr->buffer = usb_alloc_coherent(udev, USB_MAX_EP_INT_BUFFER,
508 if (!transfer_buffer) { 505 GFP_KERNEL, &intr->buffer_dma);
506 if (!intr->buffer) {
509 dev_dbg_f(zd_usb_dev(usb), 507 dev_dbg_f(zd_usb_dev(usb),
510 "couldn't allocate transfer_buffer\n"); 508 "couldn't allocate transfer_buffer\n");
511 goto error_set_urb_null; 509 goto error_set_urb_null;
512 } 510 }
513 511
514 udev = zd_usb_to_usbdev(usb);
515 usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN), 512 usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN),
516 transfer_buffer, USB_MAX_EP_INT_BUFFER, 513 intr->buffer, USB_MAX_EP_INT_BUFFER,
517 int_urb_complete, usb, 514 int_urb_complete, usb,
518 intr->interval); 515 intr->interval);
516 urb->transfer_dma = intr->buffer_dma;
517 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
519 518
520 dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb); 519 dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb);
521 r = usb_submit_urb(urb, GFP_KERNEL); 520 r = usb_submit_urb(urb, GFP_KERNEL);
@@ -527,7 +526,8 @@ int zd_usb_enable_int(struct zd_usb *usb)
527 526
528 return 0; 527 return 0;
529error: 528error:
530 kfree(transfer_buffer); 529 usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER,
530 intr->buffer, intr->buffer_dma);
531error_set_urb_null: 531error_set_urb_null:
532 spin_lock_irq(&intr->lock); 532 spin_lock_irq(&intr->lock);
533 intr->urb = NULL; 533 intr->urb = NULL;
@@ -541,8 +541,11 @@ out:
541void zd_usb_disable_int(struct zd_usb *usb) 541void zd_usb_disable_int(struct zd_usb *usb)
542{ 542{
543 unsigned long flags; 543 unsigned long flags;
544 struct usb_device *udev = zd_usb_to_usbdev(usb);
544 struct zd_usb_interrupt *intr = &usb->intr; 545 struct zd_usb_interrupt *intr = &usb->intr;
545 struct urb *urb; 546 struct urb *urb;
547 void *buffer;
548 dma_addr_t buffer_dma;
546 549
547 spin_lock_irqsave(&intr->lock, flags); 550 spin_lock_irqsave(&intr->lock, flags);
548 urb = intr->urb; 551 urb = intr->urb;
@@ -551,11 +554,18 @@ void zd_usb_disable_int(struct zd_usb *usb)
551 return; 554 return;
552 } 555 }
553 intr->urb = NULL; 556 intr->urb = NULL;
557 buffer = intr->buffer;
558 buffer_dma = intr->buffer_dma;
559 intr->buffer = NULL;
554 spin_unlock_irqrestore(&intr->lock, flags); 560 spin_unlock_irqrestore(&intr->lock, flags);
555 561
556 usb_kill_urb(urb); 562 usb_kill_urb(urb);
557 dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb); 563 dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb);
558 usb_free_urb(urb); 564 usb_free_urb(urb);
565
566 if (buffer)
567 usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER,
568 buffer, buffer_dma);
559} 569}
560 570
561static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, 571static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 2ed48ae3e60..24db0dd6842 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -162,6 +162,8 @@ struct zd_usb_interrupt {
162 struct read_regs_int read_regs; 162 struct read_regs_int read_regs;
163 spinlock_t lock; 163 spinlock_t lock;
164 struct urb *urb; 164 struct urb *urb;
165 void *buffer;
166 dma_addr_t buffer_dma;
165 int interval; 167 int interval;
166 u8 read_regs_enabled:1; 168 u8 read_regs_enabled:1;
167}; 169};