usbatm xusbatm.c,1.7,1.8

kagan at infradead.org kagan at infradead.org
Thu Apr 21 11:19:14 EDT 2005


Update of /home/cvs/usbatm
In directory phoenix.infradead.org:/tmp/cvs-serv21550

Modified Files:
	xusbatm.c 
Log Message:
Replace the stupid logic I introduced in the previous commit, showing my
complete ignorance of how USB works, with a more decent one, as per suggestion
by Duncan.


Index: xusbatm.c
===================================================================
RCS file: /home/cvs/usbatm/xusbatm.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- xusbatm.c	21 Apr 2005 12:45:29 -0000	1.7
+++ xusbatm.c	21 Apr 2005 15:19:11 -0000	1.8
@@ -37,8 +37,6 @@
 XUSBATM_PARM(vendor, unsigned short, ushort, "USB device vendor");
 XUSBATM_PARM(product, unsigned short, ushort, "USB device product");
 
-XUSBATM_PARM(rx_intf, unsigned char, byte, "rx interface number (default 0)");
-XUSBATM_PARM(tx_intf, unsigned char, byte, "tx interface number (default 0)");
 XUSBATM_PARM(rx_endpoint, unsigned char, byte, "rx endpoint number");
 XUSBATM_PARM(tx_endpoint, unsigned char, byte, "tx endpoint number");
 XUSBATM_PARM(rx_padding, unsigned char, byte, "rx padding (default 0)");
@@ -50,60 +48,62 @@
 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)
+{
+	struct usb_host_interface *alt = intf->altsetting;
+	u8 i, n_eps = alt->desc.bNumEndpoints;
+
+	for (i = 0; i < n_eps; i++)
+		if ((alt->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) == ep)
+			return 1;
+	return 0;
+}
+
 static int xusbatm_bind(struct usbatm_data *usbatm_instance,
 			struct usb_interface *intf, const struct usb_device_id *id,
 			int *need_heavy_init)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
-	struct usb_interface *rx_if, *tx_if;
-	unsigned long drv_ix = id - xusbatm_usb_ids;
+	int drv_ix = id - xusbatm_usb_ids;
 	int ifnum = intf->altsetting->desc.bInterfaceNumber;
-	int ret;
+	const int num_ifs = usb_dev->actconfig->desc.bNumInterfaces;
+	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];
+	struct usb_interface *cur_if;
+	int i, ret;
 
 	usb_dbg(usbatm_instance, "%s: binding driver %d: vendor %#x product %#x"
-		" rx: intf %d ep %#x padd %d tx: intf %d ep %#x padd %d\n",
+		" rx: ep %#x padd %d tx: ep %#x padd %d\n",
 		__func__, drv_ix, vendor[drv_ix], product[drv_ix],
-		rx_intf[drv_ix], rx_endpoint[drv_ix], rx_padding[drv_ix],
-		tx_intf[drv_ix], tx_endpoint[drv_ix], tx_padding[drv_ix]);
+		rx_endpoint[drv_ix], rx_padding[drv_ix],
+		tx_endpoint[drv_ix], tx_padding[drv_ix]);
 
-	rx_if = usb_ifnum_to_if(usb_dev, rx_intf[drv_ix]);
-	if (!rx_if) {
-		usb_err(usbatm_instance, "%s: interface #%d unavailable\n",
-			__func__, rx_intf[drv_ix]);
-		return -ENODEV;
-	}
-	tx_if = usb_ifnum_to_if(usb_dev, tx_intf[drv_ix]);
-	if (!tx_if) {
-		usb_err(usbatm_instance, "%s: interface #%d unavailable\n",
-			__func__, tx_intf[drv_ix]);
+	if (!rx_ep_present && !tx_ep_present) {
+		usb_dbg(usbatm_instance, "%s: intf #%d has neither tx (%#x) nor rx (%#x) endpoint\n",
+			__func__, ifnum, rx_endpoint[drv_ix], tx_endpoint[drv_ix]);
 		return -ENODEV;
 	}
 
-	if (rx_intf[drv_ix] != ifnum) {
-		ret = usb_driver_claim_interface(&xusbatm_usb_driver,
-						 rx_if, usbatm_instance);
-		if (!ret) {
-			usb_err(usbatm_instance, "%s: failed to claim interface #%d (%d)\n",
-				__func__, rx_intf[drv_ix], ret);
-			return ret;
-		}
-	}
+	if (rx_ep_present && tx_ep_present)
+		return 0;
 
-	if (tx_intf[drv_ix] != ifnum && tx_intf[drv_ix] != rx_intf[drv_ix]) {
-		ret = usb_driver_claim_interface(&xusbatm_usb_driver,
-						 tx_if, usbatm_instance);
-		if (!ret) {
-			usb_err(usbatm_instance, "%s: failed to claim interface #%d (%d)\n",
-				__func__, tx_intf[drv_ix], ret);
-			if (rx_intf[drv_ix] != ifnum) {
-				usb_set_intfdata(rx_if, NULL);
-				usb_driver_release_interface(&xusbatm_usb_driver, rx_if);
-			}
+	for(i = 0; i < num_ifs; i++) {
+		cur_if = usb_ifnum_to_if(usb_dev, i);
+
+		if (i != ifnum && cur_if && 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__, i, ret);
 			return ret;
 		}
 	}
 
-	return 0;
+	usb_err(usbatm_instance, "%s: no interface has endpoint %#x\n",
+		__func__, searched_ep);
+	return -ENODEV;
 }
 
 static void xusbatm_unbind(struct usbatm_data *usbatm_instance,
@@ -120,7 +120,6 @@
 			usb_set_intfdata(cur_if, NULL);
 			usb_driver_release_interface(&xusbatm_usb_driver, cur_if);
 		}
-
 }
 
 static int xusbatm_atm_start(struct usbatm_data *usbatm_instance,




More information about the Usbatm-commits mailing list