lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 2 Jan 2007 17:37:36 -0800
From:	Greg KH <greg@...ah.com>
To:	Rainer Weikusat <rainer.weikusat@...ag.com>
Cc:	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2.6.20-rc3] fix for bugzilla #7544 (keyspan USB-to-serial converter)

On Tue, Jan 02, 2007 at 07:16:54PM +0100, Rainer Weikusat wrote:
> At least the Keyspan USA-19HS USB-to-serial converter supports
> two different configurations, one where the input endpoints
> have interrupt transfer type and one where they are bulk endpoints.
> The default UHCI configuration uses the interrupt input endpoints.
> The keyspan driver, OTOH, assumes that the device has only bulk
> endpoints (all URBs are initialized by calling usb_fill_bulk_urb
> in keyspan.c/ keyspan_setup_urb).

So, this means that Keyspan changed the USB configuration of this
device?

Can you send me the output of 'cat /proc/bus/usb/devices' with this
keyspan device plugged in?  I'll compare it with the devices I have
here.

> This causes the interval field
> of the input URBs to have a value of zero instead of one, which
> 'accidentally' worked with Linux at least up to 2.6.17.11 but
> stopped to with 2.6.18, which changed the UHCI support code handling
> URBs for interrupt endpoints. The patch below modifies to driver to
> initialize its input URBs either as interrupt or as bulk URBs,
> depending on the transfertype contained in the associated endpoint
> descriptor (only tested with the default configuration) enabling
> the driver to again receive data from the serial converter.
> 
> Signed-off-by: Rainer Weikusat <rweikusat@...ag.com>
> ---
> diff -pNur linux-2.6.20-rc3/drivers/usb/serial/keyspan.c linux-2.6.20-rc3-keyspan/drivers/usb/serial/keyspan.c
> --- linux-2.6.20-rc3/drivers/usb/serial/keyspan.c	2007-01-02 11:10:22.000000000 +0100
> +++ linux-2.6.20-rc3-keyspan/drivers/usb/serial/keyspan.c	2007-01-02 18:54:16.000000000 +0100
> @@ -95,6 +95,7 @@
>  */
>  
>  
> +#include <linux/compiler.h>
>  #include <linux/kernel.h>
>  #include <linux/jiffies.h>
>  #include <linux/errno.h>
> @@ -1275,11 +1276,29 @@ static int keyspan_fake_startup (struct 
>  }
>  
>  /* Helper functions used by keyspan_setup_urbs */
> +static struct usb_endpoint_descriptor const *
> +find_ep_desc_for(struct usb_serial const *serial, int endpoint)
> +{
> +	struct usb_host_endpoint const *p, *e;
> +
> +	p = serial->interface->cur_altsetting->endpoint;
> +	e = p + serial->interface->cur_altsetting->desc.bNumEndpoints;
> +	while (p < e && p->desc.bEndpointAddress != endpoint) ++p;
> +	
> +	if (unlikely(p == e)) panic("found no endpoint descriptor for "
> +				    "endpoint %d\n", endpoint);

No need for "unlikely" on such a slow path.

Also, panic() should be on the next line for the proper coding style.

And, we don't want to panic() for such a trivial thing.  Just abort the
probe sequence at most, but never shut down the machine for an odd
device that we find.

> +
> +	return &p->desc;
> +}
> +
>  static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
>  				      int dir, void *ctx, char *buf, int len,
>  				      void (*callback)(struct urb *))
>  {
>  	struct urb *urb;
> +	struct usb_endpoint_descriptor const *ep_desc;
> +	char const *ep_type_name;
> +	unsigned ep_type;
>  
>  	if (endpoint == -1)
>  		return NULL;		/* endpoint not needed */
> @@ -1290,12 +1309,31 @@ static struct urb *keyspan_setup_urb (st
>  		dbg ("%s - alloc for endpoint %d failed.", __FUNCTION__, endpoint);
>  		return NULL;
>  	}
> +	
> +	ep_desc = find_ep_desc_for(serial, endpoint);
> +	ep_type = ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
> +	switch (ep_type) {
> +	case USB_ENDPOINT_XFER_INT:
> +		ep_type_name = "INT";
> +		usb_fill_int_urb(urb, serial->dev,
> +				 usb_sndintpipe(serial->dev, endpoint) | dir,
> +				 buf, len, callback, ctx,
> +				 ep_desc->bInterval);
> +		break;
> +
> +	case USB_ENDPOINT_XFER_BULK:
> +		ep_type_name = "BULK";
> +		usb_fill_bulk_urb(urb, serial->dev,
> +				  usb_sndbulkpipe(serial->dev, endpoint) | dir,
> +				  buf, len, callback, ctx);
> +		break;
>  
> -		/* Fill URB using supplied data. */
> -	usb_fill_bulk_urb(urb, serial->dev,
> -		      usb_sndbulkpipe(serial->dev, endpoint) | dir,
> -		      buf, len, callback, ctx);
> +	default:
> +		panic("unsupported endpoint type %d", ep_type);

Again, no usb driver should be calling panic().

thanks,

greg k-h
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