diff options
Diffstat (limited to 'xpp/xpp_usb.c')
-rw-r--r-- | xpp/xpp_usb.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/xpp/xpp_usb.c b/xpp/xpp_usb.c index 368902d..6ed7a39 100644 --- a/xpp/xpp_usb.c +++ b/xpp/xpp_usb.c @@ -24,6 +24,11 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) # warning "This module is tested only with 2.6 kernels" #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) +# undef USB_FIELDS_MISSING +#else +# define USB_FIELDS_MISSING +#endif #include <linux/kernel.h> #include <linux/errno.h> @@ -416,8 +421,9 @@ static void init_receive_tasklet(xusb_t *xusb) /*------------------------- XPP USB Bus Handling -------------------*/ -#define XUSB_MODEL(ep_in,ep_out,type,str) \ +#define XUSB_MODEL(interface, ep_in,ep_out,type,str) \ { \ + .iface_num = (interface), \ .in = { .ep_addr = (ep_in) }, \ .out = { .ep_addr = (ep_out) }, \ .bus_type = (type), \ @@ -426,11 +432,12 @@ static void init_receive_tasklet(xusb_t *xusb) static const struct xusb_model_info { const char *desc; + int iface_num; struct xusb_endpoint in; struct xusb_endpoint out; xbus_type_t bus_type; } model_table[] = { - XUSB_MODEL(0x86, 0x02, FIRMWARE_XPP, "FPGA_XPD"), + XUSB_MODEL(0, 0x86, 0x02, FIRMWARE_XPP, "FPGA_XPD"), }; /* table of devices that work with this driver */ @@ -527,17 +534,13 @@ static int check_usb1(struct usb_endpoint_descriptor *endpoint) * check out the endpoints * FIXME: Should be simplified (above 2.6.10) to use usb_dev->ep_in[0..16] and usb_dev->ep_out[0..16] */ -static int set_endpoints(xusb_t *xusb, struct usb_interface *interface, struct xusb_model_info *model_info) +static int set_endpoints(xusb_t *xusb, struct usb_host_interface *iface_desc, struct xusb_model_info *model_info) { - struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; struct xusb_endpoint *xusb_ep; int ep_addr; int i; - iface_desc = &interface->altsetting[0]; - DBG(GENERAL, "Found interface. Endpoints: %d\n", iface_desc->desc.bNumEndpoints); - #define BULK_ENDPOINT(ep) (((ep)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { @@ -585,7 +588,8 @@ static int set_endpoints(xusb_t *xusb, struct usb_interface *interface, struct x */ static int xusb_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev(interface); + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_desc = usb_altnum_to_altsetting(interface, 0); xusb_t *xusb = NULL; struct xusb_model_info *model_info = (struct xusb_model_info*)id->driver_info; struct proc_dir_entry *procsummary = NULL; @@ -597,6 +601,12 @@ static int xusb_probe(struct usb_interface *interface, const struct usb_device_i int i; DBG(GENERAL, "New XUSB device MODEL=%s bus_type=%d\n", model_info->desc, model_info->bus_type); + if(iface_desc->desc.bInterfaceNumber != model_info->iface_num) { + DBG(GENERAL, "Skip interface #%d != #%d\n", + iface_desc->desc.bInterfaceNumber, model_info->iface_num); + retval = -ENODEV; + goto probe_failed; + } /* The USB stack before 2.6.10 seems to be a bit shoddy. It seems that when being called * from the probe we may already have the lock to udev (the Usb DEVice). Thus we call @@ -631,7 +641,7 @@ static int xusb_probe(struct usb_interface *interface, const struct usb_device_i xusb->interface = interface; xusb->model_info = model_info; - if(!set_endpoints(xusb, interface, model_info)) { + if(!set_endpoints(xusb, iface_desc, model_info)) { retval = -ENODEV; goto probe_failed; } @@ -646,7 +656,10 @@ static int xusb_probe(struct usb_interface *interface, const struct usb_device_i retval = -ENOMEM; goto probe_failed; } - DBG(GENERAL, "XUSB: product=%s manufacturer=%s serial=%s\n", udev->product, udev->manufacturer, udev->serial); +#ifndef USB_FIELDS_MISSING + INFO("XUSB: manufacturer=[%s] product=[%s] serial=[%s] interface=[%s]\n", + udev->manufacturer, udev->product, udev->serial, iface_desc->string); +#endif /* allow device read, write and ioctl */ xusb->present = 1; @@ -691,6 +704,10 @@ static int xusb_probe(struct usb_interface *interface, const struct usb_device_i usb_make_path(udev, path, XBUS_DESCLEN); // May trunacte... ignore snprintf(xbus->busdesc, XBUS_DESCLEN, "%s", path); } +#ifndef USB_FIELDS_MISSING + if(udev->serial) + memcpy(xbus->serialnum, udev->serial, SERIAL_SIZE); +#endif DBG(GENERAL, "GOT XPP USB BUS #%d: %s (type=%d)\n", i, xbus->busdesc, xbus->bus_type); @@ -803,7 +820,7 @@ static void xusb_disconnect(struct usb_interface *interface) kfree(xusb); up (&disconnect_sem); - INFO("XUSB #%d now disconnected\n", minor); + DBG(GENERAL, "XUSB #%d now disconnected\n", minor); } static void xpp_send_callback(USB_PASS_CB(urb)) @@ -975,9 +992,11 @@ static int xusb_read_proc(char *page, char **start, off_t off, int count, int *e xusb->udev->bus->busnum, xusb->udev->devnum ); +#ifndef USB_FIELDS_MISSING len += sprintf(page + len, "USB: manufacturer=%s\n", xusb->udev->manufacturer); len += sprintf(page + len, "USB: product=%s\n", xusb->udev->product); len += sprintf(page + len, "USB: serial=%s\n", xusb->udev->serial); +#endif len += sprintf(page + len, "Minor: %d\n" "Model Info: Bus Type=%d (%s)\n", xusb->minor, |