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