speedtch xusbatm.c,1.15,1.16
Duncan Sands
duncan at infradead.org
Fri Nov 18 09:08:29 EST 2005
- Previous message: speedtch cxacru.c, 1.36, 1.37 speedtch.c, 1.68, 1.69 usbatm.c, 1.53,
1.54 usbatm.h, 1.25, 1.26 xusbatm.c, 1.14, 1.15
- Next message: speedtch xusbatm.c,1.16,1.17
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/speedtch
In directory phoenix.infradead.org:/tmp/cvs-serv21851
Modified Files:
xusbatm.c
Log Message:
Change the interface lookup and claiming logic, based on the fact (?) that
a given endpoint can belong to at most one interface (but perhaps in several
altsettings for that interface). Add params for choosing the altsettings.
Completely untested, but compiles. I will test later, but I though Aurelio
might like it now.
Index: xusbatm.c
===================================================================
RCS file: /home/cvs/speedtch/xusbatm.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- xusbatm.c 18 Nov 2005 10:35:04 -0000 1.15
+++ xusbatm.c 18 Nov 2005 14:08:26 -0000 1.16
@@ -41,6 +41,8 @@
XUSBATM_PARM(tx_endpoint, unsigned char, byte, "tx endpoint number");
XUSBATM_PARM(rx_padding, unsigned char, byte, "rx padding (default 0)");
XUSBATM_PARM(tx_padding, unsigned char, byte, "tx padding (default 0)");
+XUSBATM_PARM(rx_altsetting, unsigned char, byte, "rx altsetting (default 0)");
+XUSBATM_PARM(tx_altsetting, unsigned char, byte, "rx altsetting (default 0)");
static const char xusbatm_driver_name[] = "xusbatm";
@@ -48,82 +50,112 @@
static struct usb_device_id xusbatm_usb_ids[XUSBATM_DRIVERS_MAX + 1];
static struct usb_driver xusbatm_usb_driver;
-static int usb_intf_has_ep(const struct usb_interface *intf, u8 ep)
+static struct usb_interface *xusbatm_find_intf (struct usb_device *usb_dev, int altsetting, u8 ep)
{
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
int i, j;
- for (i = 0; i < intf->num_altsetting; i++) {
- struct usb_host_interface *alt = intf->altsetting;
- for (j = 0; j < alt->desc.bNumEndpoints; j++)
- if ((alt->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) == ep)
- return 1;
+ for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++)
+ if ((intf = usb_dev->actconfig->interface[i]) && (alt = usb_altnum_to_altsetting(intf, altsetting)))
+ for (j = 0; j < alt->desc.bNumEndpoints; j++)
+ if ((alt->endpoint[j].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) == ep)
+ return intf;
+ return NULL;
+}
+
+static int xusbatm_capture_intf (struct usbatm_data *usbatm, struct usb_device *usb_dev,
+ struct usb_interface *intf, int altsetting, int claim)
+{
+ int ifnum = intf->altsetting->desc.bInterfaceNumber;
+ int ret;
+
+ if (claim && !(ret = usb_driver_claim_interface(&xusbatm_usb_driver, intf, usbatm))) {
+ usb_err(usbatm, "%s: failed to claim interface %d (%d)!\n", __func__, ifnum, ret);
+ return ret;
+ }
+ if ((ret = usb_set_interface(usb_dev, ifnum, altsetting))) {
+ usb_err(usbatm, "%s: altsetting %d for interface %d failed (%d)!\n", __func__, altsetting, ifnum, ret);
+ return ret;
}
return 0;
}
-static int xusbatm_bind(struct usbatm_data *usbatm_instance,
+static void xusbatm_release_intf (struct usb_device *usb_dev, struct usb_interface *intf, int claimed)
+{
+ if (claimed) {
+ usb_set_intfdata(intf, NULL);
+ usb_driver_release_interface(&xusbatm_usb_driver, intf);
+ }
+}
+
+static int xusbatm_bind(struct usbatm_data *usbatm,
struct usb_interface *intf, const struct usb_device_id *id,
int *need_heavy_init, int *flags)
{
struct usb_device *usb_dev = interface_to_usbdev(intf);
int drv_ix = id - xusbatm_usb_ids;
- int rx_ep_present = usb_intf_has_ep(intf, rx_endpoint[drv_ix]);
- int tx_ep_present = usb_intf_has_ep(intf, tx_endpoint[drv_ix]);
- u8 searched_ep = rx_ep_present ? tx_endpoint[drv_ix] : rx_endpoint[drv_ix];
- int i, ret;
+ int rx_alt = rx_altsetting[drv_ix];
+ int tx_alt = tx_altsetting[drv_ix];
+ struct usb_interface *rx_intf = xusbatm_find_intf(usb_dev, rx_alt, rx_endpoint[drv_ix]);
+ struct usb_interface *tx_intf = xusbatm_find_intf(usb_dev, tx_alt, tx_endpoint[drv_ix]);
+ int ret;
- usb_dbg(usbatm_instance, "%s: binding driver %d: vendor %#x product %#x"
- " rx: ep %#x padd %d tx: ep %#x padd %d\n",
+ usb_dbg(usbatm, "%s: binding driver %d: vendor %#x product %#x"
+ " rx: ep %#x padd %d alt %d tx: ep %#x padd %d alt %d\n",
__func__, drv_ix, vendor[drv_ix], product[drv_ix],
- rx_endpoint[drv_ix], rx_padding[drv_ix],
- tx_endpoint[drv_ix], tx_padding[drv_ix]);
+ rx_endpoint[drv_ix], rx_padding[drv_ix], rx_alt,
+ tx_endpoint[drv_ix], tx_padding[drv_ix], tx_alt);
- if (!rx_ep_present && !tx_ep_present) {
- usb_dbg(usbatm_instance, "%s: intf #%d has neither rx (%#x) nor tx (%#x) endpoint\n",
- __func__, intf->altsetting->desc.bInterfaceNumber,
- rx_endpoint[drv_ix], tx_endpoint[drv_ix]);
+ if (!rx_intf || !tx_intf) {
+ if (!rx_intf)
+ usb_dbg(usbatm, "%s: no interface contains endpoint %#x in altsetting %d\n",
+ __func__, rx_endpoint[drv_ix] | USB_DIR_IN, rx_alt);
+ if (!tx_intf)
+ usb_dbg(usbatm, "%s: no interface contains endpoint %#x in altsetting %d\n",
+ __func__, tx_endpoint[drv_ix], tx_alt);
return -ENODEV;
}
- if (rx_ep_present && tx_ep_present)
- return 0;
+ if ((rx_intf == tx_intf) && (rx_alt != tx_alt)) {
+ usb_err(usbatm, "%s: altsettings clash on interface %d (%d/%d)!\n", __func__,
+ rx_intf->altsetting->desc.bInterfaceNumber, rx_alt, tx_alt);
+ return -EINVAL;
+ }
- for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) {
- struct usb_interface *cur_if = usb_dev->actconfig->interface[i];
+ if (!(ret = xusbatm_capture_intf(usbatm, usb_dev, rx_intf, rx_alt, rx_intf != intf)))
+ return ret;
- if (cur_if != intf && usb_intf_has_ep(cur_if, searched_ep)) {
- ret = usb_driver_claim_interface(&xusbatm_usb_driver,
- cur_if, usbatm_instance);
- if (!ret)
- usb_err(usbatm_instance, "%s: failed to claim interface #%d (%d)\n",
- __func__, cur_if->altsetting->desc.bInterfaceNumber, ret);
- return ret;
- }
+ if (!(ret = xusbatm_capture_intf(usbatm, usb_dev, tx_intf, tx_alt, tx_intf != intf))) {
+ xusbatm_release_intf(usb_dev, rx_intf, rx_intf != intf);
+ return ret;
}
- usb_err(usbatm_instance, "%s: no interface has endpoint %#x\n",
- __func__, searched_ep);
- return -ENODEV;
+ return 0;
}
-static void xusbatm_unbind(struct usbatm_data *usbatm_instance,
+static void xusbatm_unbind(struct usbatm_data *usbatm,
struct usb_interface *intf)
{
struct usb_device *usb_dev = interface_to_usbdev(intf);
int i;
- usb_dbg(usbatm_instance, "%s entered\n", __func__);
+
+ usb_dbg(usbatm, "%s entered\n", __func__);
for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) {
- struct usb_interface *cur_if = usb_dev->actconfig->interface[i];
- usb_set_intfdata(cur_if, NULL);
- usb_driver_release_interface(&xusbatm_usb_driver, cur_if);
+ struct usb_interface *cur_intf = usb_dev->actconfig->interface[i];
+
+ if (cur_intf && (usb_get_intfdata(cur_intf) == usbatm)) {
+ usb_set_intfdata(cur_intf, NULL);
+ usb_driver_release_interface(&xusbatm_usb_driver, cur_intf);
+ }
}
}
-static int xusbatm_atm_start(struct usbatm_data *usbatm_instance,
+static int xusbatm_atm_start(struct usbatm_data *usbatm,
struct atm_dev *atm_dev)
{
- atm_dbg(usbatm_instance, "%s entered\n", __func__);
+ atm_dbg(usbatm, "%s entered\n", __func__);
/* use random MAC as we've no way to get it from the device */
random_ether_addr(atm_dev->esi);
@@ -172,8 +204,8 @@
xusbatm_drivers[i].bind = xusbatm_bind;
xusbatm_drivers[i].unbind = xusbatm_unbind;
xusbatm_drivers[i].atm_start = xusbatm_atm_start;
- xusbatm_drivers[i].bulk_in = rx_endpoint[i];
- xusbatm_drivers[i].bulk_out = tx_endpoint[i];
+ xusbatm_drivers[i].bulk_in = rx_endpoint[i] & USB_ENDPOINT_NUMBER_MASK;
+ xusbatm_drivers[i].bulk_out = tx_endpoint[i] & USB_ENDPOINT_NUMBER_MASK;
xusbatm_drivers[i].rx_padding = rx_padding[i];
xusbatm_drivers[i].tx_padding = tx_padding[i];
}
- Previous message: speedtch cxacru.c, 1.36, 1.37 speedtch.c, 1.68, 1.69 usbatm.c, 1.53,
1.54 usbatm.h, 1.25, 1.26 xusbatm.c, 1.14, 1.15
- Next message: speedtch xusbatm.c,1.16,1.17
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Usbatm-commits
mailing list