Commit 4a3b0874 authored by Jussi Kivilinna's avatar Jussi Kivilinna Committed by John W. Linville

zd1211rw: change interrupt URB buffer to DMA buffer

As might lower beacon update CPU usage.
Signed-off-by: default avatarJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9bca0c3b
...@@ -411,7 +411,7 @@ static void int_urb_complete(struct urb *urb) ...@@ -411,7 +411,7 @@ static void int_urb_complete(struct urb *urb)
case -ENOENT: case -ENOENT:
case -ECONNRESET: case -ECONNRESET:
case -EPIPE: case -EPIPE:
goto kfree; return;
default: default:
goto resubmit; goto resubmit;
} }
...@@ -443,12 +443,11 @@ static void int_urb_complete(struct urb *urb) ...@@ -443,12 +443,11 @@ static void int_urb_complete(struct urb *urb)
resubmit: resubmit:
r = usb_submit_urb(urb, GFP_ATOMIC); r = usb_submit_urb(urb, GFP_ATOMIC);
if (r) { if (r) {
dev_dbg_f(urb_dev(urb), "resubmit urb %p\n", urb); dev_dbg_f(urb_dev(urb), "error: resubmit urb %p err code %d\n",
goto kfree; urb, r);
/* TODO: add worker to reset intr->urb */
} }
return; return;
kfree:
kfree(urb->transfer_buffer);
} }
static inline int int_urb_interval(struct usb_device *udev) 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,9 +478,8 @@ static inline int usb_int_enabled(struct zd_usb *usb)
int zd_usb_enable_int(struct zd_usb *usb) int zd_usb_enable_int(struct zd_usb *usb)
{ {
int r; int r;
struct usb_device *udev; struct usb_device *udev = zd_usb_to_usbdev(usb);
struct zd_usb_interrupt *intr = &usb->intr; struct zd_usb_interrupt *intr = &usb->intr;
void *transfer_buffer = NULL;
struct urb *urb; struct urb *urb;
dev_dbg_f(zd_usb_dev(usb), "\n"); dev_dbg_f(zd_usb_dev(usb), "\n");
...@@ -502,20 +500,21 @@ int zd_usb_enable_int(struct zd_usb *usb) ...@@ -502,20 +500,21 @@ int zd_usb_enable_int(struct zd_usb *usb)
intr->urb = urb; intr->urb = urb;
spin_unlock_irq(&intr->lock); spin_unlock_irq(&intr->lock);
/* TODO: make it a DMA buffer */
r = -ENOMEM; r = -ENOMEM;
transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_KERNEL); intr->buffer = usb_alloc_coherent(udev, USB_MAX_EP_INT_BUFFER,
if (!transfer_buffer) { GFP_KERNEL, &intr->buffer_dma);
if (!intr->buffer) {
dev_dbg_f(zd_usb_dev(usb), dev_dbg_f(zd_usb_dev(usb),
"couldn't allocate transfer_buffer\n"); "couldn't allocate transfer_buffer\n");
goto error_set_urb_null; goto error_set_urb_null;
} }
udev = zd_usb_to_usbdev(usb);
usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN), usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN),
transfer_buffer, USB_MAX_EP_INT_BUFFER, intr->buffer, USB_MAX_EP_INT_BUFFER,
int_urb_complete, usb, int_urb_complete, usb,
intr->interval); intr->interval);
urb->transfer_dma = intr->buffer_dma;
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb); dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb);
r = usb_submit_urb(urb, GFP_KERNEL); r = usb_submit_urb(urb, GFP_KERNEL);
...@@ -527,7 +526,8 @@ int zd_usb_enable_int(struct zd_usb *usb) ...@@ -527,7 +526,8 @@ int zd_usb_enable_int(struct zd_usb *usb)
return 0; return 0;
error: error:
kfree(transfer_buffer); usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER,
intr->buffer, intr->buffer_dma);
error_set_urb_null: error_set_urb_null:
spin_lock_irq(&intr->lock); spin_lock_irq(&intr->lock);
intr->urb = NULL; intr->urb = NULL;
...@@ -541,8 +541,11 @@ int zd_usb_enable_int(struct zd_usb *usb) ...@@ -541,8 +541,11 @@ int zd_usb_enable_int(struct zd_usb *usb)
void zd_usb_disable_int(struct zd_usb *usb) void zd_usb_disable_int(struct zd_usb *usb)
{ {
unsigned long flags; unsigned long flags;
struct usb_device *udev = zd_usb_to_usbdev(usb);
struct zd_usb_interrupt *intr = &usb->intr; struct zd_usb_interrupt *intr = &usb->intr;
struct urb *urb; struct urb *urb;
void *buffer;
dma_addr_t buffer_dma;
spin_lock_irqsave(&intr->lock, flags); spin_lock_irqsave(&intr->lock, flags);
urb = intr->urb; urb = intr->urb;
...@@ -551,11 +554,18 @@ void zd_usb_disable_int(struct zd_usb *usb) ...@@ -551,11 +554,18 @@ void zd_usb_disable_int(struct zd_usb *usb)
return; return;
} }
intr->urb = NULL; intr->urb = NULL;
buffer = intr->buffer;
buffer_dma = intr->buffer_dma;
intr->buffer = NULL;
spin_unlock_irqrestore(&intr->lock, flags); spin_unlock_irqrestore(&intr->lock, flags);
usb_kill_urb(urb); usb_kill_urb(urb);
dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb); dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb);
usb_free_urb(urb); usb_free_urb(urb);
if (buffer)
usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER,
buffer, buffer_dma);
} }
static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
......
...@@ -162,6 +162,8 @@ struct zd_usb_interrupt { ...@@ -162,6 +162,8 @@ struct zd_usb_interrupt {
struct read_regs_int read_regs; struct read_regs_int read_regs;
spinlock_t lock; spinlock_t lock;
struct urb *urb; struct urb *urb;
void *buffer;
dma_addr_t buffer_dma;
int interval; int interval;
u8 read_regs_enabled:1; u8 read_regs_enabled:1;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment