netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] zd1211rw: Convert installer CDROM device into WLAN device
@ 2006-08-13 11:15 Daniel Drake
  2006-08-13 11:18 ` Michael Buesch
  0 siblings, 1 reply; 2+ messages in thread
From: Daniel Drake @ 2006-08-13 11:15 UTC (permalink / raw)
  To: linville; +Cc: kune, netdev, mb

Some devices identify themselves as a virtual USB CDROM drive. The virtual CD
includes the windows driver. We aren't interested in this, so we eject the
virtual CDROM and then the real wireless device appears.

Patch fixed over the earlier version to not leak cmd, thanks to Michael Buesch
for spotting that.

Signed-off-by: Daniel Drake <dsd@gentoo.org>

Index: linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/zd1211rw/zd_usb.c
+++ linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -46,6 +46,8 @@ static struct usb_device_id usb_ids[] = 
 	{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
+	/* "Driverless" devices that need ejecting */
+	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
 	{}
 };
 
@@ -914,6 +916,55 @@ static void print_id(struct usb_device *
 #define print_id(udev) do { } while (0)
 #endif
 
+static int eject_installer(struct usb_interface *intf)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_host_interface *iface_desc = &intf->altsetting[0];
+	struct usb_endpoint_descriptor *endpoint;
+	unsigned char *cmd;
+	u8 bulk_out_ep;
+	int r;
+
+	/* Find bulk out endpoint */
+	endpoint = &iface_desc->endpoint[1].desc;
+	if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT &&
+	    (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+	    USB_ENDPOINT_XFER_BULK) {
+		bulk_out_ep = endpoint->bEndpointAddress;
+	} else {
+		dev_err(&udev->dev,
+			"zd1211rw: Could not find bulk out endpoint\n");
+		return -ENODEV;
+	}
+
+	cmd = kzalloc(31, GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENODEV;
+
+	/* USB bulk command block */
+	cmd[0] = 0x55;	/* bulk command signature */
+	cmd[1] = 0x53;	/* bulk command signature */
+	cmd[2] = 0x42;	/* bulk command signature */
+	cmd[3] = 0x43;	/* bulk command signature */
+	cmd[14] = 6;	/* command length */
+
+	cmd[15] = 0x1b;	/* SCSI command: START STOP UNIT */
+	cmd[19] = 0x2;	/* eject disc */
+
+	dev_info(&udev->dev, "Ejecting virtual installer media...\n");
+	r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
+		cmd, 31, NULL, 2000);
+	kfree(cmd);
+	if (r)
+		return r;
+
+	/* At this point, the device disconnects and reconnects with the real
+	 * ID numbers. */
+
+	usb_set_intfdata(intf, NULL);
+	return 0;
+}
+
 static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	int r;
@@ -922,6 +973,9 @@ static int probe(struct usb_interface *i
 
 	print_id(udev);
 
+	if (id->driver_info & DEVICE_INSTALLER)
+		return eject_installer(intf);
+
 	switch (udev->speed) {
 	case USB_SPEED_LOW:
 	case USB_SPEED_FULL:
@@ -987,6 +1041,11 @@ static void disconnect(struct usb_interf
 	struct zd_mac *mac = zd_netdev_mac(netdev);
 	struct zd_usb *usb = &mac->chip.usb;
 
+	/* Either something really bad happened, or we're just dealing with
+	 * a DEVICE_INSTALLER. */
+	if (netdev == NULL)
+		return;
+
 	dev_dbg_f(zd_usb_dev(usb), "\n");
 
 	zd_netdev_disconnect(netdev);
Index: linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.h
===================================================================
--- linux-2.6.orig/drivers/net/wireless/zd1211rw/zd_usb.h
+++ linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -30,6 +30,7 @@
 enum devicetype {
 	DEVICE_ZD1211  = 0,
 	DEVICE_ZD1211B = 1,
+	DEVICE_INSTALLER = 2,
 };
 
 enum endpoints {

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] zd1211rw: Convert installer CDROM device into WLAN device
  2006-08-13 11:15 [PATCH v2] zd1211rw: Convert installer CDROM device into WLAN device Daniel Drake
@ 2006-08-13 11:18 ` Michael Buesch
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Buesch @ 2006-08-13 11:18 UTC (permalink / raw)
  To: Daniel Drake; +Cc: linville, kune, netdev

