speedtch Makefile, 1.12, 1.13 cxacru2.c, 1.3, 1.4 usbatm.h, 1.5, 1.6 usbatm2.c, 1.15, 1.16

Duncan Sands duncan at infradead.org
Fri Jan 28 09:58:20 EST 2005


Update of /home/cvs/speedtch
In directory phoenix.infradead.org:/tmp/cvs-serv17792

Modified Files:
	Makefile cxacru2.c usbatm.h usbatm2.c 
Log Message:
New registration model, basically Roman's patch plus control over USB probing
given to the minidrivers.  Hopefully Matthieu will like it :)  It works like
this (actually, since I haven't tested it, maybe it doesn't work at all):

minidrivers register a struct usbatm_driver with usbatm, and register a
struct usb_driver with usb.  Most minidrivers should be happy with letting
usbatm do all the work: they can just use the usbatm probe and disconnect
methods:

...
        .probe          = usbatm_usb_probe,
        .disconnect     = usbatm_usb_disconnect,
...

However, if a driver needs extra flexibility it can use its own methods:

...
	.probe		= matthieu_usb_probe,
	.disconnect	= matthieu_usb_disconnect
...

It is OK to register minidrivers in the probe method, so matthieu_usb_probe
etc could be:

int matthieu_usb_probe(...) {
	...query the device, find the best driver to use...
	if ((ret = usbatm_register(best_driver)) < 0)
		return ret;
	if ((ret = usbatm_usb_probe(intf, id)) < 0) {
		usbatm_deregister(best_driver);
		return ret;
	}
	return 0;
}

void matthieu_usb_disconnect(...) {
	...

	best_driver = instance->driver;
	usbatm_disconnect(intf);
	usbatm_deregister(best_driver);
}


Index: Makefile
===================================================================
RCS file: /home/cvs/speedtch/Makefile,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Makefile	28 Jan 2005 12:31:24 -0000	1.12
+++ Makefile	28 Jan 2005 14:58:17 -0000	1.13
@@ -5,7 +5,7 @@
 FIRMWARE_EXTRACTOR := firmware
 
 #obj-m := cxacru.o speedtch.o usb_atm.o usbatm2.o speedtch2.o cxacru2.o
-obj-m := cxacru.o usb_atm.o usbatm2.o cxacru2.o
+obj-m := cxacru2.o usbatm2.o
 
 all help modules modules_install:
 	$(MAKE) -C $(KERNELDIR) M=$(PWD) $(filter-out all,$(MAKECMDGOALS)) EXTRA_CFLAGS=-DDEBUG

Index: cxacru2.c
===================================================================
RCS file: /home/cvs/speedtch/cxacru2.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- cxacru2.c	27 Jan 2005 08:35:51 -0000	1.3
+++ cxacru2.c	28 Jan 2005 14:58:17 -0000	1.4
@@ -776,58 +776,46 @@
 	usbatm_instance->driver_data = NULL;
 }
 
-static struct usbatm_driver cxacru_driver;
-
 static const struct usb_device_id cxacru_usb_ids[] = {
 	{
 		/* V = Conexant				P = ADSL modem (Euphrates project)	*/
 		USB_DEVICE(0x0572, 0xcafe),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Conexant				P = ADSL modem (Hasbani project)	*/
 		USB_DEVICE(0x0572, 0xcb00),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Conexant				P = ADSL modem				*/
 		USB_DEVICE(0x0572, 0xcb01),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Conexant				P = ADSL modem				*/
 		USB_DEVICE(0x0572, 0xcb06),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Olitec				P = ADSL modem version 2		*/
 		USB_DEVICE(0x08e3, 0x0100),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Olitec				P = ADSL modem version 3		*/
 		USB_DEVICE(0x08e3, 0x0102),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Trust/Amigo Technology Co.	P = AMX-CA86U				*/
 		USB_DEVICE(0x0eb0, 0x3457),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Zoom				P = 5510				*/
 		USB_DEVICE(0x1803, 0x5510),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Draytek				P = Vigor 318				*/
 		USB_DEVICE(0x0675, 0x0200),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{
 		/* V = Zyxel				P = 630-C1 aka OMNI ADSL USB modem	*/
 		USB_DEVICE(0x0586, 0x330a),
-		.driver_info = (unsigned long) &cxacru_driver
 	},
 	{}
 };
@@ -848,13 +836,32 @@
 	.tx_padding	= 11,
 };
 
+static struct usb_driver cxacru_usb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= cxacru_driver_name,
+	.probe		= usbatm_usb_probe,
+	.disconnect	= usbatm_usb_disconnect,
+	.id_table	= cxacru_usb_ids
+};
+
 static int __init cxacru_init(void)
 {
-	return usbatm_register(&cxacru_driver);
+	int ret;
+
+	if ((ret = usbatm_register(&cxacru_driver)))
+		return ret;
+
+	if ((ret = usb_register(&cxacru_usb_driver))) {
+		usbatm_deregister(&cxacru_driver);
+		return ret;
+	}
+
+	return 0;
 }
 
 static void __exit cxacru_cleanup(void)
 {
+	usb_deregister(&cxacru_usb_driver);
 	usbatm_deregister(&cxacru_driver);
 }
 

Index: usbatm.h
===================================================================
RCS file: /home/cvs/speedtch/usbatm.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- usbatm.h	28 Jan 2005 12:11:04 -0000	1.5
+++ usbatm.h	28 Jan 2005 14:58:17 -0000	1.6
@@ -24,12 +24,13 @@
 #ifndef	_USBATM_H_
 #define	_USBATM_H_
 
+#include <asm/semaphore.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/completion.h>
 #include <linux/config.h>
 #include <linux/list.h>
 #include <linux/kref.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <asm/semaphore.h>
 
 /*
 #define DEBUG
@@ -90,11 +91,14 @@
 	unsigned tx_padding;
 
 	/* private */
-	struct usb_driver usb;
+	struct list_head driver_list;
 };
 
-int usbatm_register (struct usbatm_driver *driver);
-void usbatm_deregister (struct usbatm_driver *driver);
+extern int usbatm_register(struct usbatm_driver *driver);
+extern void usbatm_deregister(struct usbatm_driver *driver);
+
+extern int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
+extern void usbatm_usb_disconnect(struct usb_interface *intf);
 
 
 /* usbatm */

Index: usbatm2.c
===================================================================
RCS file: /home/cvs/speedtch/usbatm2.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- usbatm2.c	28 Jan 2005 12:31:24 -0000	1.15
+++ usbatm2.c	28 Jan 2005 14:58:17 -0000	1.16
@@ -207,6 +207,13 @@
 	.owner		= THIS_MODULE,
 };
 
+
+/* mini drivers */
+
+static DECLARE_MUTEX(usbatm_driver_sem);
+static LIST_HEAD(usbatm_driver_list);
+
+
 /***********
 **  misc  **
 ***********/
@@ -1033,10 +1040,10 @@
 	return 0;
 }
 
-static int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
+int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
-	struct usbatm_driver *driver = (struct usbatm_driver *) id->driver_info;
+	struct usbatm_driver *driver = NULL, *candidate;
 	struct usbatm_data *instance;
 	char *buf;
 	int error = -ENOMEM;
@@ -1046,13 +1053,21 @@
 
 	dev_dbg(&intf->dev, "trying device with vendor=0x%x, product=0x%x, ifnum %d\n", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
 
+	down(&usbatm_driver_sem);
+	list_for_each_entry(candidate, &usbatm_driver_list, driver_list)
+		if (usb_match_id(intf, candidate->id_table)) {
+			driver = candidate;
+			break;
+		}
+
 	if (!driver) {
-		dev_dbg(&intf->dev, "blacklisted by %s\n", usbatm_driver_name);
+		up(&usbatm_driver_sem);
 		return -ENODEV;
 	}
 
 	/* instance init */
 	if (!(instance = kmalloc(sizeof(*instance), GFP_KERNEL))) {
+		up(&usbatm_driver_sem);
 		dev_dbg(&intf->dev, "no memory for instance data!\n");
 		return -ENOMEM;
 	}
@@ -1110,8 +1125,7 @@
 	}
 
 	for (i = 0; i < num_rcv_bufs; i++) {
-		struct udsl_receive_buffer *buf =
-		    &(instance->receive_buffers[i]);
+		struct udsl_receive_buffer *buf = &(instance->receive_buffers[i]);
 
 		buf->base = kmalloc(rcv_buf_size * (ATM_CELL_SIZE + instance->rx_padding),
 				    GFP_KERNEL);
@@ -1177,6 +1191,8 @@
 	if (driver->bind && (error = driver->bind(instance, intf, &need_heavy)) < 0)
 			goto fail;
 
+	up(&usbatm_driver_sem);
+
 	if (need_heavy && driver->heavy_init)
 		error = usbatm_heavy_init(instance);
 	else {
@@ -1185,15 +1201,18 @@
 	}
 
 	if (error)
-		goto fail;
+		goto fail_nosem;
 
 	usb_get_dev(dev);
-	udsl_get_instance(instance);	/* dropped in usbatm_disconnect */
+	udsl_get_instance(instance);	/* dropped in usbatm_usb_disconnect */
 	usb_set_intfdata(intf, instance);
 
 	return 0;
 
  fail:
+	up(&usbatm_driver_sem);
+
+ fail_nosem:
 	for (i = 0; i < num_snd_bufs; i++)
 		kfree(instance->send_buffers[i].base);
 
@@ -1210,8 +1229,9 @@
 
 	return error;
 }
+EXPORT_SYMBOL_GPL(usbatm_usb_probe);
 
-static void usbatm_disconnect(struct usb_interface *intf)
+void usbatm_usb_disconnect(struct usb_interface *intf)
 {
 	struct usbatm_data *instance = usb_get_intfdata(intf);
 	int i;
@@ -1281,6 +1301,7 @@
 
 	udsl_put_instance(instance);	/* taken in usbatm_usb_probe */
 }
+EXPORT_SYMBOL_GPL(usbatm_usb_disconnect);
 
 
 /***********
@@ -1289,21 +1310,19 @@
 
 int usbatm_register (struct usbatm_driver *driver)
 {
-	struct usb_driver *usb_driver = &driver->usb;
-
-	usb_driver->owner	= driver->owner;
-	usb_driver->name	= driver->driver_name;
-        usb_driver->probe	= usbatm_usb_probe;
-        usb_driver->disconnect	= usbatm_disconnect;
-        usb_driver->id_table	= driver->id_table;
+	down(&usbatm_driver_sem);
+	list_add(&driver->driver_list, &usbatm_driver_list);
+	up(&usbatm_driver_sem);
 
-	return usb_register(usb_driver);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(usbatm_register);
 
 void usbatm_deregister (struct usbatm_driver *driver)
 {
-	usb_deregister(&driver->usb);
+	down(&usbatm_driver_sem);
+	list_del(&driver->driver_list);
+	up(&usbatm_driver_sem);
 }
 EXPORT_SYMBOL_GPL(usbatm_deregister);
 




More information about the Usbatm-commits mailing list