Hello!

This is interesting bug. The device actually presents itself differently to host depending if it's running either USB 1.1 or 2.0. As I tested zd1211rw AP-mode only on USB 2.0, result was that zd1211rw expected to always see device as it seen on USB 2.0. On OHCI-host this triggers error in ohci_hcd when driver tries to communicate to device (and correct error message appears only with zd1211rw debugging enabled).


Patch attached fixes the problem.

You can get patched compat-wireless tarball from:
http://koti.mbnet.fi/axh/kernel/zd1211rw/compat-wireless-2011-05-28-zd1211rw_fix.tar.bz2

-Jussi

Quoting Jussi Kivilinna <jussi.kivili...@mbnet.fi>:

Hi,

I have reproduced the bug, happens only on ohci_hci (not ehci or
uchi). I'll start working on fix.

-Jussi

Quoting "Roh ." <rohb...@hotmail.com>:


Hi Devs,
I hope someone can shed some light on why I am seeing these errors.
When using the standard zd1211rw, mac802111 & cfg80211 drivers that
come with fedora 14 (2.6.35.13-91) i am able to run my zd1211-based
device perfectly without a glitch over a 10m UTP usb extension. I
can even run airodump-ng for days on end without a glitch (of course
no packet injection or signal level feedback).
However when I try to use the compat-wireless-2011-05-26 or
compat-wireless-2011-04-22 drivers I receive firmware timeout
errors. Please see /var/log/message output below:
Using stock Fedora 14 2.6.35.13-91 drivers: (works ok)
May 29 17:14:28 rf kernel: [ 7296.240037] usb 2-2: new full speed
USB device using ohci_hcd and address 5May 29 17:14:28 rf kernel: [
7296.417134] usb 2-2: not running at top speed; connect to a high
speed hubMay 29 17:14:28 rf kernel: [ 7296.432140] usb 2-2: New USB
device found, idVendor=07b8, idProduct=6001May 29 17:14:28 rf
kernel: [ 7296.432213] usb 2-2: New USB device strings: Mfr=16,
Product=32, SerialNumber=0May 29 17:14:28 rf kernel: [ 7296.432322]
usb 2-2: Product: USB2.0 WLANMay 29 17:14:28 rf kernel: [
7296.432379] usb 2-2: Manufacturer: wug2670May 29 17:14:29 rf
kernel: [ 7296.738492] cfg80211: Calling CRDA to update world
regulatory domainMay 29 17:14:29 rf kernel: [ 7296.995070] usb 2-2:
reset full speed USB device using ohci_hcd and address 5May 29
17:14:29 rf kernel: [ 7297.010274] cfg80211: World regulatory domain
updated:May 29 17:14:29 rf kernel: [ 7297.010346]     (start_freq -
end_freq @ bandwidth), (max_antenna_gain, max_eirp)May 29 17:14:29
rf kernel: [ 7297.010457]     (2402000 KHz - 2472000 KHz @ 40000
KHz), (300 mBi, 2000 mBm)May 29 17:14:29 rf kernel: [ 7297.010519]
  (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)May 29
17:14:29 rf kernel: [ 7297.010583]     (2474000 KHz - 2494000 KHz @
20000 KHz), (300 mBi, 2000 mBm)May 29 17:14:29 rf kernel: [
7297.010646]     (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi,
2000 mBm)May 29 17:14:29 rf kernel: [ 7297.010709]     (5735000 KHz
- 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)May 29 17:14:29 rf
kernel: [ 7297.235267] zd1211rw 2-2:1.0: phy0May 29 17:14:29 rf
kernel: [ 7297.235405] usbcore: registered new interface driver
zd1211rwMay 29 17:14:30 rf kernel: [ 7297.977792] cfg80211: Calling
CRDA for country: AUMay 29 17:14:30 rf kernel: [ 7297.999546]
cfg80211: Regulatory domain changed to country: AUMay 29 17:14:30 rf
kernel: [ 7297.999619]     (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)May 29 17:14:30 rf kernel: [
7297.999727]     (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000
mBm)May 29 17:14:30 rf kernel: [ 7297.999789]     (5170000 KHz -
5250000 KHz @ 40000 KHz), (300 mBi, 2300 mBm)May 29 17:14:30 rf
kernel: [ 7297.999852]     (5250000 KHz - 5330000 KHz @ 40000 KHz),
(300 mBi, 2300 mBm)May 29 17:14:30 rf kernel: [ 7297.999914]
(5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 mBm)May 29
17:14:31 rf kernel: [ 7298.945539] zd1211rw 2-2:1.0: firmware
version 4605May 29 17:14:31 rf kernel: [ 7299.005554] zd1211rw
2-2:1.0: zd1211 chip 07b8:6001 v4330 full 00-12-0e AL2230_RF pa0
g----May 29 17:14:31 rf kernel: [ 7299.010584] cfg80211: Calling
CRDA for country: DEMay 29 17:14:31 rf kernel: [ 7299.026125]
cfg80211: Current regulatory domain intersected:May 29 17:14:31 rf
kernel: [ 7299.026198]     (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)May 29 17:14:31 rf kernel: [
7299.026309]     (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000
mBm)May 29 17:14:31 rf kernel: [ 7299.026371]     (5170000 KHz -
5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)May 29 17:14:31 rf kernel:
[ 7299.026431]     (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A,
2000 mBm)May 29 17:14:31 rf kernel: [ 7299.071672]
ADDRCONF(NETDEV_UP): wlan0: link is not ready
Using compat-wireless-2011-04-22 (firmware upload fails):
May 29 17:09:47 rf kernel: [ 7015.122044] usb 2-2: new full speed
USB device using ohci_hcd and address 4May 29 17:09:47 rf kernel: [
7015.299130] usb 2-2: not running at top speed; connect to a high
speed hubMay 29 17:09:47 rf kernel: [ 7015.314138] usb 2-2: New USB
device found, idVendor=07b8, idProduct=6001May 29 17:09:47 rf
kernel: [ 7015.314210] usb 2-2: New USB device strings: Mfr=16,
Product=32, SerialNumber=0May 29 17:09:47 rf kernel: [ 7015.314317]
usb 2-2: Product: USB2.0 WLANMay 29 17:09:47 rf kernel: [
7015.314374] usb 2-2: Manufacturer: wug2670May 29 17:09:48 rf
kernel: [ 7015.784541] cfg80211: Calling CRDA to update world
regulatory domainMay 29 17:09:48 rf kernel: [ 7016.323803] cfg80211:
World regulatory domain updated:May 29 17:09:48 rf kernel: [
7016.323875] cfg80211:     (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)May 29 17:09:48 rf kernel: [
7016.323988] cfg80211:     (2402000 KHz - 2472000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)May 29 17:09:48 rf kernel: [ 7016.324155]
cfg80211:     (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi,
2000 mBm)May 29 17:09:48 rf kernel: [ 7016.324269] cfg80211:
(2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)May 29
17:09:48 rf kernel: [ 7016.324378] cfg80211:     (5170000 KHz -
5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)May 29 17:09:48 rf
kernel: [ 7016.324487] cfg80211:     (5735000 KHz - 5835000 KHz @
40000 KHz), (300 mBi, 2000 mBm)May 29 17:09:48 rf kernel: [
7016.425051] usb 2-2: reset full speed USB device using ohci_hcd and
address 4May 29 17:09:48 rf kernel: [ 7016.609866] zd1211rw 2-2:1.0:
phy0May 29 17:09:48 rf kernel: [ 7016.612213] usbcore: registered
new interface driver zd1211rwMay 29 17:09:49 rf kernel: [
7017.026556] udev[8907]: renamed network interface wlan%d to
wlan0May 29 17:09:49 rf kernel: [ 7017.498004] cfg80211: Calling
CRDA for country: AUMay 29 17:09:49 rf kernel: [ 7017.539227]
cfg80211: Regulatory domain changed to country: AUMay 29 17:09:49 rf
kernel: [ 7017.539299] cfg80211:     (start_freq - end_freq @
bandwidth), (max_antenna_gain, max_eirp)May 29 17:09:49 rf kernel: [
7017.539410] cfg80211:     (2402000 KHz - 2482000 KHz @ 40000 KHz),
(N/A, 2000 mBm)May 29 17:09:49 rf kernel: [ 7017.539519] cfg80211:
  (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2300 mBm)May 29
17:09:49 rf kernel: [ 7017.539627] cfg80211:     (5250000 KHz -
5330000 KHz @ 40000 KHz), (300 mBi, 2300 mBm)May 29 17:09:49 rf
kernel: [ 7017.539736] cfg80211:     (5735000 KHz - 5835000 KHz @
40000 KHz), (300 mBi, 3000 mBm)May 29 17:09:50 rf kernel: [
7018.020584] ohci_hcd 0000:00:03.0: leak ed cb972100 (#04) state
2May 29 17:09:57 rf kernel: [ 7025.061672] usb 2-2: USB control
request for firmware upload failed. Error number -110May 29 17:09:57
rf kernel: [ 7025.061794] usb 2-2: Could not upload firmware code
uph. Error number -110May 29 17:09:57 rf kernel: [ 7025.061872]
zd1211rw 2-2:1.0: couldn't load firmware. Error number -110


There are no other usb device plugged into this pc to cause a
conflict:[root@rf ~]# lsusbBus 004 Device 001: ID 1d6b:0001 Linux
Foundation 1.1 root hubBus 003 Device 001: ID 1d6b:0001 Linux
Foundation 1.1 root hubBus 002 Device 005: ID 07b8:6001 D-Link Corp.
802.11bgBus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root
hubBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
I know I am pushing usb to its limits using a 10 meter UTP cable,
but I'm still curious as to why one driver works fine, and another
driver fails?

Thanks for any help/tips/ideas etc.
Regards,
Rohan.









------------------------------------------------------------------------------
vRanger cuts backup time in half-while increasing security.
With the market-leading solution for virtual backup and recovery,
you get blazing-fast, flexible, and affordable data protection.
Download your free trial now.
http://p.sf.net/sfu/quest-d2dcopy1
_______________________________________________
Zd1211-devs mailing list - http://zd1211.wiki.sourceforge.net/
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/zd1211-devs




zd1211rw: fix zd1211rw to work on OHCI

From: Jussi Kivilinna <jussi.kivili...@mbnet.fi>

zd1211 devices register 'EP 4 OUT' endpoint as Interrupt type on USB 2.0:

      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1

However on USB 1.1 endpoint becomes Bulk:

      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0

Commit 37939810b937aba830dd751291fcdc51cae1a6cb assumed that endpoint is
always interrupt type and changed usb_bulk_msg() calls to usb_interrupt_msg().

Problem here is that usb_bulk_msg() on interrupt endpoint selfcorrects the
call and changes requested pipe to interrupt type (see usb_bulk_msg).
However with usb_interrupt_msg() on bulk endpoint does not correct the
pipe type to bulk, but instead URB is submitted with interrupt pipe.

This causes ohci_hcd to fail submitted URB instantly with -ENOSPC and
preventing driver from working with OHCI.

Fix this by detecting endpoint type and using correct endpoint/pipe types
for URB.

Signed-off-by: Jussi Kivilinna <jussi.kivili...@mbnet.fi>
---
 drivers/net/wireless/zd1211rw/zd_usb.c |   60 ++++++++++++++++++++++++++------
 1 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 0e81994..3105ad0 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1533,6 +1533,34 @@ static void __exit usb_exit(void)
 module_init(usb_init);
 module_exit(usb_exit);
 
+static int zd_usb_bulk_intr_msg(struct usb_device *usb_dev, unsigned int pipe,
+				void *data, int len, int *actual_length,
+				int timeout)
+{
+	/* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in
+	 * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint
+	 * descriptor.
+	 *
+	 * Use this function in place of usb_bulk_msg()/usb_interrupt_msg()
+	 * for EP_REGS_OUT.
+	 */
+	struct usb_host_endpoint *ep;
+
+	ep = usb_pipe_endpoint(usb_dev, pipe);
+	if (!ep)
+		return -EINVAL;
+
+	if (usb_endpoint_xfer_int(&ep->desc)) {
+		pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
+		return usb_interrupt_msg(usb_dev, pipe, data, len,
+					 actual_length, timeout);
+	} else {
+		pipe = (pipe & ~(3 << 30)) | (PIPE_BULK << 30);
+		return usb_bulk_msg(usb_dev, pipe, data, len, actual_length,
+				    timeout);
+	}
+}
+
 static int usb_int_regs_length(unsigned int count)
 {
 	return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data);
@@ -1648,15 +1676,16 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
 
 	udev = zd_usb_to_usbdev(usb);
 	prepare_read_regs_int(usb);
-	r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
-			      req, req_len, &actual_req_len, 50 /* ms */);
+	r = zd_usb_bulk_intr_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+				 req, req_len, &actual_req_len, 50 /* ms */);
 	if (r) {
 		dev_dbg_f(zd_usb_dev(usb),
-			"error in usb_interrupt_msg(). Error number %d\n", r);
+			"error in zd_usb_bulk_intr_msg(). Error number %d\n",
+			r);
 		goto error;
 	}
 	if (req_len != actual_req_len) {
-		dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n"
+		dev_dbg_f(zd_usb_dev(usb), "error in zd_usb_bulk_intr_msg()\n"
 			" req_len %d != actual_req_len %d\n",
 			req_len, actual_req_len);
 		r = -EIO;
@@ -1818,9 +1847,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
 		rw->value = cpu_to_le16(ioreqs[i].value);
 	}
 
-	usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
-			 req, req_len, iowrite16v_urb_complete, usb,
-			 ep->desc.bInterval);
+	/* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode
+	 * endpoint is bulk. Select correct type URB by endpoint descriptor.
+	 */
+	if (usb_endpoint_xfer_int(&ep->desc))
+		usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
+				 req, req_len, iowrite16v_urb_complete, usb,
+				 ep->desc.bInterval);
+	else
+		usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+				  req, req_len, iowrite16v_urb_complete, usb);
+
 	urb->transfer_flags |= URB_FREE_BUFFER;
 
 	/* Submit previous URB */
@@ -1924,15 +1961,16 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
 	}
 
 	udev = zd_usb_to_usbdev(usb);
-	r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
-			      req, req_len, &actual_req_len, 50 /* ms */);
+	r = zd_usb_bulk_intr_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+				 req, req_len, &actual_req_len, 50 /* ms */);
 	if (r) {
 		dev_dbg_f(zd_usb_dev(usb),
-			"error in usb_interrupt_msg(). Error number %d\n", r);
+			"error in zd_usb_bulk_intr_msg(). Error number %d\n",
+			r);
 		goto out;
 	}
 	if (req_len != actual_req_len) {
-		dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()"
+		dev_dbg_f(zd_usb_dev(usb), "error in zd_usb_bulk_intr_msg()"
 			" req_len %d != actual_req_len %d\n",
 			req_len, actual_req_len);
 		r = -EIO;
------------------------------------------------------------------------------
vRanger cuts backup time in half-while increasing security.
With the market-leading solution for virtual backup and recovery, 
you get blazing-fast, flexible, and affordable data protection.
Download your free trial now. 
http://p.sf.net/sfu/quest-d2dcopy1
_______________________________________________
Zd1211-devs mailing list - http://zd1211.wiki.sourceforge.net/
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/zd1211-devs

Reply via email to