On Sunday 13 August 2006 13:15, Daniel Drake wrote:
> Some devices identify themselves as a virtual USB CDROM drive. The virtual CD
> includes the windows driver. We aren't interested in this, so we eject the
> virtual CDROM and then the real wireless device appears.
> 
> Patch fixed over the earlier version to not leak cmd, thanks to Michael Buesch
> for spotting that.
> 
> Signed-off-by: Daniel Drake <dsd@gentoo.org>

This one should be ok.

Acked-by: Michael Buesch <mb@bu3sch.de>

> Index: linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.c
> ===================================================================
> --- linux-2.6.orig/drivers/net/wireless/zd1211rw/zd_usb.c
> +++ linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.c
> @@ -46,6 +46,8 @@ static struct usb_device_id usb_ids[] = 
>  	{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
>  	{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
>  	{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
> +	/* "Driverless" devices that need ejecting */
> +	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
>  	{}
>  };
>  
> @@ -914,6 +916,55 @@ static void print_id(struct usb_device *
>  #define print_id(udev) do { } while (0)
>  #endif
>  
> +static int eject_installer(struct usb_interface *intf)
> +{
> +	struct usb_device *udev = interface_to_usbdev(intf);
> +	struct usb_host_interface *iface_desc = &intf->altsetting[0];
> +	struct usb_endpoint_descriptor *endpoint;
> +	unsigned char *cmd;
> +	u8 bulk_out_ep;
> +	int r;
> +
> +	/* Find bulk out endpoint */
> +	endpoint = &iface_desc->endpoint[1].desc;
> +	if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT &&
> +	    (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
> +	    USB_ENDPOINT_XFER_BULK) {
> +		bulk_out_ep = endpoint->bEndpointAddress;
> +	} else {
> +		dev_err(&udev->dev,
> +			"zd1211rw: Could not find bulk out endpoint\n");
> +		return -ENODEV;
> +	}
> +
> +	cmd = kzalloc(31, GFP_KERNEL);
> +	if (cmd == NULL)
> +		return -ENODEV;
> +
> +	/* USB bulk command block */
> +	cmd[0] = 0x55;	/* bulk command signature */
> +	cmd[1] = 0x53;	/* bulk command signature */
> +	cmd[2] = 0x42;	/* bulk command signature */
> +	cmd[3] = 0x43;	/* bulk command signature */
> +	cmd[14] = 6;	/* command length */
> +
> +	cmd[15] = 0x1b;	/* SCSI command: START STOP UNIT */
> +	cmd[19] = 0x2;	/* eject disc */
> +
> +	dev_info(&udev->dev, "Ejecting virtual installer media...\n");
> +	r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
> +		cmd, 31, NULL, 2000);
> +	kfree(cmd);
> +	if (r)
> +		return r;
> +
> +	/* At this point, the device disconnects and reconnects with the real
> +	 * ID numbers. */
> +
> +	usb_set_intfdata(intf, NULL);
> +	return 0;
> +}
> +
>  static int probe(struct usb_interface *intf, const struct usb_device_id *id)
>  {
>  	int r;
> @@ -922,6 +973,9 @@ static int probe(struct usb_interface *i
>  
>  	print_id(udev);
>  
> +	if (id->driver_info & DEVICE_INSTALLER)
> +		return eject_installer(intf);
> +
>  	switch (udev->speed) {
>  	case USB_SPEED_LOW:
>  	case USB_SPEED_FULL:
> @@ -987,6 +1041,11 @@ static void disconnect(struct usb_interf
>  	struct zd_mac *mac = zd_netdev_mac(netdev);
>  	struct zd_usb *usb = &mac->chip.usb;
>  
> +	/* Either something really bad happened, or we're just dealing with
> +	 * a DEVICE_INSTALLER. */
> +	if (netdev == NULL)
> +		return;
> +
>  	dev_dbg_f(zd_usb_dev(usb), "\n");
>  
>  	zd_netdev_disconnect(netdev);
> Index: linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.h
> ===================================================================
> --- linux-2.6.orig/drivers/net/wireless/zd1211rw/zd_usb.h
> +++ linux-2.6/drivers/net/wireless/zd1211rw/zd_usb.h
> @@ -30,6 +30,7 @@
>  enum devicetype {
>  	DEVICE_ZD1211  = 0,
>  	DEVICE_ZD1211B = 1,
> +	DEVICE_INSTALLER = 2,
>  };
>  
>  enum endpoints {
> 

-- 
Greetings Michael.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-08-13 11:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-13 11:15 [PATCH v2] zd1211rw: Convert installer CDROM device into WLAN device Daniel Drake
2006-08-13 11:18 ` Michael Buesch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).