Nobody responded to my request for help in debugging the failure of Keyspan
USB serial converter ports under FC6. So I was forced to find my own
solution. The
problem turns out to be an inappropriate configuration of the USB
communication channels (called endpoints in USB jargon). Below is a diff
listing
showing how to patch drivers/usb/serial/keyspan.c, the kernel file with the
faulty code. With these patches applied both input and output work OK.
Keyspan is using the Cypress USB interface chip. If they change their
firmware
they could change the characteristics of their endpoints and then this
code could break in the future.
115,124d114
< #define EP_IN_INT(ep) \
< (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != 0) && \
< ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == \
< USB_ENDPOINT_XFER_INT))
< #define EP_OUT_BULK(ep) \
< (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == 0) && \
< ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == \
< USB_ENDPOINT_XFER_BULK))
<
<
1293,1297d1282
< struct usb_host_interface *iface_desc;
< struct usb_endpoint_descriptor *ep_desc = NULL;
< int bNumEnd;
< int i;
<
1303,1321d1287
<
< /*
< This code added to figure out what type of urb we are
< supposed to be creating. We look through the list of endpoints
< to find the one we are dealing with and get its descriptor.
< */
<
< iface_desc = serial->interface->cur_altsetting;
< bNumEnd = iface_desc->desc.bNumEndpoints;
< for(i=0; i<bNumEnd; i++) {
< ep_desc = &iface_desc->endpoint[i].desc;
< if (ep_desc->bEndpointAddress == endpoint) break;
< }
< if (i == bNumEnd) {
< dbg("%s - invalid endpoint number %x",__FUNCTION__,
< (unsigned int)endpoint);
< return NULL;
< }
<
1329,1336c1295
< /*
< Here we fill in the urb depending on what type of endpoint
< we have. With the current keyspan firmware we have BULK OUT
< endpoints or INTERRUPT IN endpoints.
< */
<
< if(EP_OUT_BULK(ep_desc)) {
< usb_fill_bulk_urb(urb, serial->dev,
---
> usb_fill_bulk_urb(urb, serial->dev,
1339,1347d1297
< } else if(EP_IN_INT(ep_desc)) {
< usb_fill_int_urb(urb, serial->dev,
< usb_rcvintpipe(serial->dev, endpoint) | dir,
< buf, len, callback, ctx,4);
< } else {
< dbg("%s !!!! NO ENDPOINT SETUP FOR THIS ONE !!!!",__FUNCTION__);
< usb_free_urb(urb);
< return NULL;
< }
--
----------------------------------------------------------------------
Richard Stover
Detector Development Laboratory
UCO/Lick Observatory
Natural Sciences Bldg. 2, Room 160
University of California
Santa Cruz, CA 95064 USA
----------------------------------------------------------------------