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>
This commit is contained in:
parent
9bca0c3b54
commit
4a3b0874a4
2 changed files with 25 additions and 13 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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 @@ out:
|
||||||
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)
|
||||||
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 {
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue