diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-01-31 13:49:24 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-04 16:29:50 -0500 |
commit | 4a3b0874a481573bfd95d54c883248b4c4622572 (patch) | |
tree | fdd649fdccfe27dfb4f861fdebb4b5dad34b2cf8 /drivers/net/wireless/zd1211rw | |
parent | 9bca0c3b540188e2beea9c2583fa16c46d209888 (diff) |
zd1211rw: change interrupt URB buffer to DMA buffer
As might lower beacon update CPU usage.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 2 |
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 bf1de04dc9f2..ccdf81ebc4f5 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) | |||
443 | resubmit: | 443 | resubmit: |
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; |
450 | kfree: | ||
451 | kfree(urb->transfer_buffer); | ||
452 | } | 451 | } |
453 | 452 | ||
454 | static inline int int_urb_interval(struct usb_device *udev) | 453 | static inline int int_urb_interval(struct usb_device *udev) |
@@ -479,9 +478,8 @@ static inline int usb_int_enabled(struct zd_usb *usb) | |||
479 | int zd_usb_enable_int(struct zd_usb *usb) | 478 | int 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; |
529 | error: | 528 | error: |
530 | kfree(transfer_buffer); | 529 | usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, |
530 | intr->buffer, intr->buffer_dma); | ||
531 | error_set_urb_null: | 531 | error_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: | |||
541 | void zd_usb_disable_int(struct zd_usb *usb) | 541 | void 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 | ||
561 | static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, | 571 | static 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 2ed48ae3e604..24db0dd68421 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 | }; |