summaryrefslogtreecommitdiff
path: root/xpp/xpp_usb.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-10-03 17:05:16 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-10-03 17:05:16 +0000
commitb789eafda708e700c733aee4195b586192b642c2 (patch)
tree45bd8579c07519502395c72d33446f51a3829cb0 /xpp/xpp_usb.c
parentc20d0a8f8b1229e90e4cc14fdbf98d33275c8d56 (diff)
New xpp release: r4786:
* New firmware protocol version: 2.9 . * fpga_load: initial clean-ups before interface split. * genzaptelconf: Don't leave an empty directory behind (4784) * Increase xpp poll_timeout to 1000ms - useful for CentOS 4 (r4781). * Fix initialization anoyance: if AB don't answer to polls, don't waitfor_xpds, and show no waiting XPDs (r4725). * Disable dtmf_detect by default once again (r4712). * Don't check twice for asterisk to stop. The second test was done while Asterisk was still stopping (r4708). * Support building the kernel with M= instead of with SUBDIRS= , as used in some newer build systems (r4677). Merged revisions 3105 via svnmerge from http://svn.digium.com/svn/zaptel/branches/1.2 git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3106 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xpp_usb.c')
-rw-r--r--xpp/xpp_usb.c41
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,