diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-06-20 13:42:44 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-22 22:09:46 +0200 |
commit | c900eff30a14ecf209ee7a17a7c3c54890694ce6 (patch) | |
tree | a408e64682e04326bcb334409e0f1130f8222cde /drivers/net/wireless/zd1211rw/zd_usb.h | |
parent | zd1211rw: only update HW beacon if new beacon differs from currect (diff) | |
download | linux-c900eff30a14ecf209ee7a17a7c3c54890694ce6.tar.xz linux-c900eff30a14ecf209ee7a17a7c3c54890694ce6.zip |
zd1211rw: handle lost read-reg interrupts
Device losses read-reg interrupts. By looking at usbmon it appears that
USB_INT_ID_RETRY_FAILED can override USB_INT_ID_REGS. This causes read
command to timeout, usually under heavy TX.
Fix by retrying read registers again if USB_INT_ID_RETRY_FAILED is received
while waiting for USB_INT_ID_REGS.
However USB_INT_ID_REGS is not always lost but is received after
USB_INT_ID_RETRY_FAILED and is usually received by the retried read
command. USB_INT_ID_REGS of the retry is then left unhandled and might
be received by next read command. Handle this by ignoring previous
USB_INT_ID_REGS that doesn't match current read command request.
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/zd_usb.h')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index bf942843b733..99193b456a79 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -144,6 +144,8 @@ struct usb_int_retry_fail { struct read_regs_int { struct completion completion; + struct usb_req_read_regs *req; + unsigned int req_count; /* Stores the USB int structure and contains the USB address of the * first requested register before request. */ @@ -169,7 +171,8 @@ struct zd_usb_interrupt { void *buffer; dma_addr_t buffer_dma; int interval; - u8 read_regs_enabled:1; + atomic_t read_regs_enabled; + u8 read_regs_int_overridden:1; }; static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) |