* [RFC] USB driver conversion to "struct device_driver" for 2.5.31
@ 2002-08-22 20:44 Greg KH
2002-08-23 19:31 ` Greg KH
[not found] ` <20020829221339.GA5074@kroah.com>
0 siblings, 2 replies; 4+ messages in thread
From: Greg KH @ 2002-08-22 20:44 UTC (permalink / raw)
To: linux-usb-devel, linux-kernel; +Cc: Patrick Mochel
Hi all,
Here's another patch against 2.5.31 + all of the previous USB patches,
that is the next snapshot for converting the USB code to using the core
"struct device_driver" logic. The patch also includes lots of
drivers/base patches from Pat Mochel that are already in Linus's latest
BK tree, which are necessary for this patch.
Improvements over the last patch is:
- usb-serial core is converted, now all usb-serial drivers
register with the USB core and the usb-serial core.
- usb-storage driver is converted. This was easier than I
expected, once I added a helper function to the usb core for
drivers that care about the interface number they are dealing
with. Note, this is a BIG improvement over the current ifnum
code in probe() as now you can get the _correct_ ifnum of an
interface (previously the core just incremented the number,
which could be incorrect, as some recent audio devices have
proven.)
- other USB core cleanups, removing lots of unused code, and
fixing the device tree representation, along with a number of
oopses.
Comments are appreciated.
thanks,
greg k-h
diff -Nru a/Documentation/filesystems/driverfs.txt b/Documentation/filesystems/driverfs.txt
--- a/Documentation/filesystems/driverfs.txt Thu Aug 22 13:39:15 2002
+++ b/Documentation/filesystems/driverfs.txt Thu Aug 22 13:39:15 2002
@@ -165,9 +165,9 @@
order to relieve pain in declaring attributes, the subsystem should
also define a macro, like:
-#define DEVICE_ATTR(_name,_str,_mode,_show,_store) \
+#define DEVICE_ATTR(_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_name = { \
- .attr = {.name = _str, .mode = _mode }, \
+ .attr = {.name = __stringify(_name) , .mode = _mode }, \
.show = _show, \
.store = _store, \
};
@@ -252,7 +252,7 @@
Declaring:
-BUS_ATTR(_name,_str,_mode,_show,_store)
+BUS_ATTR(_name,_mode,_show,_store)
Creation/Removal:
@@ -273,7 +273,7 @@
Declaring:
-DRIVER_ATTR(_name,_str,_mode,_show,_store)
+DRIVER_ATTR(_name,_mode,_show,_store)
Creation/Removal:
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h Thu Aug 22 13:39:15 2002
+++ b/drivers/base/base.h Thu Aug 22 13:39:15 2002
@@ -9,6 +9,8 @@
extern struct device device_root;
extern spinlock_t device_lock;
+extern struct device * get_device_locked(struct device *);
+
extern int bus_add_device(struct device * dev);
extern void bus_remove_device(struct device * dev);
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c Thu Aug 22 13:39:15 2002
+++ b/drivers/base/bus.c Thu Aug 22 13:39:15 2002
@@ -16,6 +16,9 @@
static LIST_HEAD(bus_driver_list);
+#define to_dev(node) container_of(node,struct device,bus_list)
+#define to_drv(node) container_of(node,struct device_driver,bus_list)
+
/**
* bus_for_each_dev - walk list of devices and do something to each
* @bus: bus in question
@@ -26,42 +29,41 @@
* counting on devices as we touch each one.
*
* Algorithm:
- * Take the bus lock and get the first node in the list. We increment
- * the reference count and unlock the bus. If we have a device from a
- * previous iteration, we decrement the reference count.
- * After we call the callback, we get the next node in the list and loop.
- * At the end, if @dev is not null, we still have it pinned, so we need
- * to let it go.
+ * Take device_lock and get the first node in the list.
+ * Try and increment the reference count on it. If we can't, it's in the
+ * process of being removed, but that process hasn't acquired device_lock.
+ * It's still in the list, so we grab the next node and try that one.
+ * We drop the lock to call the callback.
+ * We can't decrement the reference count yet, because we need the next
+ * node in the list. So, we set @prev to point to the current device.
+ * On the next go-round, we decrement the reference count on @prev, so if
+ * it's being removed, it won't affect us.
*/
int bus_for_each_dev(struct bus_type * bus, void * data,
int (*callback)(struct device * dev, void * data))
{
- struct device * next;
- struct device * dev = NULL;
struct list_head * node;
+ struct device * prev = NULL;
int error = 0;
get_bus(bus);
- read_lock(&bus->lock);
- node = bus->devices.next;
- while (node != &bus->devices) {
- next = list_entry(node,struct device,bus_list);
- get_device(next);
- read_unlock(&bus->lock);
-
- if (dev)
- put_device(dev);
- dev = next;
- if ((error = callback(dev,data))) {
- put_device(dev);
- break;
+ spin_lock(&device_lock);
+ list_for_each(node,&bus->devices) {
+ struct device * dev = get_device_locked(to_dev(node));
+ if (dev) {
+ spin_unlock(&device_lock);
+ error = callback(dev,data);
+ if (prev)
+ put_device(prev);
+ prev = dev;
+ spin_lock(&device_lock);
+ if (error)
+ break;
}
- read_lock(&bus->lock);
- node = dev->bus_list.next;
}
- read_unlock(&bus->lock);
- if (dev)
- put_device(dev);
+ spin_unlock(&device_lock);
+ if (prev)
+ put_device(prev);
put_bus(bus);
return error;
}
@@ -69,34 +71,30 @@
int bus_for_each_drv(struct bus_type * bus, void * data,
int (*callback)(struct device_driver * drv, void * data))
{
- struct device_driver * next;
- struct device_driver * drv = NULL;
struct list_head * node;
+ struct device_driver * prev = NULL;
int error = 0;
/* pin bus in memory */
get_bus(bus);
- read_lock(&bus->lock);
- node = bus->drivers.next;
- while (node != &bus->drivers) {
- next = list_entry(node,struct device_driver,bus_list);
- get_driver(next);
- read_unlock(&bus->lock);
-
- if (drv)
- put_driver(drv);
- drv = next;
- if ((error = callback(drv,data))) {
- put_driver(drv);
- break;
+ spin_lock(&device_lock);
+ list_for_each(node,&bus->drivers) {
+ struct device_driver * drv = get_driver(to_drv(node));
+ if (drv) {
+ spin_unlock(&device_lock);
+ error = callback(drv,data);
+ if (prev)
+ put_driver(prev);
+ prev = drv;
+ spin_lock(&device_lock);
+ if (error)
+ break;
}
- read_lock(&bus->lock);
- node = drv->bus_list.next;
}
- read_unlock(&bus->lock);
- if (drv)
- put_driver(drv);
+ spin_unlock(&device_lock);
+ if (prev)
+ put_driver(prev);
put_bus(bus);
return error;
}
@@ -115,9 +113,9 @@
if (dev->bus) {
pr_debug("registering %s with bus '%s'\n",dev->bus_id,dev->bus->name);
get_bus(dev->bus);
- write_lock(&dev->bus->lock);
+ spin_lock(&device_lock);
list_add_tail(&dev->bus_list,&dev->bus->devices);
- write_unlock(&dev->bus->lock);
+ spin_unlock(&device_lock);
device_bus_link(dev);
}
return 0;
@@ -134,9 +132,6 @@
{
if (dev->bus) {
device_remove_symlink(&dev->bus->device_dir,dev->bus_id);
- write_lock(&dev->bus->lock);
- list_del_init(&dev->bus_list);
- write_unlock(&dev->bus->lock);
put_bus(dev->bus);
}
}
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c Thu Aug 22 13:39:15 2002
+++ b/drivers/base/core.c Thu Aug 22 13:39:15 2002
@@ -25,6 +25,8 @@
spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
+#define to_dev(node) container_of(node,struct device,driver_list)
+
/**
* found_match - do actual binding of device to driver
@@ -53,9 +55,9 @@
pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id,drv->name);
- write_lock(&drv->lock);
+ spin_lock(&device_lock);
list_add_tail(&dev->driver_list,&drv->devices);
- write_unlock(&drv->lock);
+ spin_unlock(&device_lock);
goto Done;
@@ -101,19 +103,14 @@
struct device_driver * drv;
if (dev->driver) {
- lock_device(dev);
+ spin_lock(&device_lock);
drv = dev->driver;
dev->driver = NULL;
- unlock_device(dev);
-
- write_lock(&drv->lock);
- list_del_init(&dev->driver_list);
- write_unlock(&drv->lock);
+ spin_unlock(&device_lock);
/* detach from driver */
- if (drv->remove)
+ if (drv && drv->remove)
drv->remove(dev);
- put_driver(drv);
}
}
@@ -134,47 +131,26 @@
return bus_for_each_dev(drv->bus,drv,do_driver_attach);
}
-static int do_driver_detach(struct device * dev, struct device_driver * drv)
-{
- lock_device(dev);
- if (dev->driver == drv) {
- dev->driver = NULL;
- unlock_device(dev);
- if (drv->remove)
- drv->remove(dev);
- } else
- unlock_device(dev);
- return 0;
-}
-
void driver_detach(struct device_driver * drv)
{
- struct device * next;
- struct device * dev = NULL;
struct list_head * node;
- int error = 0;
+ struct device * prev = NULL;
- write_lock(&drv->lock);
- node = drv->devices.next;
- while (node != &drv->devices) {
- next = list_entry(node,struct device,driver_list);
- get_device(next);
- list_del_init(&next->driver_list);
- write_unlock(&drv->lock);
-
- if (dev)
- put_device(dev);
- dev = next;
- if ((error = do_driver_detach(dev,drv))) {
- put_device(dev);
- break;
+ spin_lock(&device_lock);
+ list_for_each(node,&drv->devices) {
+ struct device * dev = get_device_locked(to_dev(node));
+ if (dev) {
+ if (prev)
+ list_del_init(&prev->driver_list);
+ spin_unlock(&device_lock);
+ device_detach(dev);
+ if (prev)
+ put_device(prev);
+ prev = dev;
+ spin_lock(&device_lock);
}
- write_lock(&drv->lock);
- node = drv->devices.next;
}
- write_unlock(&drv->lock);
- if (dev)
- put_device(dev);
+ spin_unlock(&device_lock);
}
/**
@@ -191,7 +167,6 @@
int device_register(struct device *dev)
{
int error;
- struct device *prev_dev;
if (!dev || !strlen(dev->bus_id))
return -EINVAL;
@@ -199,24 +174,21 @@
INIT_LIST_HEAD(&dev->node);
INIT_LIST_HEAD(&dev->children);
INIT_LIST_HEAD(&dev->g_list);
+ INIT_LIST_HEAD(&dev->driver_list);
+ INIT_LIST_HEAD(&dev->bus_list);
spin_lock_init(&dev->lock);
atomic_set(&dev->refcount,2);
- spin_lock(&device_lock);
if (dev != &device_root) {
if (!dev->parent)
dev->parent = &device_root;
get_device(dev->parent);
- if (list_empty(&dev->parent->children))
- prev_dev = dev->parent;
- else
- prev_dev = list_entry(dev->parent->children.prev, struct device, node);
- list_add(&dev->g_list, &prev_dev->g_list);
-
+ spin_lock(&device_lock);
+ list_add_tail(&dev->g_list,&dev->parent->g_list);
list_add_tail(&dev->node,&dev->parent->children);
+ spin_unlock(&device_lock);
}
- spin_unlock(&device_lock);
pr_debug("DEV: registering device: ID = '%s', name = %s\n",
dev->bus_id, dev->name);
@@ -234,12 +206,37 @@
platform_notify(dev);
register_done:
+ if (error) {
+ spin_lock(&device_lock);
+ list_del_init(&dev->g_list);
+ list_del_init(&dev->node);
+ spin_unlock(&device_lock);
+ if (dev->parent)
+ put_device(dev->parent);
+ }
put_device(dev);
- if (error && dev->parent)
- put_device(dev->parent);
return error;
}
+struct device * get_device_locked(struct device * dev)
+{
+ struct device * ret = dev;
+ if (dev && atomic_read(&dev->refcount) > 0)
+ atomic_inc(&dev->refcount);
+ else
+ ret = NULL;
+ return ret;
+}
+
+struct device * get_device(struct device * dev)
+{
+ struct device * ret;
+ spin_lock(&device_lock);
+ ret = get_device_locked(dev);
+ spin_unlock(&device_lock);
+ return ret;
+}
+
/**
* put_device - decrement reference count, and clean up when it hits 0
* @dev: device in question
@@ -250,6 +247,8 @@
return;
list_del_init(&dev->node);
list_del_init(&dev->g_list);
+ list_del_init(&dev->bus_list);
+ list_del_init(&dev->driver_list);
spin_unlock(&device_lock);
pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
@@ -296,4 +295,5 @@
core_initcall(device_init);
EXPORT_SYMBOL(device_register);
+EXPORT_SYMBOL(get_device);
EXPORT_SYMBOL(put_device);
diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c
--- a/drivers/base/driver.c Thu Aug 22 13:39:15 2002
+++ b/drivers/base/driver.c Thu Aug 22 13:39:15 2002
@@ -10,35 +10,31 @@
#include <linux/errno.h>
#include "base.h"
+#define to_dev(node) container_of(node,struct device,driver_list)
-int driver_for_each_dev(struct device_driver * drv, void * data, int (*callback)(struct device *, void * ))
+int driver_for_each_dev(struct device_driver * drv, void * data,
+ int (*callback)(struct device *, void * ))
{
- struct device * next;
- struct device * dev = NULL;
struct list_head * node;
+ struct device * prev = NULL;
int error = 0;
get_driver(drv);
- read_lock(&drv->lock);
- node = drv->devices.next;
- while (node != &drv->devices) {
- next = list_entry(node,struct device,driver_list);
- get_device(next);
- read_unlock(&drv->lock);
-
- if (dev)
- put_device(dev);
- dev = next;
- if ((error = callback(dev,data))) {
- put_device(dev);
- break;
+ spin_lock(&device_lock);
+ list_for_each(node,&drv->devices) {
+ struct device * dev = get_device_locked(to_dev(node));
+ if (dev) {
+ spin_unlock(&device_lock);
+ error = callback(dev,data);
+ if (prev)
+ put_device(prev);
+ prev = dev;
+ spin_lock(&device_lock);
+ if (error)
+ break;
}
- read_lock(&drv->lock);
- node = dev->driver_list.next;
}
- read_unlock(&drv->lock);
- if (dev)
- put_device(dev);
+ spin_unlock(&device_lock);
put_driver(drv);
return error;
}
@@ -60,9 +56,9 @@
atomic_set(&drv->refcount,2);
rwlock_init(&drv->lock);
INIT_LIST_HEAD(&drv->devices);
- write_lock(&drv->bus->lock);
+ spin_lock(&device_lock);
list_add(&drv->bus_list,&drv->bus->drivers);
- write_unlock(&drv->bus->lock);
+ spin_unlock(&device_lock);
driver_make_dir(drv);
driver_attach(drv);
put_driver(drv);
@@ -81,10 +77,10 @@
void remove_driver(struct device_driver * drv)
{
- write_lock(&drv->bus->lock);
+ spin_lock(&device_lock);
atomic_set(&drv->refcount,0);
list_del_init(&drv->bus_list);
- write_unlock(&drv->bus->lock);
+ spin_unlock(&device_lock);
__remove_driver(drv);
}
@@ -94,13 +90,10 @@
*/
void put_driver(struct device_driver * drv)
{
- write_lock(&drv->bus->lock);
- if (!atomic_dec_and_test(&drv->refcount)) {
- write_unlock(&drv->bus->lock);
+ if (!atomic_dec_and_lock(&drv->refcount,&device_lock))
return;
- }
list_del_init(&drv->bus_list);
- write_unlock(&drv->bus->lock);
+ spin_unlock(&device_lock);
__remove_driver(drv);
}
diff -Nru a/drivers/base/interface.c b/drivers/base/interface.c
--- a/drivers/base/interface.c Thu Aug 22 13:39:15 2002
+++ b/drivers/base/interface.c Thu Aug 22 13:39:15 2002
@@ -14,7 +14,7 @@
return off ? 0 : sprintf(buf,"%s\n",dev->name);
}
-static DEVICE_ATTR(name,"name",S_IRUGO,device_read_name,NULL);
+static DEVICE_ATTR(name,S_IRUGO,device_read_name,NULL);
static ssize_t
device_read_power(struct device * dev, char * page, size_t count, loff_t off)
@@ -85,7 +85,7 @@
return error < 0 ? error : count;
}
-static DEVICE_ATTR(power,"power",S_IWUSR | S_IRUGO,
+static DEVICE_ATTR(power,S_IWUSR | S_IRUGO,
device_read_power,device_write_power);
struct device_attribute * device_default_files[] = {
diff -Nru a/drivers/base/power.c b/drivers/base/power.c
--- a/drivers/base/power.c Thu Aug 22 13:39:15 2002
+++ b/drivers/base/power.c Thu Aug 22 13:39:15 2002
@@ -14,6 +14,8 @@
#include <linux/module.h>
#include "base.h"
+#define to_dev(node) container_of(node,struct device,g_list)
+
/**
* device_suspend - suspend all devices on the device tree
* @state: state we're entering
@@ -25,30 +27,26 @@
*/
int device_suspend(u32 state, u32 level)
{
- struct device * dev;
- struct device * prev = &device_root;
+ struct list_head * node;
+ struct device * prev = NULL;
int error = 0;
printk(KERN_EMERG "Suspending Devices\n");
- get_device(prev);
-
spin_lock(&device_lock);
- dev = g_list_to_dev(prev->g_list.next);
- while(dev != &device_root && !error) {
- get_device(dev);
- spin_unlock(&device_lock);
- put_device(prev);
-
- if (dev->driver && dev->driver->suspend)
- error = dev->driver->suspend(dev,state,level);
-
- spin_lock(&device_lock);
- prev = dev;
- dev = g_list_to_dev(prev->g_list.next);
+ list_for_each(node,&device_root.g_list) {
+ struct device * dev = get_device_locked(dev);
+ if (dev) {
+ spin_unlock(&device_lock);
+ if (dev->driver && dev->driver->suspend)
+ error = dev->driver->suspend(dev,state,level);
+ if (prev)
+ put_device(prev);
+ prev = dev;
+ spin_lock(&device_lock);
+ }
}
spin_unlock(&device_lock);
- put_device(prev);
return error;
}
@@ -63,27 +61,23 @@
*/
void device_resume(u32 level)
{
- struct device * dev;
- struct device * prev = &device_root;
-
- get_device(prev);
+ struct list_head * node;
+ struct device * prev = NULL;
spin_lock(&device_lock);
- dev = g_list_to_dev(prev->g_list.prev);
- while(dev != &device_root) {
- get_device(dev);
- spin_unlock(&device_lock);
- put_device(prev);
-
- if (dev->driver && dev->driver->resume)
- dev->driver->resume(dev,level);
-
- spin_lock(&device_lock);
- prev = dev;
- dev = g_list_to_dev(prev->g_list.prev);
+ list_for_each_prev(node,&device_root.g_list) {
+ struct device * dev = get_device_locked(to_dev(node));
+ if (dev) {
+ spin_unlock(&device_lock);
+ if (dev->driver && dev->driver->resume)
+ dev->driver->resume(dev,level);
+ if (prev)
+ put_device(prev);
+ prev = dev;
+ spin_lock(&device_lock);
+ }
}
spin_unlock(&device_lock);
- put_device(prev);
printk(KERN_EMERG "Devices Resumed\n");
}
@@ -98,29 +92,25 @@
*/
void device_shutdown(void)
{
- struct device * dev;
- struct device * prev = &device_root;
+ struct list_head * node;
+ struct device * prev = NULL;
printk(KERN_EMERG "Shutting down devices\n");
- get_device(prev);
-
spin_lock(&device_lock);
- dev = g_list_to_dev(prev->g_list.next);
- while(dev != &device_root) {
- get_device(dev);
- spin_unlock(&device_lock);
- put_device(prev);
-
- if (dev->driver && dev->driver->remove)
- dev->driver->remove(dev);
-
- spin_lock(&device_lock);
- prev = dev;
- dev = g_list_to_dev(prev->g_list.next);
+ list_for_each(node,&device_root.g_list) {
+ struct device * dev = get_device_locked(to_dev(node));
+ if (dev) {
+ spin_unlock(&device_lock);
+ if (dev->driver && dev->driver->remove)
+ dev->driver->remove(dev);
+ if (prev)
+ put_device(prev);
+ prev = dev;
+ spin_lock(&device_lock);
+ }
}
spin_unlock(&device_lock);
- put_device(prev);
}
EXPORT_SYMBOL(device_suspend);
diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c
--- a/drivers/pci/proc.c Thu Aug 22 13:39:15 2002
+++ b/drivers/pci/proc.c Thu Aug 22 13:39:15 2002
@@ -378,7 +378,7 @@
return off ? 0 : sprintf(buf,"%u\n",pci_dev->irq);
}
-static DEVICE_ATTR(irq,"irq",S_IRUGO,pci_show_irq,NULL);
+static DEVICE_ATTR(irq,S_IRUGO,pci_show_irq,NULL);
static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count, loff_t off)
{
@@ -402,7 +402,7 @@
return (str - buf);
}
-static DEVICE_ATTR(resource,"resource",S_IRUGO,pci_show_resources,NULL);
+static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
int pci_proc_attach_device(struct pci_dev *dev)
{
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c Thu Aug 22 13:39:15 2002
+++ b/drivers/scsi/scsi_scan.c Thu Aug 22 13:39:15 2002
@@ -305,7 +305,7 @@
return 0;
}
-static DEVICE_ATTR(type,"type",S_IRUGO,scsi_device_type_read,NULL);
+static DEVICE_ATTR(type,S_IRUGO,scsi_device_type_read,NULL);
/* end content handlers */
diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c Thu Aug 22 13:39:15 2002
+++ b/drivers/scsi/sg.c Thu Aug 22 13:39:15 2002
@@ -1401,14 +1401,14 @@
Sg_device * sdp=list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
return off ? 0 : sprintf(page, "%x\n",sdp->i_rdev.value);
}
-static DEVICE_ATTR(kdev,"kdev",S_IRUGO,sg_device_kdev_read,NULL);
+static DEVICE_ATTR(kdev,S_IRUGO,sg_device_kdev_read,NULL);
static ssize_t sg_device_type_read(struct device *driverfs_dev, char *page,
size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
-static DEVICE_ATTR(type,"type",S_IRUGO,sg_device_type_read,NULL);
+static DEVICE_ATTR(type,S_IRUGO,sg_device_type_read,NULL);
static int sg_attach(Scsi_Device * scsidp)
{
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c Thu Aug 22 13:39:15 2002
+++ b/drivers/scsi/sr.c Thu Aug 22 13:39:15 2002
@@ -737,14 +737,14 @@
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value);
}
-static DEVICE_ATTR(kdev,"kdev",S_IRUGO,sr_device_kdev_read,NULL);
+static DEVICE_ATTR(kdev,S_IRUGO,sr_device_kdev_read,NULL);
static ssize_t sr_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
-static DEVICE_ATTR(type,"type",S_IRUGO,sr_device_type_read,NULL);
+static DEVICE_ATTR(type,S_IRUGO,sr_device_type_read,NULL);
void sr_finish()
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c Thu Aug 22 13:39:15 2002
+++ b/drivers/scsi/st.c Thu Aug 22 13:39:15 2002
@@ -3533,14 +3533,14 @@
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value);
}
-static DEVICE_ATTR(kdev,"kdev",S_IRUGO,st_device_kdev_read,NULL);
+static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL);
static ssize_t st_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
-static DEVICE_ATTR(type,"type",S_IRUGO,st_device_type_read,NULL);
+static DEVICE_ATTR(type,S_IRUGO,st_device_type_read,NULL);
static struct file_operations st_fops =
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/class/audio.c Thu Aug 22 13:39:15 2002
@@ -2756,7 +2756,6 @@
.name = "audio",
.probe = usb_audio_probe,
.disconnect = usb_audio_disconnect,
- .driver_list = LIST_HEAD_INIT(usb_audio_driver.driver_list),
.id_table = usb_audio_ids,
};
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/class/usb-midi.c Thu Aug 22 13:39:15 2002
@@ -2099,7 +2099,6 @@
.probe = usb_midi_probe,
.disconnect = usb_midi_disconnect,
.id_table = NULL, /* check all devices */
- .driver_list = LIST_HEAD_INIT(usb_midi_driver.driver_list)
};
/* ------------------------------------------------------------------------- */
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/devices.c Thu Aug 22 13:39:15 2002
@@ -111,7 +111,6 @@
/*
* Need access to the driver and USB bus lists.
- * extern struct list_head usb_driver_list;
* extern struct list_head usb_bus_list;
* However, these will come from functions that return ptrs to each of them.
*/
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/devio.c Thu Aug 22 13:39:15 2002
@@ -427,30 +427,6 @@
return -ENOENT;
}
-extern struct list_head usb_driver_list;
-
-#if 0
-static int finddriver(struct usb_driver **driver, char *name)
-{
- struct list_head *tmp;
-
- tmp = usb_driver_list.next;
- while (tmp != &usb_driver_list) {
- struct usb_driver *d = list_entry(tmp, struct usb_driver,
- driver_list);
-
- if (!strcmp(d->name, name)) {
- *driver = d;
- return 0;
- }
-
- tmp = tmp->next;
- }
-
- return -EINVAL;
-}
-#endif
-
static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index)
{
int ret;
@@ -1105,7 +1081,9 @@
/* let kernel drivers try to (re)bind to the interface */
case USBDEVFS_CONNECT:
- usb_find_interface_driver (ps->dev, ifp);
+ //usb_find_interface_driver (ps->dev, ifp);
+ err ("USBDEVFS_CONNECT is no longer supported.");
+ retval = -EINVAL;
break;
/* talk directly to the interface's driver */
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/hcd.c Thu Aug 22 13:39:15 2002
@@ -722,13 +722,15 @@
{
int retval;
- usb_dev->dev.parent = parent_dev;
- strcpy (&usb_dev->dev.name[0], "usb_name");
- strcpy (&usb_dev->dev.bus_id[0], "usb_bus");
- retval = usb_new_device (usb_dev);
+// usb_dev->dev.parent = parent_dev;
+// strcpy (&usb_dev->dev.name[0], "usb_name");
+// strcpy (&usb_dev->dev.bus_id[0], "usb_bus");
+ retval = usb_new_device (usb_dev, parent_dev);
if (retval)
- put_device (&usb_dev->dev);
+ err("%s - usb_new_device failed with value %d", __FUNCTION__, retval);
+// put_device (&usb_dev->dev);
return retval;
+// return usb_new_device (usb_dev, parent_dev);
}
EXPORT_SYMBOL (usb_register_root_hub);
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/hcd.h Thu Aug 22 13:39:15 2002
@@ -255,7 +255,7 @@
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
-extern int usb_new_device(struct usb_device *dev);
+extern int usb_new_device(struct usb_device *dev, struct device *parent);
extern void usb_connect(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);
@@ -384,8 +384,6 @@
/* for probe/disconnect with correct module usage counting */
void *usb_bind_driver(struct usb_driver *driver, struct usb_interface *intf);
void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf);
-
-extern struct list_head usb_driver_list;
/*
* USB device fs stuff
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/hub.c Thu Aug 22 13:39:15 2002
@@ -175,6 +175,7 @@
while (!list_empty (&hub->tt.clear_list)) {
struct list_head *temp;
struct usb_tt_clear *clear;
+ struct usb_device *dev;
int status;
temp = hub->tt.clear_list.next;
@@ -183,13 +184,13 @@
/* drop lock so HCD can concurrently report other TT errors */
spin_unlock_irqrestore (&hub->tt.lock, flags);
- status = hub_clear_tt_buffer (hub->dev,
- clear->devinfo, clear->tt);
+ dev = interface_to_usbdev (hub->intf);
+ status = hub_clear_tt_buffer (dev, clear->devinfo, clear->tt);
spin_lock_irqsave (&hub->tt.lock, flags);
if (status)
err ("usb-%s-%s clear tt %d (%04x) error %d",
- hub->dev->bus->bus_name, hub->dev->devpath,
+ dev->bus->bus_name, dev->devpath,
clear->tt, clear->devinfo, status);
kfree (clear);
}
@@ -245,12 +246,14 @@
static void usb_hub_power_on(struct usb_hub *hub)
{
+ struct usb_device *dev;
int i;
/* Enable power to the ports */
dbg("enabling power on all ports");
+ dev = interface_to_usbdev(hub->intf);
for (i = 0; i < hub->descriptor->bNbrPorts; i++)
- usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+ usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
/* Wait for power to be enabled */
wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
@@ -259,7 +262,7 @@
static int usb_hub_configure(struct usb_hub *hub,
struct usb_endpoint_descriptor *endpoint)
{
- struct usb_device *dev = hub->dev;
+ struct usb_device *dev = interface_to_usbdev (hub->intf);
struct usb_hub_status hubstatus;
unsigned int pipe;
int maxp, ret;
@@ -425,39 +428,78 @@
return 0;
}
-static void *hub_probe(struct usb_device *dev, unsigned int i,
- const struct usb_device_id *id)
+static void hub_disconnect(struct usb_interface *intf)
{
- struct usb_interface_descriptor *interface;
+ struct usb_hub *hub = (struct usb_hub *)intf->dev.driver_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hub_event_lock, flags);
+
+ /* Delete it and then reset it */
+ list_del(&hub->event_list);
+ INIT_LIST_HEAD(&hub->event_list);
+ list_del(&hub->hub_list);
+ INIT_LIST_HEAD(&hub->hub_list);
+
+ spin_unlock_irqrestore(&hub_event_lock, flags);
+
+ down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
+ up(&hub->khubd_sem);
+
+ /* assuming we used keventd, it must quiesce too */
+ if (hub->tt.hub)
+ flush_scheduled_tasks ();
+
+ if (hub->urb) {
+ usb_unlink_urb(hub->urb);
+ usb_free_urb(hub->urb);
+ hub->urb = NULL;
+ }
+
+ if (hub->descriptor) {
+ kfree(hub->descriptor);
+ hub->descriptor = NULL;
+ }
+
+ /* Free the memory */
+ kfree(hub);
+ intf->dev.driver_data = NULL;
+}
+
+static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_interface_descriptor *desc;
struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *dev;
struct usb_hub *hub;
unsigned long flags;
- interface = &dev->actconfig->interface[i].altsetting[0];
+ desc = intf->altsetting + intf->act_altsetting;
+ dev = interface_to_usbdev(intf);
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
- if ((interface->bInterfaceSubClass != 0) &&
- (interface->bInterfaceSubClass != 1)) {
+ if ((desc->bInterfaceSubClass != 0) &&
+ (desc->bInterfaceSubClass != 1)) {
err("invalid subclass (%d) for USB hub device #%d",
- interface->bInterfaceSubClass, dev->devnum);
- return NULL;
+ desc->bInterfaceSubClass, dev->devnum);
+ return -EIO;
}
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
- if (interface->bNumEndpoints != 1) {
+ if (desc->bNumEndpoints != 1) {
err("invalid bNumEndpoints (%d) for USB hub device #%d",
- interface->bNumEndpoints, dev->devnum);
- return NULL;
+ desc->bNumEndpoints, dev->devnum);
+ return -EIO;
}
- endpoint = &interface->endpoint[0];
+ endpoint = &desc->endpoint[0];
/* Output endpoint? Curiousier and curiousier.. */
if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
err("Device #%d is hub class, but has output endpoint?",
dev->devnum);
- return NULL;
+ return -EIO;
}
/* If it's not an interrupt endpoint, we'd better punt! */
@@ -465,7 +507,7 @@
!= USB_ENDPOINT_XFER_INT) {
err("Device #%d is hub class, but endpoint is not interrupt?",
dev->devnum);
- return NULL;
+ return -EIO;
}
/* We found a hub */
@@ -474,13 +516,13 @@
hub = kmalloc(sizeof(*hub), GFP_KERNEL);
if (!hub) {
err("couldn't kmalloc hub struct");
- return NULL;
+ return -ENOMEM;
}
memset(hub, 0, sizeof(*hub));
INIT_LIST_HEAD(&hub->event_list);
- hub->dev = dev;
+ hub->intf = intf;
init_MUTEX(&hub->khubd_sem);
/* Record the new hub's existence */
@@ -489,14 +531,18 @@
list_add(&hub->hub_list, &hub_list);
spin_unlock_irqrestore(&hub_event_lock, flags);
+ intf->dev.driver_data = hub;
+
if (usb_hub_configure(hub, endpoint) >= 0) {
- strcpy (dev->actconfig->interface[i].dev.name,
- "Hub/Port Status Changes");
- return hub;
+ strcpy (intf->dev.name, "Hub/Port Status Changes");
+ return 0;
}
err("hub configuration failed for device at %s", dev->devpath);
+ hub_disconnect (intf);
+ return -ENODEV;
+#if 0
/* free hub, but first clean up its list. */
spin_lock_irqsave(&hub_event_lock, flags);
@@ -511,43 +557,7 @@
kfree(hub);
return NULL;
-}
-
-static void hub_disconnect(struct usb_device *dev, void *ptr)
-{
- struct usb_hub *hub = (struct usb_hub *)ptr;
- unsigned long flags;
-
- spin_lock_irqsave(&hub_event_lock, flags);
-
- /* Delete it and then reset it */
- list_del(&hub->event_list);
- INIT_LIST_HEAD(&hub->event_list);
- list_del(&hub->hub_list);
- INIT_LIST_HEAD(&hub->hub_list);
-
- spin_unlock_irqrestore(&hub_event_lock, flags);
-
- down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
- up(&hub->khubd_sem);
-
- /* assuming we used keventd, it must quiesce too */
- if (hub->tt.hub)
- flush_scheduled_tasks ();
-
- if (hub->urb) {
- usb_unlink_urb(hub->urb);
- usb_free_urb(hub->urb);
- hub->urb = NULL;
- }
-
- if (hub->descriptor) {
- kfree(hub->descriptor);
- hub->descriptor = NULL;
- }
-
- /* Free the memory */
- kfree(hub);
+#endif
}
static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
@@ -584,7 +594,7 @@
static int usb_hub_reset(struct usb_hub *hub)
{
- struct usb_device *dev = hub->dev;
+ struct usb_device *dev = interface_to_usbdev(hub->intf);
int i;
/* Disconnect any attached devices */
@@ -796,7 +806,7 @@
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
u16 portstatus, u16 portchange)
{
- struct usb_device *hub = hubstate->dev;
+ struct usb_device *hub = interface_to_usbdev(hubstate->intf);
struct usb_device *dev;
unsigned int delay = HUB_SHORT_RESET_TIME;
int i;
@@ -891,11 +901,15 @@
/* put the device in the global device tree. the hub port
* is the "bus_id"; hubs show in hierarchy like bridges
*/
- dev->dev.parent = &dev->parent->dev;
+// dev->dev.parent = &dev->parent->dev;
+// if (dev->parent->dev.parent)
+ dev->dev.parent = dev->parent->dev.parent->parent;
+// else
+// dev->dev.parent = &dev->parent->dev;
sprintf (&dev->dev.bus_id[0], "%d", port + 1);
/* Run it through the hoops (find a driver, etc) */
- if (!usb_new_device(dev))
+ if (!usb_new_device(dev, &hubstate->intf->dev))
goto done;
/* Free the configuration if there was an error */
@@ -940,7 +954,7 @@
tmp = hub_event_list.next;
hub = list_entry(tmp, struct usb_hub, event_list);
- dev = hub->dev;
+ dev = interface_to_usbdev(hub->intf);
list_del(tmp);
INIT_LIST_HEAD(tmp);
@@ -1080,9 +1094,9 @@
static struct usb_driver hub_driver = {
.name = "hub",
- .probe = hub_probe,
+ .new_probe = hub_probe,
.ioctl = hub_ioctl,
- .disconnect = hub_disconnect,
+ .new_disco = hub_disconnect,
.id_table = hub_id_table,
};
diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/hub.h Thu Aug 22 13:39:15 2002
@@ -170,7 +170,8 @@
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
- struct usb_device *dev; /* the "real" device */
+// struct usb_device *dev; /* the "real" device */
+ struct usb_interface *intf; /* the "real" device */
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/core/usb.c Thu Aug 22 13:39:15 2002
@@ -48,17 +48,60 @@
extern int usb_major_init(void);
extern void usb_major_cleanup(void);
-/*
- * Prototypes for the device driver probing/loading functions
- */
-static void usb_find_drivers(struct usb_device *);
-static void usb_check_support(struct usb_device *);
-/*
- * We have a per-interface "registered driver" list.
- */
-LIST_HEAD(usb_driver_list);
+static int generic_probe (struct device *dev)
+{
+ return 0;
+}
+static int generic_remove (struct device *dev)
+{
+ return 0;
+}
+static void generic_release (struct device_driver * drv)
+{
+}
+
+static struct device_driver usb_generic_driver = {
+ .name = "generic usb driver",
+ .probe = generic_probe,
+ .remove = generic_remove,
+ .release = generic_release,
+};
+
+
+static int usb_device_probe(struct device * dev)
+{
+ struct usb_interface * intf = to_usb_interface(dev);
+ struct usb_driver * driver = to_usb_driver(dev->driver);
+ const struct usb_device_id *id;
+ int error = -ENODEV;
+
+ dbg("%s", __FUNCTION__);
+
+ if (!driver->new_probe)
+ return error;
+
+ id = usb_match_id (intf, driver->id_table);
+ if (id) {
+ dbg ("%s - got id", __FUNCTION__);
+ down (&driver->serialize);
+ error = driver->new_probe (intf, id);
+ up (&driver->serialize);
+ }
+ if (!error)
+ intf->driver = driver;
+ return error;
+}
+
+static int usb_device_remove(struct device * dev)
+{
+ struct usb_interface * intf = list_entry(dev,struct usb_interface,dev);
+
+ if (intf->driver && intf->driver->new_disco)
+ intf->driver->new_disco(intf);
+ return 0;
+}
/**
* usb_register - register a USB driver
@@ -77,46 +120,26 @@
{
int retval = 0;
- info("registered new driver %s", new_driver->name);
+ new_driver->driver.name = (char *)new_driver->name;
+ new_driver->driver.bus = &usb_bus_type;
+ new_driver->driver.probe = usb_device_probe;
+ new_driver->driver.remove = usb_device_remove;
init_MUTEX(&new_driver->serialize);
- /* Add it to the list of known drivers */
- list_add_tail(&new_driver->driver_list, &usb_driver_list);
-
- usb_scan_devices();
+ retval = driver_register(&new_driver->driver);
- usbfs_update_special();
+ if (!retval) {
+ info("registered new driver %s", new_driver->name);
+ usbfs_update_special();
+ } else {
+ err("problem %d when registering driver %s",
+ retval, new_driver->name);
+ }
return retval;
}
-
-/**
- * usb_scan_devices - scans all unclaimed USB interfaces
- * Context: !in_interrupt ()
- *
- * Goes through all unclaimed USB interfaces, and offers them to all
- * registered USB drivers through the 'probe' function.
- * This will automatically be called after usb_register is called.
- * It is called by some of the subsystems layered over USB
- * after one of their subdrivers are registered.
- */
-void usb_scan_devices(void)
-{
- struct list_head *tmp;
-
- down (&usb_bus_list_lock);
- tmp = usb_bus_list.next;
- while (tmp != &usb_bus_list) {
- struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);
-
- tmp = tmp->next;
- usb_check_support(bus->root_hub);
- }
- up (&usb_bus_list_lock);
-}
-
/**
* usb_unbind_driver - disconnects a driver from a device (usbcore-internal)
* @device: usb device to be disconnected
@@ -232,43 +255,6 @@
return private;
}
-/*
- * This function is part of a depth-first search down the device tree,
- * removing any instances of a device driver.
- */
-static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev)
-{
- int i;
-
- if (!dev) {
- err("null device being purged!!!");
- return;
- }
-
- for (i=0; i<USB_MAXCHILDREN; i++)
- if (dev->children[i])
- usb_drivers_purge(driver, dev->children[i]);
-
- if (!dev->actconfig)
- return;
-
- for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
- struct usb_interface *interface = &dev->actconfig->interface[i];
-
- if (interface->driver == driver) {
- usb_unbind_driver(dev, interface);
- /* if driver->disconnect didn't release the interface */
- if (interface->driver)
- usb_driver_release_interface(driver, interface);
- /*
- * This will go through the list looking for another
- * driver that can handle the device
- */
- usb_find_interface_driver(dev, interface);
- }
- }
-}
-
/**
* usb_deregister - unregister a USB driver
* @driver: USB operations of the driver to unregister
@@ -282,25 +268,9 @@
*/
void usb_deregister(struct usb_driver *driver)
{
- struct list_head *tmp;
-
info("deregistering driver %s", driver->name);
- /*
- * first we remove the driver, to be sure it doesn't get used by
- * another thread while we are stepping through removing entries
- */
- list_del(&driver->driver_list);
-
- down (&usb_bus_list_lock);
- tmp = usb_bus_list.next;
- while (tmp != &usb_bus_list) {
- struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
-
- tmp = tmp->next;
- usb_drivers_purge(driver, bus->root_hub);
- }
- up (&usb_bus_list_lock);
+ remove_driver (&driver->driver);
usbfs_update_special();
}
@@ -333,6 +303,32 @@
}
/**
+ * usb_if_to_ifnum - get the interface number for a given interface
+ * @iface: the interface to determine the ifnum of
+ *
+ * This walks the device descriptor for the currently active configuration
+ * and returns the interface number of this specific interface, or -ENODEV.
+ *
+ * Note that configuration descriptors are not required to assign interface
+ * numbers sequentially, so that it would be incorrect to assume that
+ * the first interface in that descriptor corresponds to interface zero.
+ * This routine helps device drivers avoid such mistakes.
+ * However, you should make sure that you do the right thing with any
+ * alternate settings available for this interfaces.
+ */
+int usb_if_to_ifnum(struct usb_interface *iface)
+{
+ struct usb_device *dev = interface_to_usbdev(iface);
+ int i;
+
+ for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
+ if (iface == &dev->actconfig->interface[i])
+ return dev->actconfig->interface[i].altsetting[0].bInterfaceNumber;
+
+ return -ENODEV;
+}
+
+/**
* usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number
* @dev: the device whose current configuration is considered
* @epnum: the desired endpoint
@@ -359,34 +355,6 @@
return NULL;
}
-/*
- * This function is for doing a depth-first search for devices which
- * have support, for dynamic loading of driver modules.
- */
-static void usb_check_support(struct usb_device *dev)
-{
- int i;
-
- if (!dev) {
- err("null device being checked!!!");
- return;
- }
-
- for (i=0; i<USB_MAXCHILDREN; i++)
- if (dev->children[i])
- usb_check_support(dev->children[i]);
-
- if (!dev->actconfig)
- return;
-
- /* now we check this device */
- if (dev->devnum > 0)
- for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
- usb_find_interface_driver (dev,
- dev->actconfig->interface + i);
-}
-
-
/**
* usb_driver_claim_interface - bind a driver to an interface
* @driver: the driver to be bound
@@ -595,72 +563,25 @@
return NULL;
}
-/*
- * This entrypoint gets called for unclaimed interfaces.
- *
- * We now walk the list of registered USB drivers,
- * looking for one that will accept this interface.
- *
- * "New Style" drivers use a table describing the devices and interfaces
- * they handle. Those tables are available to user mode tools deciding
- * whether to load driver modules for a new device.
- *
- * The probe return value is changed to be a private pointer. This way
- * the drivers don't have to dig around in our structures to set the
- * private pointer if they only need one interface.
- *
- * Returns: 0 if a driver accepted the interface, -1 otherwise
- */
-int usb_find_interface_driver (
- struct usb_device *dev,
- struct usb_interface *interface
-)
+static int usb_device_match (struct device *dev, struct device_driver *drv)
{
- struct list_head *tmp;
- void *private;
- struct usb_driver *driver;
- int ifnum;
-
- down(&dev->serialize);
-
- /* FIXME It's just luck that for some devices with drivers that set
- * configuration in probe(), the interface numbers still make sense.
- * That's one of several unsafe assumptions involved in configuring
- * devices, and in binding drivers to their interfaces.
- */
- for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++)
- if (&dev->actconfig->interface [ifnum] == interface)
- break;
- BUG_ON (ifnum == dev->actconfig->bNumInterfaces);
+ struct usb_interface *intf;
+ struct usb_driver *usb_drv;
+ const struct usb_device_id *id;
- if (usb_interface_claimed(interface))
- goto out_err;
+ intf = to_usb_interface(dev);
- private = NULL;
- lock_kernel();
- for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) {
- driver = list_entry(tmp, struct usb_driver, driver_list);
- tmp = tmp->next;
-
- private = usb_bind_driver(driver, interface);
-
- /* probe() may have changed the config on us */
- interface = dev->actconfig->interface + ifnum;
-
- if (private) {
- usb_driver_claim_interface(driver, interface, private);
- up(&dev->serialize);
- unlock_kernel();
- return 0;
- }
- }
- unlock_kernel();
+ usb_drv = to_usb_driver(drv);
+ id = usb_drv->id_table;
+
+ id = usb_match_id (intf, usb_drv->id_table);
+ if (id)
+ return 1;
-out_err:
- up(&dev->serialize);
- return -1;
+ return 0;
}
+
#ifdef CONFIG_HOTPLUG
/*
@@ -814,7 +735,7 @@
return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue);
}
-static DEVICE_ATTR(config,"configuration",S_IRUGO,show_config,NULL);
+static DEVICE_ATTR(configuration,S_IRUGO,show_config,NULL);
/* interfaces have one current setting; alternates
* can have different endpoints and class info.
@@ -829,7 +750,7 @@
interface = to_usb_interface (dev);
return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting);
}
-static DEVICE_ATTR(altsetting,"altsetting",S_IRUGO,show_altsetting,NULL);
+static DEVICE_ATTR(altsetting,S_IRUGO,show_altsetting,NULL);
/* product driverfs file */
static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off)
@@ -848,7 +769,7 @@
buf[len+1] = 0;
return len+1;
}
-static DEVICE_ATTR(product,"product",S_IRUGO,show_product,NULL);
+static DEVICE_ATTR(product,S_IRUGO,show_product,NULL);
/* manufacturer driverfs file */
static ssize_t
@@ -868,7 +789,7 @@
buf[len+1] = 0;
return len+1;
}
-static DEVICE_ATTR(manufacturer,"manufacturer",S_IRUGO,show_manufacturer,NULL);
+static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL);
/* serial number driverfs file */
static ssize_t
@@ -888,72 +809,7 @@
buf[len+1] = 0;
return len+1;
}
-static DEVICE_ATTR(serial,"serial",S_IRUGO,show_serial,NULL);
-
-/*
- * This entrypoint gets called for each new device.
- *
- * All interfaces are scanned for matching drivers.
- */
-static void usb_find_drivers(struct usb_device *dev)
-{
- unsigned ifnum;
- unsigned rejected = 0;
- unsigned claimed = 0;
-
- /* FIXME should get called for each new configuration not just the
- * first one for a device. switching configs (or altsettings) should
- * undo driverfs and HCD state for the previous interfaces.
- */
- for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
- struct usb_interface *interface = &dev->actconfig->interface[ifnum];
- struct usb_interface_descriptor *desc = interface->altsetting;
-
- /* register this interface with driverfs */
- interface->dev.parent = &dev->dev;
- interface->dev.bus = &usb_bus_type;
- sprintf (&interface->dev.bus_id[0], "%s-%s:%d",
- dev->bus->bus_name, dev->devpath,
- interface->altsetting->bInterfaceNumber);
- if (!desc->iInterface
- || usb_string (dev, desc->iInterface,
- interface->dev.name,
- sizeof interface->dev.name) <= 0) {
- /* typically devices won't bother with interface
- * descriptions; this is the normal case. an
- * interface's driver might describe it better.
- * (also: iInterface is per-altsetting ...)
- */
- sprintf (&interface->dev.name[0],
- "usb-%s-%s interface %d",
- dev->bus->bus_name, dev->devpath,
- interface->altsetting->bInterfaceNumber);
- }
- device_register (&interface->dev);
- device_create_file (&interface->dev, &dev_attr_altsetting);
-
- /* if this interface hasn't already been claimed */
- if (!usb_interface_claimed(interface)) {
- if (usb_find_interface_driver(dev, interface))
- rejected++;
- else
- claimed++;
- }
- }
-
- if (rejected)
- dbg("unhandled interfaces on device");
-
- if (!claimed) {
- warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.",
- dev->devnum,
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
-#ifdef DEBUG
- usb_show_device(dev);
-#endif
- }
-}
+static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
/**
* usb_alloc_dev - allocate a usb device structure (usbcore-internal)
@@ -1271,11 +1127,12 @@
*/
#define NEW_DEVICE_RETRYS 2
#define SET_ADDRESS_RETRYS 2
-int usb_new_device(struct usb_device *dev)
+int usb_new_device(struct usb_device *dev, struct device *parent)
{
int err = 0;
int i;
int j;
+ int ifnum;
/* USB v1.1 5.5.3 */
/* We read the first 8 bytes from the device descriptor to get to */
@@ -1361,11 +1218,23 @@
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
#endif
- /* register this device in the driverfs tree */
+ /*
+ * Set the driver for the usb device to point to the "generic" driver.
+ * This prevents the main usb device from being sent to the usb bus
+ * probe function. Yes, it's a hack, but a nice one :)
+ */
+ usb_generic_driver.bus = &usb_bus_type;
+ dev->dev.parent = parent;
+ dev->dev.driver = &usb_generic_driver;
+ dev->dev.bus = &usb_bus_type;
+ sprintf (&dev->dev.bus_id[0], "%s-%s",
+ dev->bus->bus_name, dev->devpath);
err = device_register (&dev->dev);
if (err)
return err;
- device_create_file (&dev->dev, &dev_attr_config);
+
+ /* add the USB device specific driverfs files */
+ device_create_file (&dev->dev, &dev_attr_configuration);
if (dev->descriptor.iManufacturer)
device_create_file (&dev->dev, &dev_attr_manufacturer);
if (dev->descriptor.iProduct)
@@ -1373,11 +1242,38 @@
if (dev->descriptor.iSerialNumber)
device_create_file (&dev->dev, &dev_attr_serial);
- /* now that the basic setup is over, add a /proc/bus/usb entry */
- usbfs_add_device(dev);
+ /* Register all of the interfaces for this device with the driver core.
+ * Remember, interfaces get bound to drivers, not devices. */
+ for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
+ struct usb_interface *interface = &dev->actconfig->interface[ifnum];
+ struct usb_interface_descriptor *desc = interface->altsetting;
- /* find drivers willing to handle this device */
- usb_find_drivers(dev);
+ interface->dev.parent = &dev->dev;
+ interface->dev.bus = &usb_bus_type;
+ sprintf (&interface->dev.bus_id[0], "%s-%s:%d",
+ dev->bus->bus_name, dev->devpath,
+ interface->altsetting->bInterfaceNumber);
+ if (!desc->iInterface
+ || usb_string (dev, desc->iInterface,
+ interface->dev.name,
+ sizeof interface->dev.name) <= 0) {
+ /* typically devices won't bother with interface
+ * descriptions; this is the normal case. an
+ * interface's driver might describe it better.
+ * (also: iInterface is per-altsetting ...)
+ */
+ sprintf (&interface->dev.name[0],
+ "usb-%s-%s interface %d",
+ dev->bus->bus_name, dev->devpath,
+ interface->altsetting->bInterfaceNumber);
+ }
+ dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
+ device_register (&interface->dev);
+ device_create_file (&interface->dev, &dev_attr_altsetting);
+ }
+
+ /* add a /proc/bus/usb entry */
+ usbfs_add_device(dev);
/* userspace may load modules and/or configure further */
call_policy ("add", dev);
@@ -1385,7 +1281,6 @@
return 0;
}
-
/**
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP
* @dev: device the buffer will be used with
@@ -1532,20 +1427,9 @@
: USB_DIR_OUT);
}
-#ifdef CONFIG_PROC_FS
-struct list_head *usb_driver_get_list(void)
-{
- return &usb_driver_list;
-}
-
-struct list_head *usb_bus_get_list(void)
-{
- return &usb_bus_list;
-}
-#endif
-
struct bus_type usb_bus_type = {
- .name = "usb",
+ .name = "usb",
+ .match = usb_device_match,
};
/*
@@ -1584,7 +1468,9 @@
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
-EXPORT_SYMBOL(usb_scan_devices);
+//EXPORT_SYMBOL(usb_scan_devices);
+
+EXPORT_SYMBOL(usb_if_to_ifnum);
EXPORT_SYMBOL(usb_alloc_dev);
EXPORT_SYMBOL(usb_free_dev);
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/host/ehci-dbg.c Thu Aug 22 13:39:15 2002
@@ -252,7 +252,7 @@
return count - size;
}
-static DEVICE_ATTR (async, "sched-async", S_IRUSR, show_async, NULL);
+static DEVICE_ATTR (async, S_IRUSR, show_async, NULL);
#define DBG_SCHED_LIMIT 64
@@ -360,7 +360,7 @@
return count - size;
}
-static DEVICE_ATTR (periodic, "sched-periodic", S_IRUSR, show_periodic, NULL);
+static DEVICE_ATTR (periodic, S_IRUSR, show_periodic, NULL);
#undef DBG_SCHED_LIMIT
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/input/hid-core.c Thu Aug 22 13:39:15 2002
@@ -1338,9 +1338,10 @@
{ 0, 0 }
};
-static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
+static struct hid_device *usb_hid_configure(struct usb_interface *intf)
{
- struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
+ struct usb_interface_descriptor *interface = intf->altsetting + intf->act_altsetting;
+ struct usb_device *dev = interface_to_usbdev (intf);
struct hid_descriptor *hdesc;
struct hid_device *hid;
unsigned quirks = 0, rsize = 0;
@@ -1450,7 +1451,7 @@
snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
usb_make_path(dev, buf, 64);
- snprintf(hid->phys, 64, "%s/input%d", buf, ifnum);
+ snprintf(hid->phys, 64, "%s/input%d", buf, intf->altsetting[0].bInterfaceNumber);
if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
hid->uniq[0] = 0;
@@ -1472,9 +1473,9 @@
return NULL;
}
-static void hid_disconnect(struct usb_device *dev, void *ptr)
+static void hid_disconnect(struct usb_interface *intf)
{
- struct hid_device *hid = ptr;
+ struct hid_device *hid = intf->dev.driver_data;
usb_unlink_urb(hid->urbin);
usb_unlink_urb(hid->urbout);
@@ -1491,20 +1492,20 @@
usb_free_urb(hid->urbout);
hid_free_device(hid);
+ intf->dev.driver_data = NULL;
}
-static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
+static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id)
{
struct hid_device *hid;
char path[64];
int i;
char *c;
- dbg("HID probe called for ifnum %d", ifnum);
+ dbg("HID probe called for ifnum %d", intf->ifnum);
- if (!(hid = usb_hid_configure(dev, ifnum)))
- return NULL;
+ if (!(hid = usb_hid_configure(intf)))
+ return -EIO;
hid_init_reports(hid);
hid_dump_device(hid);
@@ -1516,9 +1517,11 @@
if (!hiddev_connect(hid))
hid->claimed |= HID_CLAIMED_HIDDEV;
+ intf->dev.driver_data = hid;
+
if (!hid->claimed) {
- hid_disconnect(dev, hid);
- return NULL;
+ hid_disconnect(intf);
+ return -EIO;
}
printk(KERN_INFO);
@@ -1540,12 +1543,12 @@
}
}
- usb_make_path(dev, path, 63);
+ usb_make_path(interface_to_usbdev(intf), path, 63);
printk(": USB HID v%x.%02x %s [%s] on %s\n",
hid->version >> 8, hid->version & 0xff, c, hid->name, path);
- return hid;
+ return 0;
}
static struct usb_device_id hid_usb_ids [] = {
@@ -1558,8 +1561,8 @@
static struct usb_driver hid_driver = {
.name = "hid",
- .probe = hid_probe,
- .disconnect = hid_disconnect,
+ .new_probe = hid_probe,
+ .new_disco = hid_disconnect,
.id_table = hid_usb_ids,
};
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
--- a/drivers/usb/serial/belkin_sa.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/belkin_sa.c Thu Aug 22 13:39:15 2002
@@ -114,6 +114,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver belkin_driver = {
+ .name = "belkin",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
/* All of the device info needed for the serial converters */
static struct usb_serial_device_type belkin_device = {
.owner = THIS_MODULE,
@@ -526,6 +533,7 @@
static int __init belkin_sa_init (void)
{
usb_serial_register (&belkin_device);
+ usb_register (&belkin_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -533,6 +541,7 @@
static void __exit belkin_sa_exit (void)
{
+ usb_deregister (&belkin_driver);
usb_serial_deregister (&belkin_device);
}
diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/cyberjack.c Thu Aug 22 13:39:15 2002
@@ -73,6 +73,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver cyberjack_driver = {
+ .name = "cyberjack",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static struct usb_serial_device_type cyberjack_device = {
.owner = THIS_MODULE,
.name = "Reiner SCT Cyberjack USB card reader",
@@ -461,6 +468,7 @@
static int __init cyberjack_init (void)
{
usb_serial_register (&cyberjack_device);
+ usb_register (&cyberjack_driver);
info(DRIVER_VERSION " " DRIVER_AUTHOR);
info(DRIVER_DESC);
@@ -470,6 +478,7 @@
static void __exit cyberjack_exit (void)
{
+ usb_deregister (&cyberjack_driver);
usb_serial_deregister (&cyberjack_device);
}
diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
--- a/drivers/usb/serial/digi_acceleport.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/digi_acceleport.c Thu Aug 22 13:39:15 2002
@@ -477,7 +477,7 @@
/* Statics */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
{ } /* Terminating entry */
@@ -495,6 +495,14 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver digi_driver = {
+ .name = "digi_acceleport",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
+
/* device info needed for the Digi serial converter */
static struct usb_serial_device_type digi_acceleport_2_device = {
@@ -2026,6 +2034,7 @@
{
usb_serial_register (&digi_acceleport_2_device);
usb_serial_register (&digi_acceleport_4_device);
+ usb_register (&digi_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -2033,6 +2042,7 @@
static void __exit digi_exit (void)
{
+ usb_deregister (&digi_driver);
usb_serial_deregister (&digi_acceleport_2_device);
usb_serial_deregister (&digi_acceleport_4_device);
}
diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
--- a/drivers/usb/serial/empeg.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/empeg.c Thu Aug 22 13:39:15 2002
@@ -110,6 +110,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver empeg_driver = {
+ .name = "empeg",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static struct usb_serial_device_type empeg_device = {
.owner = THIS_MODULE,
.name = "Empeg",
@@ -550,8 +557,6 @@
struct urb *urb;
int i;
- usb_serial_register (&empeg_device);
-
/* create our write urb pool and transfer buffers */
spin_lock_init (&write_urb_pool_lock);
for (i = 0; i < NUM_URBS; ++i) {
@@ -570,10 +575,12 @@
}
}
+ usb_serial_register (&empeg_device);
+ usb_register (&empeg_driver);
+
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
-
}
@@ -582,6 +589,7 @@
int i;
unsigned long flags;
+ usb_register (&empeg_driver);
usb_serial_deregister (&empeg_device);
spin_lock_irqsave (&write_urb_pool_lock, flags);
@@ -599,7 +607,6 @@
}
spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
}
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/ftdi_sio.c Thu Aug 22 13:39:15 2002
@@ -140,7 +140,7 @@
};
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
@@ -149,6 +149,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver ftdi_driver = {
+ .name = "ftdi_sio",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
struct ftdi_private {
enum ftdi_type ftdi_type;
@@ -944,6 +951,7 @@
dbg(__FUNCTION__);
usb_serial_register (&ftdi_sio_device);
usb_serial_register (&ftdi_8U232AM_device);
+ usb_register (&ftdi_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -952,6 +960,7 @@
static void __exit ftdi_sio_exit (void)
{
dbg(__FUNCTION__);
+ usb_deregister (&ftdi_driver);
usb_serial_deregister (&ftdi_sio_device);
usb_serial_deregister (&ftdi_8U232AM_device);
}
diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
--- a/drivers/usb/serial/io_edgeport.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/io_edgeport.c Thu Aug 22 13:39:15 2002
@@ -457,6 +457,12 @@
#include "io_tables.h" /* all of the devices that this driver supports */
+static struct usb_driver io_driver = {
+ .name = "io_edgeport",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
/* function prototypes for all of our local functions */
static int process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength);
@@ -3049,6 +3055,7 @@
usb_serial_register (&edgeport_2port_device);
usb_serial_register (&edgeport_4port_device);
usb_serial_register (&edgeport_8port_device);
+ usb_register (&io_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -3061,6 +3068,7 @@
****************************************************************************/
void __exit edgeport_exit (void)
{
+ usb_deregister (&io_driver);
usb_serial_deregister (&edgeport_1port_device);
usb_serial_deregister (&edgeport_2port_device);
usb_serial_deregister (&edgeport_4port_device);
diff -Nru a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
--- a/drivers/usb/serial/io_tables.h Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/io_tables.h Thu Aug 22 13:39:15 2002
@@ -61,7 +61,7 @@
};
/* Devices that this driver supports */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) },
diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
--- a/drivers/usb/serial/io_ti.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/io_ti.c Thu Aug 22 13:39:15 2002
@@ -142,7 +142,7 @@
};
/* Devices that this driver supports */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) },
@@ -161,6 +161,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver io_driver = {
+ .name = "io_ti",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion;
@@ -2658,12 +2665,14 @@
{
usb_serial_register (&edgeport_1port_device);
usb_serial_register (&edgeport_2port_device);
+ usb_register (&io_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
static void __exit edgeport_exit (void)
{
+ usb_deregister (&io_driver);
usb_serial_deregister (&edgeport_1port_device);
usb_serial_deregister (&edgeport_2port_device);
}
diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/ipaq.c Thu Aug 22 13:39:15 2002
@@ -94,6 +94,14 @@
MODULE_DEVICE_TABLE (usb, ipaq_id_table);
+static struct usb_driver ipaq_driver = {
+ .name = "ipaq",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = ipaq_id_table,
+};
+
+
/* All of the device info needed for the Compaq iPAQ */
struct usb_serial_device_type ipaq_device = {
.owner = THIS_MODULE,
@@ -516,6 +524,7 @@
static int __init ipaq_init(void)
{
usb_serial_register(&ipaq_device);
+ usb_register(&ipaq_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -524,6 +533,7 @@
static void __exit ipaq_exit(void)
{
+ usb_deregister(&ipaq_driver);
usb_serial_deregister(&ipaq_device);
}
diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
--- a/drivers/usb/serial/ir-usb.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/ir-usb.c Thu Aug 22 13:39:15 2002
@@ -129,6 +129,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver ir_driver = {
+ .name = "ir-usb",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
struct usb_serial_device_type ir_device = {
.owner = THIS_MODULE,
@@ -606,6 +613,7 @@
static int __init ir_init (void)
{
usb_serial_register (&ir_device);
+ usb_register (&ir_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -613,6 +621,7 @@
static void __exit ir_exit (void)
{
+ usb_deregister (&ir_driver);
usb_serial_deregister (&ir_device);
}
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/keyspan.c Thu Aug 22 13:39:15 2002
@@ -183,6 +183,7 @@
usb_serial_register (&keyspan_1port_device);
usb_serial_register (&keyspan_2port_device);
usb_serial_register (&keyspan_4port_device);
+ usb_register (&keyspan_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
@@ -191,6 +192,7 @@
static void __exit keyspan_exit (void)
{
+ usb_deregister (&keyspan_driver);
usb_serial_deregister (&keyspan_pre_device);
usb_serial_deregister (&keyspan_1port_device);
usb_serial_deregister (&keyspan_2port_device);
diff -Nru a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
--- a/drivers/usb/serial/keyspan.h Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/keyspan.h Thu Aug 22 13:39:15 2002
@@ -408,7 +408,7 @@
NULL,
};
-static __devinitdata struct usb_device_id keyspan_ids_combined[] = {
+static struct usb_device_id keyspan_ids_combined[] = {
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
@@ -433,6 +433,13 @@
};
MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
+
+static struct usb_driver keyspan_driver = {
+ .name = "keyspan",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = keyspan_ids_combined,
+};
/* usb_device_id table for the pre-firmware download keyspan devices */
static struct usb_device_id keyspan_pre_ids[] = {
diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
--- a/drivers/usb/serial/keyspan_pda.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/keyspan_pda.c Thu Aug 22 13:39:15 2002
@@ -140,7 +140,7 @@
#define ENTREGRA_VENDOR_ID 0x1645
#define ENTREGRA_FAKE_ID 0x8093
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
#ifdef KEYSPAN
{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
#endif
@@ -154,6 +154,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver keyspan_pda_driver = {
+ .name = "keyspan_pda",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
static struct usb_device_id id_table_std [] = {
{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
{ } /* Terminating entry */
@@ -862,6 +869,7 @@
#ifdef XIRCOM
usb_serial_register (&xircom_pgs_fake_device);
#endif
+ usb_register (&keyspan_pda_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -869,6 +877,7 @@
static void __exit keyspan_pda_exit (void)
{
+ usb_deregister (&keyspan_pda_driver);
usb_serial_deregister (&keyspan_pda_device);
#ifdef KEYSPAN
usb_serial_deregister (&keyspan_pda_fake_device);
diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
--- a/drivers/usb/serial/kl5kusb105.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/kl5kusb105.c Thu Aug 22 13:39:15 2002
@@ -117,6 +117,12 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver kl5kusb105d_driver = {
+ .name = "kl5kusb105d",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
static struct usb_serial_device_type kl5kusb105d_device = {
.owner = THIS_MODULE,
@@ -1013,6 +1019,7 @@
static int __init klsi_105_init (void)
{
usb_serial_register (&kl5kusb105d_device);
+ usb_register (&kl5kusb105d_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -1021,6 +1028,7 @@
static void __exit klsi_105_exit (void)
{
+ usb_deregister (&kl5kusb105d_driver);
usb_serial_deregister (&kl5kusb105d_device);
}
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/mct_u232.c Thu Aug 22 13:39:15 2002
@@ -139,6 +139,12 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver mct_u232_driver = {
+ .name = "mct_u232",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
static struct usb_serial_device_type mct_u232_device = {
.owner = THIS_MODULE,
@@ -783,6 +789,7 @@
static int __init mct_u232_init (void)
{
usb_serial_register (&mct_u232_device);
+ usb_register (&mct_u232_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -790,6 +797,7 @@
static void __exit mct_u232_exit (void)
{
+ usb_deregister (&mct_u232_driver);
usb_serial_deregister (&mct_u232_device);
}
diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
--- a/drivers/usb/serial/omninet.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/omninet.c Thu Aug 22 13:39:15 2002
@@ -83,6 +83,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver omninet_driver = {
+ .name = "omninet",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static struct usb_serial_device_type zyxel_omninet_device = {
.owner = THIS_MODULE,
@@ -370,6 +377,7 @@
static int __init omninet_init (void)
{
usb_serial_register (&zyxel_omninet_device);
+ usb_register (&omninet_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -377,6 +385,7 @@
static void __exit omninet_exit (void)
{
+ usb_deregister (&omninet_driver);
usb_serial_deregister (&zyxel_omninet_device);
}
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/pl2303.c Thu Aug 22 13:39:15 2002
@@ -77,6 +77,12 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver pl2303_driver = {
+ .name = "pl2303",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
#define SET_LINE_REQUEST_TYPE 0x21
#define SET_LINE_REQUEST 0x20
@@ -708,6 +714,7 @@
static int __init pl2303_init (void)
{
usb_serial_register (&pl2303_device);
+ usb_register (&pl2303_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -715,6 +722,7 @@
static void __exit pl2303_exit (void)
{
+ usb_deregister (&pl2303_driver);
usb_serial_deregister (&pl2303_device);
}
diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
--- a/drivers/usb/serial/safe_serial.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/safe_serial.c Thu Aug 22 13:39:15 2002
@@ -161,6 +161,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver safe_driver = {
+ .name = "safe_serial",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static __u16 crc10_table[256] = {
0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
@@ -434,12 +441,14 @@
}
usb_serial_register (&safe_device);
+ usb_register (&safe_driver);
return 0;
}
static void __exit safe_exit (void)
{
+ usb_deregister (&safe_driver);
usb_serial_deregister (&safe_device);
}
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/usb-serial.h Thu Aug 22 13:39:15 2002
@@ -233,6 +233,9 @@
extern int usb_serial_register(struct usb_serial_device_type *new_device);
extern void usb_serial_deregister(struct usb_serial_device_type *device);
+extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
+extern void usb_serial_disconnect(struct usb_interface *iface);
+
/* determine if we should include the EzUSB loader functions */
#undef USES_EZUSB_FUNCTIONS
#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/usbserial.c Thu Aug 22 13:39:15 2002
@@ -380,30 +380,23 @@
.num_ports = 1,
.shutdown = generic_shutdown,
};
-#endif
-
-/* local function prototypes */
-static int serial_open (struct tty_struct *tty, struct file * filp);
-static void serial_close (struct tty_struct *tty, struct file * filp);
-static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count);
-static int serial_write_room (struct tty_struct *tty);
-static int serial_chars_in_buffer (struct tty_struct *tty);
-static void serial_throttle (struct tty_struct * tty);
-static void serial_unthrottle (struct tty_struct * tty);
-static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
-static void serial_set_termios (struct tty_struct *tty, struct termios * old);
-static void serial_shutdown (struct usb_serial *serial);
-
-static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id);
-static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
+/* we want to look at all devices, as the vendor/product id can change
+ * depending on the command line argument */
+static struct usb_device_id generic_serial_ids[] = {
+ {.driver_info = 42},
+ {}
+};
+#endif
+/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
.name = "serial",
- .probe = usb_serial_probe,
- .disconnect = usb_serial_disconnect,
- .id_table = NULL, /* check all devices */
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+#ifdef CONFIG_USB_SERIAL_GENERIC
+ .id_table = generic_serial_ids,
+#endif
};
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
@@ -413,7 +406,6 @@
drivers depend on it.
*/
-
static int serial_refcount;
static struct tty_driver serial_tty_driver;
static struct tty_struct * serial_tty[SERIAL_TTY_MINORS];
@@ -1162,12 +1154,12 @@
return serial;
}
-static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
+int usb_serial_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
+ struct usb_device *dev = interface_to_usbdev (interface);
struct usb_serial *serial = NULL;
struct usb_serial_port *port;
- struct usb_interface *interface;
struct usb_interface_descriptor *iface_desc;
struct usb_endpoint_descriptor *endpoint;
struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
@@ -1190,7 +1182,6 @@
/* loop through our list of known serial converters, and see if this
device matches. */
found = 0;
- interface = &dev->actconfig->interface[ifnum];
list_for_each (tmp, &usb_serial_driver_list) {
type = list_entry(tmp, struct usb_serial_device_type, driver_list);
id_pattern = usb_match_id(interface, type->id_table);
@@ -1203,13 +1194,13 @@
if (!found) {
/* no match */
dbg("none matched");
- return(NULL);
+ return -ENODEV;
}
serial = create_serial (dev, interface, type);
if (!serial) {
err ("%s - out of memory", __FUNCTION__);
- return NULL;
+ return -ENODEV;
}
/* if this device type has a probe function, call it */
@@ -1223,7 +1214,7 @@
if (retval < 0) {
dbg ("sub driver rejected device");
kfree (serial);
- return NULL;
+ return -ENODEV;
}
}
@@ -1259,6 +1250,7 @@
}
#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
+#if 0
/* BEGIN HORRIBLE HACK FOR PL2303 */
/* this is needed due to the looney way its endpoints are set up */
if (ifnum == 1) {
@@ -1283,6 +1275,7 @@
}
/* END HORRIBLE HACK FOR PL2303 */
#endif
+#endif
/* found all that we need */
info("%s converter detected", type->name);
@@ -1293,7 +1286,7 @@
if (num_ports == 0) {
err("Generic device with no bulk out, not allowed.");
kfree (serial);
- return NULL;
+ return -EIO;
}
}
#endif
@@ -1313,7 +1306,7 @@
if (get_free_serial (serial, num_ports, &minor) == NULL) {
err("No more free serial devices");
kfree (serial);
- return NULL;
+ return -ENOMEM;
}
serial->minor = minor;
@@ -1425,7 +1418,8 @@
if (retval > 0) {
/* quietly accept this device, but don't bind to a serial port
* as it's about to disappear */
- return serial;
+ interface->dev.driver_data = serial;
+ return 0;
}
}
@@ -1456,7 +1450,9 @@
}
#endif
- return serial; /* success */
+ /* success */
+ interface->dev.driver_data = serial;
+ return 0;
probe_error:
@@ -1487,12 +1483,12 @@
/* free up any memory that we allocated */
kfree (serial);
- return NULL;
+ return -EIO;
}
-static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
+void usb_serial_disconnect(struct usb_interface *interface)
{
- struct usb_serial *serial = (struct usb_serial *) ptr;
+ struct usb_serial *serial = (struct usb_serial *)interface->dev.driver_data;
struct usb_serial_port *port;
int i;
@@ -1660,8 +1656,6 @@
info ("USB Serial support registered for %s", new_device->name);
- usb_scan_devices();
-
return 0;
}
@@ -1678,7 +1672,7 @@
serial = serial_table[i];
if ((serial != NULL) && (serial->type == device)) {
usb_driver_release_interface (&usb_serial_driver, serial->interface);
- usb_serial_disconnect (NULL, serial);
+ usb_serial_disconnect (serial->interface);
}
}
@@ -1691,6 +1685,8 @@
need these symbols to load properly as modules. */
EXPORT_SYMBOL(usb_serial_register);
EXPORT_SYMBOL(usb_serial_deregister);
+EXPORT_SYMBOL(usb_serial_probe);
+EXPORT_SYMBOL(usb_serial_disconnect);
#ifdef USES_EZUSB_FUNCTIONS
EXPORT_SYMBOL(ezusb_writememory);
EXPORT_SYMBOL(ezusb_set_reset);
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/visor.c Thu Aug 22 13:39:15 2002
@@ -197,7 +197,7 @@
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
@@ -214,7 +214,12 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
-
+static struct usb_driver visor_driver = {
+ .name = "visor",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
static struct usb_serial_device_type handspring_device = {
@@ -761,6 +766,7 @@
{
usb_serial_register (&handspring_device);
usb_serial_register (&clie_3_5_device);
+ usb_register (&visor_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -769,6 +775,7 @@
static void __exit visor_exit (void)
{
+ usb_deregister (&visor_driver);
usb_serial_deregister (&handspring_device);
usb_serial_deregister (&clie_3_5_device);
}
diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
--- a/drivers/usb/serial/whiteheat.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/serial/whiteheat.c Thu Aug 22 13:39:15 2002
@@ -110,7 +110,7 @@
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
{ } /* Terminating entry */
@@ -118,6 +118,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver whiteheat_driver = {
+ .name = "whiteheat",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
/* function prototypes for the Connect Tech WhiteHEAT serial converter */
static int whiteheat_open (struct usb_serial_port *port, struct file *filp);
static void whiteheat_close (struct usb_serial_port *port, struct file *filp);
@@ -676,6 +683,7 @@
{
usb_serial_register (&whiteheat_fake_device);
usb_serial_register (&whiteheat_device);
+ usb_register (&whiteheat_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -683,6 +691,7 @@
static void __exit whiteheat_exit (void)
{
+ usb_deregister (&whiteheat_driver);
usb_serial_deregister (&whiteheat_fake_device);
usb_serial_deregister (&whiteheat_device);
}
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c Thu Aug 22 13:39:15 2002
+++ b/drivers/usb/storage/usb.c Thu Aug 22 13:39:15 2002
@@ -103,10 +103,10 @@
struct us_data *us_list;
struct semaphore us_list_semaphore;
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id);
+static int storage_probe(struct usb_interface *iface,
+ const struct usb_device_id *id);
-static void storage_disconnect(struct usb_device *dev, void *ptr);
+static void storage_disconnect(struct usb_interface *iface);
/* The entries in this table, except for final ones here
* (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
@@ -229,8 +229,8 @@
struct usb_driver usb_storage_driver = {
.name = "usb-storage",
- .probe = storage_probe,
- .disconnect = storage_disconnect,
+ .new_probe = storage_probe,
+ .new_disco = storage_disconnect,
.id_table = storage_usb_ids,
};
@@ -618,9 +618,11 @@
}
/* Probe to see if a new device is actually a SCSI device */
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
+static int storage_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ int ifnum = usb_if_to_ifnum(intf);
int i;
const int id_index = id - storage_usb_ids;
char mf[USB_STOR_STRING_LEN]; /* manufacturer */
@@ -645,7 +647,6 @@
/* the altsetting on the interface we're probing that matched our
* usb_match_id table
*/
- struct usb_interface *intf = dev->actconfig->interface;
struct usb_interface_descriptor *altsetting =
intf[ifnum].altsetting + intf[ifnum].act_altsetting;
US_DEBUGP("act_altsetting is %d\n", intf[ifnum].act_altsetting);
@@ -675,7 +676,7 @@
US_DEBUGP("Product: %s\n", unusual_dev->productName);
} else
/* no, we can't support it */
- return NULL;
+ return -EIO;
/* At this point, we know we've got a live one */
US_DEBUGP("USB Mass Storage device detected\n");
@@ -724,7 +725,7 @@
} else if (result != 0) {
/* it's not a stall, but another error -- time to bail */
US_DEBUGP("-- Unknown error. Rejecting device\n");
- return NULL;
+ return -EIO;
}
}
#endif
@@ -732,7 +733,7 @@
/* Do some basic sanity checks, and bail if we find a problem */
if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) {
US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n");
- return NULL;
+ return -EIO;
}
/* At this point, we've decided to try to use the device */
@@ -811,7 +812,7 @@
GFP_KERNEL)) == NULL) {
printk(KERN_WARNING USB_STORAGE "Out of memory\n");
usb_put_dev(dev);
- return NULL;
+ return -ENOMEM;
}
memset(ss, 0, sizeof(struct us_data));
new_device = 1;
@@ -1088,8 +1089,9 @@
printk(KERN_DEBUG
"USB Mass Storage device found at %d\n", dev->devnum);
- /* return a pointer for the disconnect function */
- return ss;
+ /* save a pointer to our structure */
+ intf->dev.driver_data = ss;
+ return 0;
/* we come here if there are any problems */
/* ss->dev_semaphore must be locked */
@@ -1099,13 +1101,13 @@
up(&ss->dev_semaphore);
if (new_device)
kfree(ss);
- return NULL;
+ return -EIO;
}
/* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_device *dev, void *ptr)
+static void storage_disconnect(struct usb_interface *intf)
{
- struct us_data *ss = ptr;
+ struct us_data *ss = intf->dev.driver_data;
US_DEBUGP("storage_disconnect() called\n");
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c Thu Aug 22 13:39:15 2002
+++ b/fs/partitions/check.c Thu Aug 22 13:39:15 2002
@@ -175,14 +175,14 @@
kdev.value=(int)(long)driverfs_dev->driver_data;
return off ? 0 : sprintf (page, "%x\n",kdev.value);
}
-static DEVICE_ATTR(kdev,"kdev",S_IRUGO,partition_device_kdev_read,NULL);
+static DEVICE_ATTR(kdev,S_IRUGO,partition_device_kdev_read,NULL);
static ssize_t partition_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "BLK\n");
}
-static DEVICE_ATTR(type,"type",S_IRUGO,partition_device_type_read,NULL);
+static DEVICE_ATTR(type,S_IRUGO,partition_device_type_read,NULL);
void driverfs_create_partitions(struct gendisk *hd, int minor)
{
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h Thu Aug 22 13:39:15 2002
+++ b/include/linux/device.h Thu Aug 22 13:39:15 2002
@@ -93,9 +93,9 @@
ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
};
-#define BUS_ATTR(_name,_str,_mode,_show,_store) \
+#define BUS_ATTR(_name,_mode,_show,_store) \
struct bus_attribute bus_attr_##_name = { \
- .attr = {.name = _str, .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
};
@@ -150,9 +150,9 @@
ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off);
};
-#define DRIVER_ATTR(_name,_str,_mode,_show,_store) \
+#define DRIVER_ATTR(_name,_mode,_show,_store) \
struct driver_attribute driver_attr_##_name = { \
- .attr = {.name = _str, .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
};
@@ -222,13 +222,14 @@
ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
};
-#define DEVICE_ATTR(_name,_str,_mode,_show,_store) \
+#define DEVICE_ATTR(_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_name = { \
- .attr = {.name = _str, .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
};
+
extern int device_create_file(struct device *device, struct device_attribute * entry);
extern void device_remove_file(struct device * dev, struct device_attribute * attr);
@@ -260,12 +261,7 @@
* get_device - atomically increment the reference count for the device.
*
*/
-static inline void get_device(struct device * dev)
-{
- BUG_ON(!atomic_read(&dev->refcount));
- atomic_inc(&dev->refcount);
-}
-
+extern struct device * get_device(struct device * dev);
extern void put_device(struct device * dev);
/* drivers/base/sys.c */
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h Thu Aug 22 13:39:15 2002
+++ b/include/linux/usb.h Thu Aug 22 13:39:15 2002
@@ -227,7 +227,7 @@
int act_altsetting; /* active alternate setting */
int num_altsetting; /* number of alternate settings */
int max_altsetting; /* total memory allocated */
-
+
struct usb_driver *driver; /* driver */
struct device dev; /* interface specific device info */
void *private_data;
@@ -291,6 +291,8 @@
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
type,(void**)ptr)
+extern int usb_if_to_ifnum(struct usb_interface *iface);
+
/* -------------------------------------------------------------------------- */
/* Host Controller Driver (HCD) support */
@@ -399,9 +401,6 @@
extern void usb_free_dev(struct usb_device *);
#define usb_put_dev usb_free_dev
-/* for when layers above USB add new non-USB drivers */
-extern void usb_scan_devices(void);
-
/* mostly for devices emulating SCSI over USB */
extern int usb_reset_device(struct usb_device *dev);
@@ -645,6 +644,11 @@
struct module *owner;
const char *name;
+ int (*new_probe) (struct usb_interface *intf, const struct usb_device_id *id);
+ void (*new_disco) (struct usb_interface *intf);
+
+ struct device_driver driver;
+
void *(*probe)(
struct usb_device *dev, /* the device */
unsigned intf, /* what interface */
@@ -655,7 +659,6 @@
void *handle /* as returned by probe() */
);
- struct list_head driver_list;
struct semaphore serialize;
/* ioctl -- userspace apps can talk to drivers through usbfs */
@@ -669,6 +672,7 @@
/* void (*suspend)(struct usb_device *dev); */
/* void (*resume)(struct usb_device *dev); */
};
+#define to_usb_driver(d) container_of(d, struct usb_driver, driver)
extern struct bus_type usb_bus_type;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] USB driver conversion to "struct device_driver" for 2.5.31
2002-08-22 20:44 [RFC] USB driver conversion to "struct device_driver" for 2.5.31 Greg KH
@ 2002-08-23 19:31 ` Greg KH
[not found] ` <20020829221339.GA5074@kroah.com>
1 sibling, 0 replies; 4+ messages in thread
From: Greg KH @ 2002-08-23 19:31 UTC (permalink / raw)
To: linux-usb-devel, linux-kernel; +Cc: Patrick Mochel
As I got some complaints that the patch was difficult to apply, here it
is again, against 2.5.31-bk6.
Changes from the version yesterday include:
- conversion of usbmouse.c driver by Pat Mochel
- tried to fix up module locking issues in the new_probe() and
new_disco() calls.
I'm pretty sure I've messed up the disconnect and connect ability of
usbfs (the ioctl calls). If anyone can test this out, I would
appreciate it.
thanks,
greg k-h
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/class/audio.c linux-2.5.31-bk6-greg/drivers/usb/class/audio.c
--- linux-2.5.31-bk6/drivers/usb/class/audio.c Sat Aug 10 18:41:56 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/class/audio.c Fri Aug 23 12:13:26 2002
@@ -2756,7 +2756,6 @@
.name = "audio",
.probe = usb_audio_probe,
.disconnect = usb_audio_disconnect,
- .driver_list = LIST_HEAD_INIT(usb_audio_driver.driver_list),
.id_table = usb_audio_ids,
};
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/class/usb-midi.c linux-2.5.31-bk6-greg/drivers/usb/class/usb-midi.c
--- linux-2.5.31-bk6/drivers/usb/class/usb-midi.c Sat Aug 10 18:41:18 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/class/usb-midi.c Fri Aug 23 12:13:26 2002
@@ -2099,7 +2099,6 @@
.probe = usb_midi_probe,
.disconnect = usb_midi_disconnect,
.id_table = NULL, /* check all devices */
- .driver_list = LIST_HEAD_INIT(usb_midi_driver.driver_list)
};
/* ------------------------------------------------------------------------- */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/devices.c linux-2.5.31-bk6-greg/drivers/usb/core/devices.c
--- linux-2.5.31-bk6/drivers/usb/core/devices.c Sat Aug 10 18:41:28 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/devices.c Fri Aug 23 12:13:26 2002
@@ -111,7 +111,6 @@
/*
* Need access to the driver and USB bus lists.
- * extern struct list_head usb_driver_list;
* extern struct list_head usb_bus_list;
* However, these will come from functions that return ptrs to each of them.
*/
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/devio.c linux-2.5.31-bk6-greg/drivers/usb/core/devio.c
--- linux-2.5.31-bk6/drivers/usb/core/devio.c Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/devio.c Fri Aug 23 12:13:26 2002
@@ -427,30 +427,6 @@
return -ENOENT;
}
-extern struct list_head usb_driver_list;
-
-#if 0
-static int finddriver(struct usb_driver **driver, char *name)
-{
- struct list_head *tmp;
-
- tmp = usb_driver_list.next;
- while (tmp != &usb_driver_list) {
- struct usb_driver *d = list_entry(tmp, struct usb_driver,
- driver_list);
-
- if (!strcmp(d->name, name)) {
- *driver = d;
- return 0;
- }
-
- tmp = tmp->next;
- }
-
- return -EINVAL;
-}
-#endif
-
static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index)
{
int ret;
@@ -723,11 +699,10 @@
if (test_bit(i, &ps->ifclaimed))
continue;
- lock_kernel();
+ err ("%s - this function is broken", __FUNCTION__);
if (intf->driver && ps->dev) {
- usb_bind_driver (intf->driver, intf);
+ usb_device_probe (&intf->dev);
}
- unlock_kernel();
}
return 0;
@@ -1090,22 +1065,19 @@
/* disconnect kernel driver from interface, leaving it unbound. */
case USBDEVFS_DISCONNECT:
- /* this function is voodoo. without locking it is a maybe thing */
- lock_kernel();
- driver = ifp->driver;
- if (driver) {
- dbg ("disconnect '%s' from dev %d interface %d",
- driver->name, ps->dev->devnum, ctrl.ifno);
- usb_unbind_driver(ps->dev, ifp);
- usb_driver_release_interface (driver, ifp);
- } else
+ /* this function is voodoo. */
+ driver = ifp->driver;
+ if (driver) {
+ dbg ("disconnect '%s' from dev %d interface %d",
+ driver->name, ps->dev->devnum, ctrl.ifno);
+ usb_device_remove(&ifp->dev);
+ } else
retval = -EINVAL;
- unlock_kernel();
- break;
+ break;
/* let kernel drivers try to (re)bind to the interface */
case USBDEVFS_CONNECT:
- usb_find_interface_driver (ps->dev, ifp);
+ retval = usb_device_probe (&ifp->dev);
break;
/* talk directly to the interface's driver */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/hcd.c linux-2.5.31-bk6-greg/drivers/usb/core/hcd.c
--- linux-2.5.31-bk6/drivers/usb/core/hcd.c Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/hcd.c Fri Aug 23 12:13:26 2002
@@ -724,13 +724,15 @@
{
int retval;
- usb_dev->dev.parent = parent_dev;
- strcpy (&usb_dev->dev.name[0], "usb_name");
- strcpy (&usb_dev->dev.bus_id[0], "usb_bus");
- retval = usb_new_device (usb_dev);
+// usb_dev->dev.parent = parent_dev;
+// strcpy (&usb_dev->dev.name[0], "usb_name");
+// strcpy (&usb_dev->dev.bus_id[0], "usb_bus");
+ retval = usb_new_device (usb_dev, parent_dev);
if (retval)
- put_device (&usb_dev->dev);
+ err("%s - usb_new_device failed with value %d", __FUNCTION__, retval);
+// put_device (&usb_dev->dev);
return retval;
+// return usb_new_device (usb_dev, parent_dev);
}
EXPORT_SYMBOL (usb_register_root_hub);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/hcd.h linux-2.5.31-bk6-greg/drivers/usb/core/hcd.h
--- linux-2.5.31-bk6/drivers/usb/core/hcd.h Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/hcd.h Fri Aug 23 12:14:33 2002
@@ -230,7 +230,7 @@
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
-extern int usb_new_device(struct usb_device *dev);
+extern int usb_new_device(struct usb_device *dev, struct device *parent);
extern void usb_connect(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);
@@ -354,10 +354,6 @@
extern int usb_find_interface_driver (struct usb_device *dev,
struct usb_interface *interface);
-/* for probe/disconnect with correct module usage counting */
-void *usb_bind_driver(struct usb_driver *driver, struct usb_interface *intf);
-void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf);
-
/*-------------------------------------------------------------------------*/
/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/hub.c linux-2.5.31-bk6-greg/drivers/usb/core/hub.c
--- linux-2.5.31-bk6/drivers/usb/core/hub.c Sat Aug 10 18:41:28 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/hub.c Fri Aug 23 12:13:26 2002
@@ -175,6 +175,7 @@
while (!list_empty (&hub->tt.clear_list)) {
struct list_head *temp;
struct usb_tt_clear *clear;
+ struct usb_device *dev;
int status;
temp = hub->tt.clear_list.next;
@@ -183,13 +184,13 @@
/* drop lock so HCD can concurrently report other TT errors */
spin_unlock_irqrestore (&hub->tt.lock, flags);
- status = hub_clear_tt_buffer (hub->dev,
- clear->devinfo, clear->tt);
+ dev = interface_to_usbdev (hub->intf);
+ status = hub_clear_tt_buffer (dev, clear->devinfo, clear->tt);
spin_lock_irqsave (&hub->tt.lock, flags);
if (status)
err ("usb-%s-%s clear tt %d (%04x) error %d",
- hub->dev->bus->bus_name, hub->dev->devpath,
+ dev->bus->bus_name, dev->devpath,
clear->tt, clear->devinfo, status);
kfree (clear);
}
@@ -245,12 +246,14 @@
static void usb_hub_power_on(struct usb_hub *hub)
{
+ struct usb_device *dev;
int i;
/* Enable power to the ports */
dbg("enabling power on all ports");
+ dev = interface_to_usbdev(hub->intf);
for (i = 0; i < hub->descriptor->bNbrPorts; i++)
- usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+ usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
/* Wait for power to be enabled */
wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
@@ -259,7 +262,7 @@
static int usb_hub_configure(struct usb_hub *hub,
struct usb_endpoint_descriptor *endpoint)
{
- struct usb_device *dev = hub->dev;
+ struct usb_device *dev = interface_to_usbdev (hub->intf);
struct usb_hub_status hubstatus;
char portstr[USB_MAXCHILDREN + 1];
unsigned int pipe;
@@ -426,39 +429,81 @@
return 0;
}
-static void *hub_probe(struct usb_device *dev, unsigned int i,
- const struct usb_device_id *id)
+static void hub_disconnect(struct usb_interface *intf)
+{
+ struct usb_hub *hub = (struct usb_hub *)intf->dev.driver_data;
+ unsigned long flags;
+
+ if (!hub)
+ return;
+
+ spin_lock_irqsave(&hub_event_lock, flags);
+
+ /* Delete it and then reset it */
+ list_del(&hub->event_list);
+ INIT_LIST_HEAD(&hub->event_list);
+ list_del(&hub->hub_list);
+ INIT_LIST_HEAD(&hub->hub_list);
+
+ spin_unlock_irqrestore(&hub_event_lock, flags);
+
+ down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
+ up(&hub->khubd_sem);
+
+ /* assuming we used keventd, it must quiesce too */
+ if (hub->tt.hub)
+ flush_scheduled_tasks ();
+
+ if (hub->urb) {
+ usb_unlink_urb(hub->urb);
+ usb_free_urb(hub->urb);
+ hub->urb = NULL;
+ }
+
+ if (hub->descriptor) {
+ kfree(hub->descriptor);
+ hub->descriptor = NULL;
+ }
+
+ /* Free the memory */
+ kfree(hub);
+ intf->dev.driver_data = NULL;
+}
+
+static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- struct usb_interface_descriptor *interface;
+ struct usb_interface_descriptor *desc;
struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *dev;
struct usb_hub *hub;
unsigned long flags;
- interface = &dev->actconfig->interface[i].altsetting[0];
+ desc = intf->altsetting + intf->act_altsetting;
+ dev = interface_to_usbdev(intf);
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
- if ((interface->bInterfaceSubClass != 0) &&
- (interface->bInterfaceSubClass != 1)) {
+ if ((desc->bInterfaceSubClass != 0) &&
+ (desc->bInterfaceSubClass != 1)) {
err("invalid subclass (%d) for USB hub device #%d",
- interface->bInterfaceSubClass, dev->devnum);
- return NULL;
+ desc->bInterfaceSubClass, dev->devnum);
+ return -EIO;
}
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
- if (interface->bNumEndpoints != 1) {
+ if (desc->bNumEndpoints != 1) {
err("invalid bNumEndpoints (%d) for USB hub device #%d",
- interface->bNumEndpoints, dev->devnum);
- return NULL;
+ desc->bNumEndpoints, dev->devnum);
+ return -EIO;
}
- endpoint = &interface->endpoint[0];
+ endpoint = &desc->endpoint[0];
/* Output endpoint? Curiousier and curiousier.. */
if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
err("Device #%d is hub class, but has output endpoint?",
dev->devnum);
- return NULL;
+ return -EIO;
}
/* If it's not an interrupt endpoint, we'd better punt! */
@@ -466,7 +511,7 @@
!= USB_ENDPOINT_XFER_INT) {
err("Device #%d is hub class, but endpoint is not interrupt?",
dev->devnum);
- return NULL;
+ return -EIO;
}
/* We found a hub */
@@ -475,13 +520,13 @@
hub = kmalloc(sizeof(*hub), GFP_KERNEL);
if (!hub) {
err("couldn't kmalloc hub struct");
- return NULL;
+ return -ENOMEM;
}
memset(hub, 0, sizeof(*hub));
INIT_LIST_HEAD(&hub->event_list);
- hub->dev = dev;
+ hub->intf = intf;
init_MUTEX(&hub->khubd_sem);
/* Record the new hub's existence */
@@ -490,14 +535,18 @@
list_add(&hub->hub_list, &hub_list);
spin_unlock_irqrestore(&hub_event_lock, flags);
+ intf->dev.driver_data = hub;
+
if (usb_hub_configure(hub, endpoint) >= 0) {
- strcpy (dev->actconfig->interface[i].dev.name,
- "Hub/Port Status Changes");
- return hub;
+ strcpy (intf->dev.name, "Hub/Port Status Changes");
+ return 0;
}
err("hub configuration failed for device at %s", dev->devpath);
+ hub_disconnect (intf);
+ return -ENODEV;
+#if 0
/* free hub, but first clean up its list. */
spin_lock_irqsave(&hub_event_lock, flags);
@@ -512,43 +561,7 @@
kfree(hub);
return NULL;
-}
-
-static void hub_disconnect(struct usb_device *dev, void *ptr)
-{
- struct usb_hub *hub = (struct usb_hub *)ptr;
- unsigned long flags;
-
- spin_lock_irqsave(&hub_event_lock, flags);
-
- /* Delete it and then reset it */
- list_del(&hub->event_list);
- INIT_LIST_HEAD(&hub->event_list);
- list_del(&hub->hub_list);
- INIT_LIST_HEAD(&hub->hub_list);
-
- spin_unlock_irqrestore(&hub_event_lock, flags);
-
- down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
- up(&hub->khubd_sem);
-
- /* assuming we used keventd, it must quiesce too */
- if (hub->tt.hub)
- flush_scheduled_tasks ();
-
- if (hub->urb) {
- usb_unlink_urb(hub->urb);
- usb_free_urb(hub->urb);
- hub->urb = NULL;
- }
-
- if (hub->descriptor) {
- kfree(hub->descriptor);
- hub->descriptor = NULL;
- }
-
- /* Free the memory */
- kfree(hub);
+#endif
}
static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
@@ -585,7 +598,7 @@
static int usb_hub_reset(struct usb_hub *hub)
{
- struct usb_device *dev = hub->dev;
+ struct usb_device *dev = interface_to_usbdev(hub->intf);
int i;
/* Disconnect any attached devices */
@@ -797,7 +810,7 @@
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
u16 portstatus, u16 portchange)
{
- struct usb_device *hub = hubstate->dev;
+ struct usb_device *hub = interface_to_usbdev(hubstate->intf);
struct usb_device *dev;
unsigned int delay = HUB_SHORT_RESET_TIME;
int i;
@@ -892,11 +905,15 @@
/* put the device in the global device tree. the hub port
* is the "bus_id"; hubs show in hierarchy like bridges
*/
- dev->dev.parent = &dev->parent->dev;
+// dev->dev.parent = &dev->parent->dev;
+// if (dev->parent->dev.parent)
+ dev->dev.parent = dev->parent->dev.parent->parent;
+// else
+// dev->dev.parent = &dev->parent->dev;
sprintf (&dev->dev.bus_id[0], "%d", port + 1);
/* Run it through the hoops (find a driver, etc) */
- if (!usb_new_device(dev))
+ if (!usb_new_device(dev, &hubstate->intf->dev))
goto done;
/* Free the configuration if there was an error */
@@ -941,7 +958,7 @@
tmp = hub_event_list.next;
hub = list_entry(tmp, struct usb_hub, event_list);
- dev = hub->dev;
+ dev = interface_to_usbdev(hub->intf);
list_del(tmp);
INIT_LIST_HEAD(tmp);
@@ -1081,9 +1098,9 @@
static struct usb_driver hub_driver = {
.name = "hub",
- .probe = hub_probe,
+ .new_probe = hub_probe,
.ioctl = hub_ioctl,
- .disconnect = hub_disconnect,
+ .new_disco = hub_disconnect,
.id_table = hub_id_table,
};
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/hub.h linux-2.5.31-bk6-greg/drivers/usb/core/hub.h
--- linux-2.5.31-bk6/drivers/usb/core/hub.h Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/hub.h Fri Aug 23 12:13:26 2002
@@ -170,7 +170,8 @@
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
- struct usb_device *dev; /* the "real" device */
+// struct usb_device *dev; /* the "real" device */
+ struct usb_interface *intf; /* the "real" device */
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/core/usb.c linux-2.5.31-bk6-greg/drivers/usb/core/usb.c
--- linux-2.5.31-bk6/drivers/usb/core/usb.c Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/core/usb.c Fri Aug 23 12:17:19 2002
@@ -48,17 +48,95 @@
extern int usb_major_init(void);
extern void usb_major_cleanup(void);
-/*
- * Prototypes for the device driver probing/loading functions
- */
-static void usb_find_drivers(struct usb_device *);
-static void usb_check_support(struct usb_device *);
-/*
- * We have a per-interface "registered driver" list.
- */
-LIST_HEAD(usb_driver_list);
+static int generic_probe (struct device *dev)
+{
+ return 0;
+}
+static int generic_remove (struct device *dev)
+{
+ return 0;
+}
+static void generic_release (struct device_driver * drv)
+{
+}
+
+static struct device_driver usb_generic_driver = {
+ .name = "generic usb driver",
+ .probe = generic_probe,
+ .remove = generic_remove,
+ .release = generic_release,
+};
+
+
+int usb_device_probe(struct device *dev)
+{
+ struct usb_interface * intf = to_usb_interface(dev);
+ struct usb_driver * driver = to_usb_driver(dev->driver);
+ const struct usb_device_id *id;
+ int error = -ENODEV;
+ int m;
+
+ dbg("%s", __FUNCTION__);
+
+ if (!driver->new_probe)
+ return error;
+
+ if (driver->owner) {
+ m = try_inc_mod_count(driver->owner);
+ if (m == 0)
+ return error;
+ }
+
+ id = usb_match_id (intf, driver->id_table);
+ if (id) {
+ dbg ("%s - got id", __FUNCTION__);
+ down (&driver->serialize);
+ error = driver->new_probe (intf, id);
+ up (&driver->serialize);
+ }
+ if (!error)
+ intf->driver = driver;
+
+ if (driver->owner)
+ __MOD_DEC_USE_COUNT(driver->owner);
+
+ return error;
+}
+
+int usb_device_remove(struct device *dev)
+{
+ struct usb_interface *intf = list_entry(dev,struct usb_interface,dev);
+ struct usb_driver *driver = to_usb_driver(dev->driver);
+ int m;
+
+ if (driver->owner) {
+ m = try_inc_mod_count(driver->owner);
+ if (m == 0) {
+ err("Dieing driver still bound to device.\n");
+ return -EIO;
+ }
+ }
+
+ /* if we sleep here on an umanaged driver
+ * the holder of the lock guards against
+ * module unload */
+ down(&driver->serialize);
+
+ if (intf->driver && intf->driver->new_disco)
+ intf->driver->new_disco(intf);
+
+ /* if driver->disconnect didn't release the interface */
+ if (intf->driver)
+ usb_driver_release_interface(driver, intf);
+
+ up(&driver->serialize);
+ if (driver->owner) {
+ __MOD_DEC_USE_COUNT(driver->owner);
+ }
+ return 0;
+}
/**
* usb_register - register a USB driver
@@ -77,61 +155,40 @@
{
int retval = 0;
- info("registered new driver %s", new_driver->name);
+ new_driver->driver.name = (char *)new_driver->name;
+ new_driver->driver.bus = &usb_bus_type;
+ new_driver->driver.probe = usb_device_probe;
+ new_driver->driver.remove = usb_device_remove;
init_MUTEX(&new_driver->serialize);
- /* Add it to the list of known drivers */
- list_add_tail(&new_driver->driver_list, &usb_driver_list);
-
- usb_scan_devices();
+ retval = driver_register(&new_driver->driver);
- usbfs_update_special();
+ if (!retval) {
+ info("registered new driver %s", new_driver->name);
+ usbfs_update_special();
+ } else {
+ err("problem %d when registering driver %s",
+ retval, new_driver->name);
+ }
return retval;
}
-
+#if 0
/**
- * usb_scan_devices - scans all unclaimed USB interfaces
- * Context: !in_interrupt ()
+ * usb_unbind_driver - disconnects a driver from a device (usbcore-internal)
+ * @device: usb device to be disconnected
+ * @intf: interface of the device to be disconnected
+ * Context: BKL held
*
- * Goes through all unclaimed USB interfaces, and offers them to all
- * registered USB drivers through the 'probe' function.
- * This will automatically be called after usb_register is called.
- * It is called by some of the subsystems layered over USB
- * after one of their subdrivers are registered.
+ * Handles module usage count correctly
*/
-void usb_scan_devices(void)
-{
- struct list_head *tmp;
-
- down (&usb_bus_list_lock);
- tmp = usb_bus_list.next;
- while (tmp != &usb_bus_list) {
- struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);
-
- tmp = tmp->next;
- usb_check_support(bus->root_hub);
- }
- up (&usb_bus_list_lock);
-}
-
-/**
- * usb_unbind_driver - disconnects a driver from a device (usbcore-internal)
- * @device: usb device to be disconnected
- * @intf: interface of the device to be disconnected
- * Context: BKL held
- *
- * Handles module usage count correctly
- */
-
-void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf)
+static void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf)
{
struct usb_driver *driver;
void *priv;
int m;
-
driver = intf->driver;
priv = intf->private_data;
@@ -176,7 +233,7 @@
* drivers and neither calls the driver's probe() entry nor does any
* locking to guard against removing driver modules.
*/
-void *
+static void *
usb_bind_driver (struct usb_driver *driver, struct usb_interface *interface)
{
int i,m;
@@ -231,43 +288,7 @@
return private;
}
-
-/*
- * This function is part of a depth-first search down the device tree,
- * removing any instances of a device driver.
- */
-static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev)
-{
- int i;
-
- if (!dev) {
- err("null device being purged!!!");
- return;
- }
-
- for (i=0; i<USB_MAXCHILDREN; i++)
- if (dev->children[i])
- usb_drivers_purge(driver, dev->children[i]);
-
- if (!dev->actconfig)
- return;
-
- for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
- struct usb_interface *interface = &dev->actconfig->interface[i];
-
- if (interface->driver == driver) {
- usb_unbind_driver(dev, interface);
- /* if driver->disconnect didn't release the interface */
- if (interface->driver)
- usb_driver_release_interface(driver, interface);
- /*
- * This will go through the list looking for another
- * driver that can handle the device
- */
- usb_find_interface_driver(dev, interface);
- }
- }
-}
+#endif
/**
* usb_deregister - unregister a USB driver
@@ -282,25 +303,9 @@
*/
void usb_deregister(struct usb_driver *driver)
{
- struct list_head *tmp;
-
info("deregistering driver %s", driver->name);
- /*
- * first we remove the driver, to be sure it doesn't get used by
- * another thread while we are stepping through removing entries
- */
- list_del(&driver->driver_list);
-
- down (&usb_bus_list_lock);
- tmp = usb_bus_list.next;
- while (tmp != &usb_bus_list) {
- struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
-
- tmp = tmp->next;
- usb_drivers_purge(driver, bus->root_hub);
- }
- up (&usb_bus_list_lock);
+ remove_driver (&driver->driver);
usbfs_update_special();
}
@@ -333,6 +338,32 @@
}
/**
+ * usb_if_to_ifnum - get the interface number for a given interface
+ * @iface: the interface to determine the ifnum of
+ *
+ * This walks the device descriptor for the currently active configuration
+ * and returns the interface number of this specific interface, or -ENODEV.
+ *
+ * Note that configuration descriptors are not required to assign interface
+ * numbers sequentially, so that it would be incorrect to assume that
+ * the first interface in that descriptor corresponds to interface zero.
+ * This routine helps device drivers avoid such mistakes.
+ * However, you should make sure that you do the right thing with any
+ * alternate settings available for this interfaces.
+ */
+int usb_if_to_ifnum(struct usb_interface *iface)
+{
+ struct usb_device *dev = interface_to_usbdev(iface);
+ int i;
+
+ for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
+ if (iface == &dev->actconfig->interface[i])
+ return dev->actconfig->interface[i].altsetting[0].bInterfaceNumber;
+
+ return -ENODEV;
+}
+
+/**
* usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number
* @dev: the device whose current configuration is considered
* @epnum: the desired endpoint
@@ -359,34 +390,6 @@
return NULL;
}
-/*
- * This function is for doing a depth-first search for devices which
- * have support, for dynamic loading of driver modules.
- */
-static void usb_check_support(struct usb_device *dev)
-{
- int i;
-
- if (!dev) {
- err("null device being checked!!!");
- return;
- }
-
- for (i=0; i<USB_MAXCHILDREN; i++)
- if (dev->children[i])
- usb_check_support(dev->children[i]);
-
- if (!dev->actconfig)
- return;
-
- /* now we check this device */
- if (dev->devnum > 0)
- for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
- usb_find_interface_driver (dev,
- dev->actconfig->interface + i);
-}
-
-
/**
* usb_driver_claim_interface - bind a driver to an interface
* @driver: the driver to be bound
@@ -595,72 +598,25 @@
return NULL;
}
-/*
- * This entrypoint gets called for unclaimed interfaces.
- *
- * We now walk the list of registered USB drivers,
- * looking for one that will accept this interface.
- *
- * "New Style" drivers use a table describing the devices and interfaces
- * they handle. Those tables are available to user mode tools deciding
- * whether to load driver modules for a new device.
- *
- * The probe return value is changed to be a private pointer. This way
- * the drivers don't have to dig around in our structures to set the
- * private pointer if they only need one interface.
- *
- * Returns: 0 if a driver accepted the interface, -1 otherwise
- */
-int usb_find_interface_driver (
- struct usb_device *dev,
- struct usb_interface *interface
-)
+static int usb_device_match (struct device *dev, struct device_driver *drv)
{
- struct list_head *tmp;
- void *private;
- struct usb_driver *driver;
- int ifnum;
-
- down(&dev->serialize);
-
- /* FIXME It's just luck that for some devices with drivers that set
- * configuration in probe(), the interface numbers still make sense.
- * That's one of several unsafe assumptions involved in configuring
- * devices, and in binding drivers to their interfaces.
- */
- for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++)
- if (&dev->actconfig->interface [ifnum] == interface)
- break;
- BUG_ON (ifnum == dev->actconfig->bNumInterfaces);
+ struct usb_interface *intf;
+ struct usb_driver *usb_drv;
+ const struct usb_device_id *id;
- if (usb_interface_claimed(interface))
- goto out_err;
+ intf = to_usb_interface(dev);
- private = NULL;
- lock_kernel();
- for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) {
- driver = list_entry(tmp, struct usb_driver, driver_list);
- tmp = tmp->next;
-
- private = usb_bind_driver(driver, interface);
-
- /* probe() may have changed the config on us */
- interface = dev->actconfig->interface + ifnum;
-
- if (private) {
- usb_driver_claim_interface(driver, interface, private);
- up(&dev->serialize);
- unlock_kernel();
- return 0;
- }
- }
- unlock_kernel();
+ usb_drv = to_usb_driver(drv);
+ id = usb_drv->id_table;
+
+ id = usb_match_id (intf, usb_drv->id_table);
+ if (id)
+ return 1;
-out_err:
- up(&dev->serialize);
- return -1;
+ return 0;
}
+
#ifdef CONFIG_HOTPLUG
/*
@@ -890,71 +846,6 @@
}
static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
-/*
- * This entrypoint gets called for each new device.
- *
- * All interfaces are scanned for matching drivers.
- */
-static void usb_find_drivers(struct usb_device *dev)
-{
- unsigned ifnum;
- unsigned rejected = 0;
- unsigned claimed = 0;
-
- /* FIXME should get called for each new configuration not just the
- * first one for a device. switching configs (or altsettings) should
- * undo driverfs and HCD state for the previous interfaces.
- */
- for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
- struct usb_interface *interface = &dev->actconfig->interface[ifnum];
- struct usb_interface_descriptor *desc = interface->altsetting;
-
- /* register this interface with driverfs */
- interface->dev.parent = &dev->dev;
- interface->dev.bus = &usb_bus_type;
- sprintf (&interface->dev.bus_id[0], "%s-%s:%d",
- dev->bus->bus_name, dev->devpath,
- interface->altsetting->bInterfaceNumber);
- if (!desc->iInterface
- || usb_string (dev, desc->iInterface,
- interface->dev.name,
- sizeof interface->dev.name) <= 0) {
- /* typically devices won't bother with interface
- * descriptions; this is the normal case. an
- * interface's driver might describe it better.
- * (also: iInterface is per-altsetting ...)
- */
- sprintf (&interface->dev.name[0],
- "usb-%s-%s interface %d",
- dev->bus->bus_name, dev->devpath,
- interface->altsetting->bInterfaceNumber);
- }
- device_register (&interface->dev);
- device_create_file (&interface->dev, &dev_attr_altsetting);
-
- /* if this interface hasn't already been claimed */
- if (!usb_interface_claimed(interface)) {
- if (usb_find_interface_driver(dev, interface))
- rejected++;
- else
- claimed++;
- }
- }
-
- if (rejected)
- dbg("unhandled interfaces on device");
-
- if (!claimed) {
- warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.",
- dev->devnum,
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
-#ifdef DEBUG
- usb_show_device(dev);
-#endif
- }
-}
-
/**
* usb_alloc_dev - allocate a usb device structure (usbcore-internal)
* @parent: hub to which device is connected
@@ -1159,22 +1050,17 @@
info("USB disconnect on device %d", dev->devnum);
- lock_kernel();
if (dev->actconfig) {
for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
struct usb_interface *interface = &dev->actconfig->interface[i];
- struct usb_driver *driver = interface->driver;
- if (driver) {
- usb_unbind_driver(dev, interface);
- /* if driver->disconnect didn't release the interface */
- if (interface->driver)
- usb_driver_release_interface(driver, interface);
- }
+// struct usb_driver *driver = interface->driver;
+// if (driver) {
+// usb_unbind_driver(dev, interface);
+// }
/* remove our device node for this interface */
put_device(&interface->dev);
}
}
- unlock_kernel();
/* Free up all the children.. */
for (i = 0; i < USB_MAXCHILDREN; i++) {
@@ -1324,11 +1210,12 @@
*/
#define NEW_DEVICE_RETRYS 2
#define SET_ADDRESS_RETRYS 2
-int usb_new_device(struct usb_device *dev)
+int usb_new_device(struct usb_device *dev, struct device *parent)
{
int err = 0;
int i;
int j;
+ int ifnum;
/* USB v1.1 5.5.3 */
/* We read the first 8 bytes from the device descriptor to get to */
@@ -1414,10 +1301,22 @@
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
#endif
- /* register this device in the driverfs tree */
+ /*
+ * Set the driver for the usb device to point to the "generic" driver.
+ * This prevents the main usb device from being sent to the usb bus
+ * probe function. Yes, it's a hack, but a nice one :)
+ */
+ usb_generic_driver.bus = &usb_bus_type;
+ dev->dev.parent = parent;
+ dev->dev.driver = &usb_generic_driver;
+ dev->dev.bus = &usb_bus_type;
+ sprintf (&dev->dev.bus_id[0], "%s-%s",
+ dev->bus->bus_name, dev->devpath);
err = device_register (&dev->dev);
if (err)
return err;
+
+ /* add the USB device specific driverfs files */
device_create_file (&dev->dev, &dev_attr_configuration);
if (dev->descriptor.iManufacturer)
device_create_file (&dev->dev, &dev_attr_manufacturer);
@@ -1426,11 +1325,38 @@
if (dev->descriptor.iSerialNumber)
device_create_file (&dev->dev, &dev_attr_serial);
- /* now that the basic setup is over, add a /proc/bus/usb entry */
- usbfs_add_device(dev);
+ /* Register all of the interfaces for this device with the driver core.
+ * Remember, interfaces get bound to drivers, not devices. */
+ for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
+ struct usb_interface *interface = &dev->actconfig->interface[ifnum];
+ struct usb_interface_descriptor *desc = interface->altsetting;
+
+ interface->dev.parent = &dev->dev;
+ interface->dev.bus = &usb_bus_type;
+ sprintf (&interface->dev.bus_id[0], "%s-%s:%d",
+ dev->bus->bus_name, dev->devpath,
+ interface->altsetting->bInterfaceNumber);
+ if (!desc->iInterface
+ || usb_string (dev, desc->iInterface,
+ interface->dev.name,
+ sizeof interface->dev.name) <= 0) {
+ /* typically devices won't bother with interface
+ * descriptions; this is the normal case. an
+ * interface's driver might describe it better.
+ * (also: iInterface is per-altsetting ...)
+ */
+ sprintf (&interface->dev.name[0],
+ "usb-%s-%s interface %d",
+ dev->bus->bus_name, dev->devpath,
+ interface->altsetting->bInterfaceNumber);
+ }
+ dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
+ device_register (&interface->dev);
+ device_create_file (&interface->dev, &dev_attr_altsetting);
+ }
- /* find drivers willing to handle this device */
- usb_find_drivers(dev);
+ /* add a /proc/bus/usb entry */
+ usbfs_add_device(dev);
/* userspace may load modules and/or configure further */
call_policy ("add", dev);
@@ -1438,7 +1364,6 @@
return 0;
}
-
/**
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP
* @dev: device the buffer will be used with
@@ -1585,20 +1510,9 @@
: USB_DIR_OUT);
}
-#ifdef CONFIG_PROC_FS
-struct list_head *usb_driver_get_list(void)
-{
- return &usb_driver_list;
-}
-
-struct list_head *usb_bus_get_list(void)
-{
- return &usb_bus_list;
-}
-#endif
-
struct bus_type usb_bus_type = {
- .name = "usb",
+ .name = "usb",
+ .match = usb_device_match,
};
/*
@@ -1637,7 +1551,11 @@
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
-EXPORT_SYMBOL(usb_scan_devices);
+
+EXPORT_SYMBOL(usb_device_probe);
+EXPORT_SYMBOL(usb_device_remove);
+
+EXPORT_SYMBOL(usb_if_to_ifnum);
EXPORT_SYMBOL(usb_alloc_dev);
EXPORT_SYMBOL(usb_free_dev);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/input/hid-core.c linux-2.5.31-bk6-greg/drivers/usb/input/hid-core.c
--- linux-2.5.31-bk6/drivers/usb/input/hid-core.c Sat Aug 10 18:41:40 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/input/hid-core.c Fri Aug 23 12:13:26 2002
@@ -1338,9 +1338,10 @@
{ 0, 0 }
};
-static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
+static struct hid_device *usb_hid_configure(struct usb_interface *intf)
{
- struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
+ struct usb_interface_descriptor *interface = intf->altsetting + intf->act_altsetting;
+ struct usb_device *dev = interface_to_usbdev (intf);
struct hid_descriptor *hdesc;
struct hid_device *hid;
unsigned quirks = 0, rsize = 0;
@@ -1450,7 +1451,7 @@
snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
usb_make_path(dev, buf, 64);
- snprintf(hid->phys, 64, "%s/input%d", buf, ifnum);
+ snprintf(hid->phys, 64, "%s/input%d", buf, intf->altsetting[0].bInterfaceNumber);
if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
hid->uniq[0] = 0;
@@ -1472,9 +1473,12 @@
return NULL;
}
-static void hid_disconnect(struct usb_device *dev, void *ptr)
+static void hid_disconnect(struct usb_interface *intf)
{
- struct hid_device *hid = ptr;
+ struct hid_device *hid = intf->dev.driver_data;
+
+ if (!hid)
+ return;
usb_unlink_urb(hid->urbin);
usb_unlink_urb(hid->urbout);
@@ -1491,20 +1495,20 @@
usb_free_urb(hid->urbout);
hid_free_device(hid);
+ intf->dev.driver_data = NULL;
}
-static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
+static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id)
{
struct hid_device *hid;
char path[64];
int i;
char *c;
- dbg("HID probe called for ifnum %d", ifnum);
+ dbg("HID probe called for ifnum %d", intf->ifnum);
- if (!(hid = usb_hid_configure(dev, ifnum)))
- return NULL;
+ if (!(hid = usb_hid_configure(intf)))
+ return -EIO;
hid_init_reports(hid);
hid_dump_device(hid);
@@ -1516,9 +1520,11 @@
if (!hiddev_connect(hid))
hid->claimed |= HID_CLAIMED_HIDDEV;
+ intf->dev.driver_data = hid;
+
if (!hid->claimed) {
- hid_disconnect(dev, hid);
- return NULL;
+ hid_disconnect(intf);
+ return -EIO;
}
printk(KERN_INFO);
@@ -1540,12 +1546,12 @@
}
}
- usb_make_path(dev, path, 63);
+ usb_make_path(interface_to_usbdev(intf), path, 63);
printk(": USB HID v%x.%02x %s [%s] on %s\n",
hid->version >> 8, hid->version & 0xff, c, hid->name, path);
- return hid;
+ return 0;
}
static struct usb_device_id hid_usb_ids [] = {
@@ -1558,8 +1564,8 @@
static struct usb_driver hid_driver = {
.name = "hid",
- .probe = hid_probe,
- .disconnect = hid_disconnect,
+ .new_probe = hid_probe,
+ .new_disco = hid_disconnect,
.id_table = hid_usb_ids,
};
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/input/usbmouse.c linux-2.5.31-bk6-greg/drivers/usb/input/usbmouse.c
--- linux-2.5.31-bk6/drivers/usb/input/usbmouse.c Sat Aug 10 18:41:55 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/input/usbmouse.c Fri Aug 23 12:13:26 2002
@@ -98,10 +98,9 @@
usb_unlink_urb(mouse->irq);
}
-static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
+static int usb_mouse_new_probe(struct usb_interface * intf, const struct usb_device_id * id)
{
- struct usb_interface *iface;
+ struct usb_device * dev = interface_to_usbdev(intf);
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_mouse *mouse;
@@ -109,25 +108,28 @@
char path[64];
char *buf;
- iface = &dev->actconfig->interface[ifnum];
- interface = &iface->altsetting[iface->act_altsetting];
+ interface = &intf->altsetting[intf->act_altsetting];
- if (interface->bNumEndpoints != 1) return NULL;
+ if (interface->bNumEndpoints != 1)
+ return -ENODEV;
endpoint = interface->endpoint + 0;
- if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
- if ((endpoint->bmAttributes & 3) != 3) return NULL;
+ if (!(endpoint->bEndpointAddress & 0x80))
+ return -ENODEV;
+ if ((endpoint->bmAttributes & 3) != 3)
+ return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL;
+ if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
+ return -ENOMEM;
memset(mouse, 0, sizeof(struct usb_mouse));
mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!mouse->irq) {
kfree(mouse);
- return NULL;
+ return -ENODEV;
}
mouse->usbdev = dev;
@@ -154,7 +156,7 @@
if (!(buf = kmalloc(63, GFP_KERNEL))) {
kfree(mouse);
- return NULL;
+ return -ENOMEM;
}
if (dev->descriptor.iManufacturer &&
@@ -174,19 +176,23 @@
usb_mouse_irq, mouse, endpoint->bInterval);
input_register_device(&mouse->dev);
-
printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
- return mouse;
+ intf->dev.driver_data = mouse;
+ return 0;
}
-static void usb_mouse_disconnect(struct usb_device *dev, void *ptr)
+static void usb_mouse_new_disco(struct usb_interface * intf)
{
- struct usb_mouse *mouse = ptr;
- usb_unlink_urb(mouse->irq);
- input_unregister_device(&mouse->dev);
- usb_free_urb(mouse->irq);
- kfree(mouse);
+ struct usb_mouse *mouse = intf->dev.driver_data;
+ intf->dev.driver_data = NULL;
+
+ if (mouse) {
+ usb_unlink_urb(mouse->irq);
+ input_unregister_device(&mouse->dev);
+ usb_free_urb(mouse->irq);
+ kfree(mouse);
+ }
}
static struct usb_device_id usb_mouse_id_table [] = {
@@ -197,10 +203,10 @@
MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
static struct usb_driver usb_mouse_driver = {
- .name = "usb_mouse",
- .probe = usb_mouse_probe,
- .disconnect = usb_mouse_disconnect,
- .id_table = usb_mouse_id_table,
+ .name = "usb_mouse",
+ .new_probe = usb_mouse_new_probe,
+ .new_disco = usb_mouse_new_disco,
+ .id_table = usb_mouse_id_table,
};
static int __init usb_mouse_init(void)
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/belkin_sa.c linux-2.5.31-bk6-greg/drivers/usb/serial/belkin_sa.c
--- linux-2.5.31-bk6/drivers/usb/serial/belkin_sa.c Sat Aug 10 18:41:40 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/belkin_sa.c Fri Aug 23 12:13:26 2002
@@ -114,6 +114,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver belkin_driver = {
+ .name = "belkin",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
/* All of the device info needed for the serial converters */
static struct usb_serial_device_type belkin_device = {
.owner = THIS_MODULE,
@@ -526,6 +533,7 @@
static int __init belkin_sa_init (void)
{
usb_serial_register (&belkin_device);
+ usb_register (&belkin_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -533,6 +541,7 @@
static void __exit belkin_sa_exit (void)
{
+ usb_deregister (&belkin_driver);
usb_serial_deregister (&belkin_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/cyberjack.c linux-2.5.31-bk6-greg/drivers/usb/serial/cyberjack.c
--- linux-2.5.31-bk6/drivers/usb/serial/cyberjack.c Sat Aug 10 18:41:53 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/cyberjack.c Fri Aug 23 12:13:26 2002
@@ -73,6 +73,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver cyberjack_driver = {
+ .name = "cyberjack",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static struct usb_serial_device_type cyberjack_device = {
.owner = THIS_MODULE,
.name = "Reiner SCT Cyberjack USB card reader",
@@ -461,6 +468,7 @@
static int __init cyberjack_init (void)
{
usb_serial_register (&cyberjack_device);
+ usb_register (&cyberjack_driver);
info(DRIVER_VERSION " " DRIVER_AUTHOR);
info(DRIVER_DESC);
@@ -470,6 +478,7 @@
static void __exit cyberjack_exit (void)
{
+ usb_deregister (&cyberjack_driver);
usb_serial_deregister (&cyberjack_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/digi_acceleport.c linux-2.5.31-bk6-greg/drivers/usb/serial/digi_acceleport.c
--- linux-2.5.31-bk6/drivers/usb/serial/digi_acceleport.c Sat Aug 10 18:41:28 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/digi_acceleport.c Fri Aug 23 12:13:26 2002
@@ -477,7 +477,7 @@
/* Statics */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
{ } /* Terminating entry */
@@ -495,6 +495,14 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver digi_driver = {
+ .name = "digi_acceleport",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
+
/* device info needed for the Digi serial converter */
static struct usb_serial_device_type digi_acceleport_2_device = {
@@ -2026,6 +2034,7 @@
{
usb_serial_register (&digi_acceleport_2_device);
usb_serial_register (&digi_acceleport_4_device);
+ usb_register (&digi_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -2033,6 +2042,7 @@
static void __exit digi_exit (void)
{
+ usb_deregister (&digi_driver);
usb_serial_deregister (&digi_acceleport_2_device);
usb_serial_deregister (&digi_acceleport_4_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/empeg.c linux-2.5.31-bk6-greg/drivers/usb/serial/empeg.c
--- linux-2.5.31-bk6/drivers/usb/serial/empeg.c Sat Aug 10 18:41:28 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/empeg.c Fri Aug 23 12:13:26 2002
@@ -110,6 +110,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver empeg_driver = {
+ .name = "empeg",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static struct usb_serial_device_type empeg_device = {
.owner = THIS_MODULE,
.name = "Empeg",
@@ -550,8 +557,6 @@
struct urb *urb;
int i;
- usb_serial_register (&empeg_device);
-
/* create our write urb pool and transfer buffers */
spin_lock_init (&write_urb_pool_lock);
for (i = 0; i < NUM_URBS; ++i) {
@@ -570,10 +575,12 @@
}
}
+ usb_serial_register (&empeg_device);
+ usb_register (&empeg_driver);
+
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
-
}
@@ -582,6 +589,7 @@
int i;
unsigned long flags;
+ usb_register (&empeg_driver);
usb_serial_deregister (&empeg_device);
spin_lock_irqsave (&write_urb_pool_lock, flags);
@@ -599,7 +607,6 @@
}
spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/ftdi_sio.c linux-2.5.31-bk6-greg/drivers/usb/serial/ftdi_sio.c
--- linux-2.5.31-bk6/drivers/usb/serial/ftdi_sio.c Sat Aug 10 18:41:23 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/ftdi_sio.c Fri Aug 23 12:13:26 2002
@@ -140,7 +140,7 @@
};
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
@@ -149,6 +149,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver ftdi_driver = {
+ .name = "ftdi_sio",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
struct ftdi_private {
enum ftdi_type ftdi_type;
@@ -944,6 +951,7 @@
dbg(__FUNCTION__);
usb_serial_register (&ftdi_sio_device);
usb_serial_register (&ftdi_8U232AM_device);
+ usb_register (&ftdi_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -952,6 +960,7 @@
static void __exit ftdi_sio_exit (void)
{
dbg(__FUNCTION__);
+ usb_deregister (&ftdi_driver);
usb_serial_deregister (&ftdi_sio_device);
usb_serial_deregister (&ftdi_8U232AM_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/io_edgeport.c linux-2.5.31-bk6-greg/drivers/usb/serial/io_edgeport.c
--- linux-2.5.31-bk6/drivers/usb/serial/io_edgeport.c Sat Aug 10 18:41:19 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/io_edgeport.c Fri Aug 23 12:13:26 2002
@@ -457,6 +457,12 @@
#include "io_tables.h" /* all of the devices that this driver supports */
+static struct usb_driver io_driver = {
+ .name = "io_edgeport",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
/* function prototypes for all of our local functions */
static int process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength);
@@ -3049,6 +3055,7 @@
usb_serial_register (&edgeport_2port_device);
usb_serial_register (&edgeport_4port_device);
usb_serial_register (&edgeport_8port_device);
+ usb_register (&io_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -3061,6 +3068,7 @@
****************************************************************************/
void __exit edgeport_exit (void)
{
+ usb_deregister (&io_driver);
usb_serial_deregister (&edgeport_1port_device);
usb_serial_deregister (&edgeport_2port_device);
usb_serial_deregister (&edgeport_4port_device);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/io_tables.h linux-2.5.31-bk6-greg/drivers/usb/serial/io_tables.h
--- linux-2.5.31-bk6/drivers/usb/serial/io_tables.h Sat Aug 10 18:41:19 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/io_tables.h Fri Aug 23 12:13:26 2002
@@ -61,7 +61,7 @@
};
/* Devices that this driver supports */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) },
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/io_ti.c linux-2.5.31-bk6-greg/drivers/usb/serial/io_ti.c
--- linux-2.5.31-bk6/drivers/usb/serial/io_ti.c Sat Aug 10 18:41:27 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/io_ti.c Fri Aug 23 12:13:26 2002
@@ -142,7 +142,7 @@
};
/* Devices that this driver supports */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) },
{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) },
@@ -161,6 +161,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver io_driver = {
+ .name = "io_ti",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion;
@@ -2658,12 +2665,14 @@
{
usb_serial_register (&edgeport_1port_device);
usb_serial_register (&edgeport_2port_device);
+ usb_register (&io_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
static void __exit edgeport_exit (void)
{
+ usb_deregister (&io_driver);
usb_serial_deregister (&edgeport_1port_device);
usb_serial_deregister (&edgeport_2port_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/ipaq.c linux-2.5.31-bk6-greg/drivers/usb/serial/ipaq.c
--- linux-2.5.31-bk6/drivers/usb/serial/ipaq.c Sat Aug 10 18:41:24 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/ipaq.c Fri Aug 23 12:13:26 2002
@@ -94,6 +94,14 @@
MODULE_DEVICE_TABLE (usb, ipaq_id_table);
+static struct usb_driver ipaq_driver = {
+ .name = "ipaq",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = ipaq_id_table,
+};
+
+
/* All of the device info needed for the Compaq iPAQ */
struct usb_serial_device_type ipaq_device = {
.owner = THIS_MODULE,
@@ -516,6 +524,7 @@
static int __init ipaq_init(void)
{
usb_serial_register(&ipaq_device);
+ usb_register(&ipaq_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -524,6 +533,7 @@
static void __exit ipaq_exit(void)
{
+ usb_deregister(&ipaq_driver);
usb_serial_deregister(&ipaq_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/ir-usb.c linux-2.5.31-bk6-greg/drivers/usb/serial/ir-usb.c
--- linux-2.5.31-bk6/drivers/usb/serial/ir-usb.c Sat Aug 10 18:41:28 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/ir-usb.c Fri Aug 23 12:13:26 2002
@@ -129,6 +129,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver ir_driver = {
+ .name = "ir-usb",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
struct usb_serial_device_type ir_device = {
.owner = THIS_MODULE,
@@ -606,6 +613,7 @@
static int __init ir_init (void)
{
usb_serial_register (&ir_device);
+ usb_register (&ir_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -613,6 +621,7 @@
static void __exit ir_exit (void)
{
+ usb_deregister (&ir_driver);
usb_serial_deregister (&ir_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/keyspan.c linux-2.5.31-bk6-greg/drivers/usb/serial/keyspan.c
--- linux-2.5.31-bk6/drivers/usb/serial/keyspan.c Sat Aug 10 18:41:20 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/keyspan.c Fri Aug 23 12:13:26 2002
@@ -183,6 +183,7 @@
usb_serial_register (&keyspan_1port_device);
usb_serial_register (&keyspan_2port_device);
usb_serial_register (&keyspan_4port_device);
+ usb_register (&keyspan_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
@@ -191,6 +192,7 @@
static void __exit keyspan_exit (void)
{
+ usb_deregister (&keyspan_driver);
usb_serial_deregister (&keyspan_pre_device);
usb_serial_deregister (&keyspan_1port_device);
usb_serial_deregister (&keyspan_2port_device);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/keyspan.h linux-2.5.31-bk6-greg/drivers/usb/serial/keyspan.h
--- linux-2.5.31-bk6/drivers/usb/serial/keyspan.h Sat Aug 10 18:41:42 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/keyspan.h Fri Aug 23 12:13:26 2002
@@ -408,7 +408,7 @@
NULL,
};
-static __devinitdata struct usb_device_id keyspan_ids_combined[] = {
+static struct usb_device_id keyspan_ids_combined[] = {
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
@@ -434,6 +434,13 @@
MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
+static struct usb_driver keyspan_driver = {
+ .name = "keyspan",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = keyspan_ids_combined,
+};
+
/* usb_device_id table for the pre-firmware download keyspan devices */
static struct usb_device_id keyspan_pre_ids[] = {
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/keyspan_pda.c linux-2.5.31-bk6-greg/drivers/usb/serial/keyspan_pda.c
--- linux-2.5.31-bk6/drivers/usb/serial/keyspan_pda.c Sat Aug 10 18:41:42 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/keyspan_pda.c Fri Aug 23 12:13:26 2002
@@ -140,7 +140,7 @@
#define ENTREGRA_VENDOR_ID 0x1645
#define ENTREGRA_FAKE_ID 0x8093
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
#ifdef KEYSPAN
{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
#endif
@@ -154,6 +154,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver keyspan_pda_driver = {
+ .name = "keyspan_pda",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
static struct usb_device_id id_table_std [] = {
{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
{ } /* Terminating entry */
@@ -862,6 +869,7 @@
#ifdef XIRCOM
usb_serial_register (&xircom_pgs_fake_device);
#endif
+ usb_register (&keyspan_pda_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -869,6 +877,7 @@
static void __exit keyspan_pda_exit (void)
{
+ usb_deregister (&keyspan_pda_driver);
usb_serial_deregister (&keyspan_pda_device);
#ifdef KEYSPAN
usb_serial_deregister (&keyspan_pda_fake_device);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/kl5kusb105.c linux-2.5.31-bk6-greg/drivers/usb/serial/kl5kusb105.c
--- linux-2.5.31-bk6/drivers/usb/serial/kl5kusb105.c Sat Aug 10 18:41:36 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/kl5kusb105.c Fri Aug 23 12:13:26 2002
@@ -117,6 +117,12 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver kl5kusb105d_driver = {
+ .name = "kl5kusb105d",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
static struct usb_serial_device_type kl5kusb105d_device = {
.owner = THIS_MODULE,
@@ -1013,6 +1019,7 @@
static int __init klsi_105_init (void)
{
usb_serial_register (&kl5kusb105d_device);
+ usb_register (&kl5kusb105d_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -1021,6 +1028,7 @@
static void __exit klsi_105_exit (void)
{
+ usb_deregister (&kl5kusb105d_driver);
usb_serial_deregister (&kl5kusb105d_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/mct_u232.c linux-2.5.31-bk6-greg/drivers/usb/serial/mct_u232.c
--- linux-2.5.31-bk6/drivers/usb/serial/mct_u232.c Sat Aug 10 18:41:42 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/mct_u232.c Fri Aug 23 12:13:26 2002
@@ -139,6 +139,12 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver mct_u232_driver = {
+ .name = "mct_u232",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
static struct usb_serial_device_type mct_u232_device = {
.owner = THIS_MODULE,
@@ -783,6 +789,7 @@
static int __init mct_u232_init (void)
{
usb_serial_register (&mct_u232_device);
+ usb_register (&mct_u232_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -790,6 +797,7 @@
static void __exit mct_u232_exit (void)
{
+ usb_deregister (&mct_u232_driver);
usb_serial_deregister (&mct_u232_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/omninet.c linux-2.5.31-bk6-greg/drivers/usb/serial/omninet.c
--- linux-2.5.31-bk6/drivers/usb/serial/omninet.c Sat Aug 10 18:41:25 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/omninet.c Fri Aug 23 12:13:26 2002
@@ -83,6 +83,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver omninet_driver = {
+ .name = "omninet",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static struct usb_serial_device_type zyxel_omninet_device = {
.owner = THIS_MODULE,
@@ -370,6 +377,7 @@
static int __init omninet_init (void)
{
usb_serial_register (&zyxel_omninet_device);
+ usb_register (&omninet_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -377,6 +385,7 @@
static void __exit omninet_exit (void)
{
+ usb_deregister (&omninet_driver);
usb_serial_deregister (&zyxel_omninet_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/pl2303.c linux-2.5.31-bk6-greg/drivers/usb/serial/pl2303.c
--- linux-2.5.31-bk6/drivers/usb/serial/pl2303.c Sat Aug 10 18:41:28 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/pl2303.c Fri Aug 23 12:13:26 2002
@@ -77,6 +77,12 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver pl2303_driver = {
+ .name = "pl2303",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
#define SET_LINE_REQUEST_TYPE 0x21
#define SET_LINE_REQUEST 0x20
@@ -708,6 +714,7 @@
static int __init pl2303_init (void)
{
usb_serial_register (&pl2303_device);
+ usb_register (&pl2303_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -715,6 +722,7 @@
static void __exit pl2303_exit (void)
{
+ usb_deregister (&pl2303_driver);
usb_serial_deregister (&pl2303_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/safe_serial.c linux-2.5.31-bk6-greg/drivers/usb/serial/safe_serial.c
--- linux-2.5.31-bk6/drivers/usb/serial/safe_serial.c Sat Aug 10 18:41:23 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/safe_serial.c Fri Aug 23 12:13:26 2002
@@ -161,6 +161,13 @@
MODULE_DEVICE_TABLE (usb, id_table);
+static struct usb_driver safe_driver = {
+ .name = "safe_serial",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
static __u16 crc10_table[256] = {
0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
@@ -434,12 +441,14 @@
}
usb_serial_register (&safe_device);
+ usb_register (&safe_driver);
return 0;
}
static void __exit safe_exit (void)
{
+ usb_deregister (&safe_driver);
usb_serial_deregister (&safe_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/usb-serial.h linux-2.5.31-bk6-greg/drivers/usb/serial/usb-serial.h
--- linux-2.5.31-bk6/drivers/usb/serial/usb-serial.h Sat Aug 10 18:41:30 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/usb-serial.h Fri Aug 23 12:13:26 2002
@@ -233,6 +233,9 @@
extern int usb_serial_register(struct usb_serial_device_type *new_device);
extern void usb_serial_deregister(struct usb_serial_device_type *device);
+extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
+extern void usb_serial_disconnect(struct usb_interface *iface);
+
/* determine if we should include the EzUSB loader functions */
#undef USES_EZUSB_FUNCTIONS
#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/usbserial.c linux-2.5.31-bk6-greg/drivers/usb/serial/usbserial.c
--- linux-2.5.31-bk6/drivers/usb/serial/usbserial.c Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/usbserial.c Fri Aug 23 12:13:26 2002
@@ -380,30 +380,23 @@
.num_ports = 1,
.shutdown = generic_shutdown,
};
-#endif
-
-/* local function prototypes */
-static int serial_open (struct tty_struct *tty, struct file * filp);
-static void serial_close (struct tty_struct *tty, struct file * filp);
-static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count);
-static int serial_write_room (struct tty_struct *tty);
-static int serial_chars_in_buffer (struct tty_struct *tty);
-static void serial_throttle (struct tty_struct * tty);
-static void serial_unthrottle (struct tty_struct * tty);
-static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
-static void serial_set_termios (struct tty_struct *tty, struct termios * old);
-static void serial_shutdown (struct usb_serial *serial);
-
-static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id);
-static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
+/* we want to look at all devices, as the vendor/product id can change
+ * depending on the command line argument */
+static struct usb_device_id generic_serial_ids[] = {
+ {.driver_info = 42},
+ {}
+};
+#endif
+/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
.name = "serial",
- .probe = usb_serial_probe,
- .disconnect = usb_serial_disconnect,
- .id_table = NULL, /* check all devices */
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+#ifdef CONFIG_USB_SERIAL_GENERIC
+ .id_table = generic_serial_ids,
+#endif
};
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
@@ -413,7 +406,6 @@
drivers depend on it.
*/
-
static int serial_refcount;
static struct tty_driver serial_tty_driver;
static struct tty_struct * serial_tty[SERIAL_TTY_MINORS];
@@ -1162,12 +1154,12 @@
return serial;
}
-static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
+int usb_serial_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
+ struct usb_device *dev = interface_to_usbdev (interface);
struct usb_serial *serial = NULL;
struct usb_serial_port *port;
- struct usb_interface *interface;
struct usb_interface_descriptor *iface_desc;
struct usb_endpoint_descriptor *endpoint;
struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
@@ -1190,7 +1182,6 @@
/* loop through our list of known serial converters, and see if this
device matches. */
found = 0;
- interface = &dev->actconfig->interface[ifnum];
list_for_each (tmp, &usb_serial_driver_list) {
type = list_entry(tmp, struct usb_serial_device_type, driver_list);
id_pattern = usb_match_id(interface, type->id_table);
@@ -1203,13 +1194,13 @@
if (!found) {
/* no match */
dbg("none matched");
- return(NULL);
+ return -ENODEV;
}
serial = create_serial (dev, interface, type);
if (!serial) {
err ("%s - out of memory", __FUNCTION__);
- return NULL;
+ return -ENODEV;
}
/* if this device type has a probe function, call it */
@@ -1223,7 +1214,7 @@
if (retval < 0) {
dbg ("sub driver rejected device");
kfree (serial);
- return NULL;
+ return -ENODEV;
}
}
@@ -1259,6 +1250,7 @@
}
#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
+#if 0
/* BEGIN HORRIBLE HACK FOR PL2303 */
/* this is needed due to the looney way its endpoints are set up */
if (ifnum == 1) {
@@ -1283,6 +1275,7 @@
}
/* END HORRIBLE HACK FOR PL2303 */
#endif
+#endif
/* found all that we need */
info("%s converter detected", type->name);
@@ -1293,7 +1286,7 @@
if (num_ports == 0) {
err("Generic device with no bulk out, not allowed.");
kfree (serial);
- return NULL;
+ return -EIO;
}
}
#endif
@@ -1313,7 +1306,7 @@
if (get_free_serial (serial, num_ports, &minor) == NULL) {
err("No more free serial devices");
kfree (serial);
- return NULL;
+ return -ENOMEM;
}
serial->minor = minor;
@@ -1425,7 +1418,8 @@
if (retval > 0) {
/* quietly accept this device, but don't bind to a serial port
* as it's about to disappear */
- return serial;
+ interface->dev.driver_data = serial;
+ return 0;
}
}
@@ -1456,7 +1450,9 @@
}
#endif
- return serial; /* success */
+ /* success */
+ interface->dev.driver_data = serial;
+ return 0;
probe_error:
@@ -1487,16 +1483,18 @@
/* free up any memory that we allocated */
kfree (serial);
- return NULL;
+ return -EIO;
}
-static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
+void usb_serial_disconnect(struct usb_interface *interface)
{
- struct usb_serial *serial = (struct usb_serial *) ptr;
+ struct usb_serial *serial = (struct usb_serial *)interface->dev.driver_data;
struct usb_serial_port *port;
int i;
dbg(__FUNCTION__);
+
+ interface->dev.driver_data = NULL;
if (serial) {
/* fail all future close/read/write/ioctl/etc calls */
for (i = 0; i < serial->num_ports; ++i) {
@@ -1555,10 +1553,8 @@
/* free up any memory that we allocated */
kfree (serial);
-
- } else {
- info("device disconnected");
}
+ info("device disconnected");
}
@@ -1660,8 +1656,6 @@
info ("USB Serial support registered for %s", new_device->name);
- usb_scan_devices();
-
return 0;
}
@@ -1678,7 +1672,7 @@
serial = serial_table[i];
if ((serial != NULL) && (serial->type == device)) {
usb_driver_release_interface (&usb_serial_driver, serial->interface);
- usb_serial_disconnect (NULL, serial);
+ usb_serial_disconnect (serial->interface);
}
}
@@ -1691,6 +1685,8 @@
need these symbols to load properly as modules. */
EXPORT_SYMBOL(usb_serial_register);
EXPORT_SYMBOL(usb_serial_deregister);
+EXPORT_SYMBOL(usb_serial_probe);
+EXPORT_SYMBOL(usb_serial_disconnect);
#ifdef USES_EZUSB_FUNCTIONS
EXPORT_SYMBOL(ezusb_writememory);
EXPORT_SYMBOL(ezusb_set_reset);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/visor.c linux-2.5.31-bk6-greg/drivers/usb/serial/visor.c
--- linux-2.5.31-bk6/drivers/usb/serial/visor.c Sat Aug 10 18:41:25 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/visor.c Fri Aug 23 12:13:26 2002
@@ -197,7 +197,7 @@
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
@@ -214,7 +214,12 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
-
+static struct usb_driver visor_driver = {
+ .name = "visor",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
static struct usb_serial_device_type handspring_device = {
@@ -761,6 +766,7 @@
{
usb_serial_register (&handspring_device);
usb_serial_register (&clie_3_5_device);
+ usb_register (&visor_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -769,6 +775,7 @@
static void __exit visor_exit (void)
{
+ usb_deregister (&visor_driver);
usb_serial_deregister (&handspring_device);
usb_serial_deregister (&clie_3_5_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/serial/whiteheat.c linux-2.5.31-bk6-greg/drivers/usb/serial/whiteheat.c
--- linux-2.5.31-bk6/drivers/usb/serial/whiteheat.c Sat Aug 10 18:41:26 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/serial/whiteheat.c Fri Aug 23 12:13:26 2002
@@ -110,7 +110,7 @@
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
{ } /* Terminating entry */
@@ -118,6 +118,13 @@
MODULE_DEVICE_TABLE (usb, id_table_combined);
+static struct usb_driver whiteheat_driver = {
+ .name = "whiteheat",
+ .new_probe = usb_serial_probe,
+ .new_disco = usb_serial_disconnect,
+ .id_table = id_table_combined,
+};
+
/* function prototypes for the Connect Tech WhiteHEAT serial converter */
static int whiteheat_open (struct usb_serial_port *port, struct file *filp);
static void whiteheat_close (struct usb_serial_port *port, struct file *filp);
@@ -676,6 +683,7 @@
{
usb_serial_register (&whiteheat_fake_device);
usb_serial_register (&whiteheat_device);
+ usb_register (&whiteheat_driver);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -683,6 +691,7 @@
static void __exit whiteheat_exit (void)
{
+ usb_deregister (&whiteheat_driver);
usb_serial_deregister (&whiteheat_fake_device);
usb_serial_deregister (&whiteheat_device);
}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/storage/scsiglue.c linux-2.5.31-bk6-greg/drivers/usb/storage/scsiglue.c
--- linux-2.5.31-bk6/drivers/usb/storage/scsiglue.c Fri Aug 23 11:53:49 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/storage/scsiglue.c Fri Aug 23 12:13:26 2002
@@ -252,7 +252,6 @@
for (i = 0; i < pusb_dev_save->actconfig->bNumInterfaces; i++) {
struct usb_interface *intf =
&pusb_dev_save->actconfig->interface[i];
- const struct usb_device_id *id;
/* if this is an unclaimed interface, skip it */
if (!intf->driver) {
@@ -263,11 +262,8 @@
/* simulate a disconnect and reconnect for all interfaces */
US_DEBUGPX("simulating disconnect/reconnect.\n");
- down(&intf->driver->serialize);
- intf->driver->disconnect(pusb_dev_save, intf->private_data);
- id = usb_match_id(intf, intf->driver->id_table);
- intf->driver->probe(pusb_dev_save, i, id);
- up(&intf->driver->serialize);
+ usb_device_remove (&intf->dev);
+ usb_device_probe (&intf->dev);
}
US_DEBUGP("bus_reset() complete\n");
scsi_lock(srb->host);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/drivers/usb/storage/usb.c linux-2.5.31-bk6-greg/drivers/usb/storage/usb.c
--- linux-2.5.31-bk6/drivers/usb/storage/usb.c Sat Aug 10 18:41:24 2002
+++ linux-2.5.31-bk6-greg/drivers/usb/storage/usb.c Fri Aug 23 12:13:26 2002
@@ -103,10 +103,10 @@
struct us_data *us_list;
struct semaphore us_list_semaphore;
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id);
+static int storage_probe(struct usb_interface *iface,
+ const struct usb_device_id *id);
-static void storage_disconnect(struct usb_device *dev, void *ptr);
+static void storage_disconnect(struct usb_interface *iface);
/* The entries in this table, except for final ones here
* (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
@@ -229,8 +229,8 @@
struct usb_driver usb_storage_driver = {
.name = "usb-storage",
- .probe = storage_probe,
- .disconnect = storage_disconnect,
+ .new_probe = storage_probe,
+ .new_disco = storage_disconnect,
.id_table = storage_usb_ids,
};
@@ -583,9 +583,11 @@
}
/* Probe to see if a new device is actually a SCSI device */
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
+static int storage_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ int ifnum = usb_if_to_ifnum(intf);
int i;
const int id_index = id - storage_usb_ids;
char mf[USB_STOR_STRING_LEN]; /* manufacturer */
@@ -610,7 +612,6 @@
/* the altsetting on the interface we're probing that matched our
* usb_match_id table
*/
- struct usb_interface *intf = dev->actconfig->interface;
struct usb_interface_descriptor *altsetting =
intf[ifnum].altsetting + intf[ifnum].act_altsetting;
US_DEBUGP("act_altsetting is %d\n", intf[ifnum].act_altsetting);
@@ -640,7 +641,7 @@
US_DEBUGP("Product: %s\n", unusual_dev->productName);
} else
/* no, we can't support it */
- return NULL;
+ return -EIO;
/* At this point, we know we've got a live one */
US_DEBUGP("USB Mass Storage device detected\n");
@@ -689,7 +690,7 @@
} else if (result != 0) {
/* it's not a stall, but another error -- time to bail */
US_DEBUGP("-- Unknown error. Rejecting device\n");
- return NULL;
+ return -EIO;
}
}
#endif
@@ -697,7 +698,7 @@
/* Do some basic sanity checks, and bail if we find a problem */
if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) {
US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n");
- return NULL;
+ return -EIO;
}
/* At this point, we've decided to try to use the device */
@@ -776,7 +777,7 @@
GFP_KERNEL)) == NULL) {
printk(KERN_WARNING USB_STORAGE "Out of memory\n");
usb_put_dev(dev);
- return NULL;
+ return -ENOMEM;
}
memset(ss, 0, sizeof(struct us_data));
new_device = 1;
@@ -1053,8 +1054,9 @@
printk(KERN_DEBUG
"USB Mass Storage device found at %d\n", dev->devnum);
- /* return a pointer for the disconnect function */
- return ss;
+ /* save a pointer to our structure */
+ intf->dev.driver_data = ss;
+ return 0;
/* we come here if there are any problems */
/* ss->dev_semaphore must be locked */
@@ -1064,16 +1066,18 @@
up(&ss->dev_semaphore);
if (new_device)
kfree(ss);
- return NULL;
+ return -EIO;
}
/* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_device *dev, void *ptr)
+static void storage_disconnect(struct usb_interface *intf)
{
- struct us_data *ss = ptr;
+ struct us_data *ss = intf->dev.driver_data;
US_DEBUGP("storage_disconnect() called\n");
+ intf->dev.driver_data = NULL;
+
/* this is the odd case -- we disconnected but weren't using it */
if (!ss) {
US_DEBUGP("-- device was not in use\n");
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.31-bk6/include/linux/usb.h linux-2.5.31-bk6-greg/include/linux/usb.h
--- linux-2.5.31-bk6/include/linux/usb.h Fri Aug 23 11:53:58 2002
+++ linux-2.5.31-bk6-greg/include/linux/usb.h Fri Aug 23 12:13:26 2002
@@ -248,7 +248,7 @@
int act_altsetting; /* active alternate setting */
int num_altsetting; /* number of alternate settings */
int max_altsetting; /* total memory allocated */
-
+
struct usb_driver *driver; /* driver */
struct device dev; /* interface specific device info */
void *private_data;
@@ -312,6 +312,8 @@
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
type,(void**)ptr)
+extern int usb_if_to_ifnum(struct usb_interface *iface);
+
/* -------------------------------------------------------------------------- */
/* Host Controller Driver (HCD) support */
@@ -428,9 +430,6 @@
extern void usb_free_dev(struct usb_device *);
#define usb_put_dev usb_free_dev
-/* for when layers above USB add new non-USB drivers */
-extern void usb_scan_devices(void);
-
/* mostly for devices emulating SCSI over USB */
extern int usb_reset_device(struct usb_device *dev);
@@ -674,6 +673,11 @@
struct module *owner;
const char *name;
+ int (*new_probe) (struct usb_interface *intf, const struct usb_device_id *id);
+ void (*new_disco) (struct usb_interface *intf);
+
+ struct device_driver driver;
+
void *(*probe)(
struct usb_device *dev, /* the device */
unsigned intf, /* what interface */
@@ -684,7 +688,6 @@
void *handle /* as returned by probe() */
);
- struct list_head driver_list;
struct semaphore serialize;
/* ioctl -- userspace apps can talk to drivers through usbfs */
@@ -698,6 +701,7 @@
/* void (*suspend)(struct usb_device *dev); */
/* void (*resume)(struct usb_device *dev); */
};
+#define to_usb_driver(d) container_of(d, struct usb_driver, driver)
extern struct bus_type usb_bus_type;
@@ -711,6 +715,9 @@
extern int usb_register_dev(struct file_operations *fops, int minor, int num_minors, int *start_minor);
extern void usb_deregister_dev(int num_minors, int start_minor);
+extern int usb_device_probe(struct device *dev);
+extern int usb_device_remove(struct device *dev);
+
/* -------------------------------------------------------------------------- */
/*
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [linux-usb-devel] [RFC] USB driver conversion to "struct device_driver" for 2.5.32
[not found] ` <20020829221339.GA5074@kroah.com>
@ 2002-08-29 23:50 ` David Brownell
2002-08-30 3:46 ` Greg KH
0 siblings, 1 reply; 4+ messages in thread
From: David Brownell @ 2002-08-29 23:50 UTC (permalink / raw)
To: Greg KH; +Cc: linux-usb-devel, linux-kernel, Patrick Mochel
So to be sure I've got this right ... those modified driver
entry points change things as follows:
> + int (*probe) (struct usb_interface *intf,
> + const struct usb_device_id *id);
(a) the device (for urbs etc) is now implicit:
struct usb_device *dev = interface_to_usbdev (int):
(b) the interface index should no longer matter
(c) returns 0 (not void *) or -Errno (not null)
(d) that void * handle is explicitly intf->dev.driver_data
> + void (*disconnect) (struct usb_interface *intf);
(a) and (d) above: same change
Makes me wonder about intf->private_data, which was the
original version of intf->dev.driver_data. Shouldn't that
be removed too? It's only used in the interface claiming
calls (shouldn't they fit in with the driver model?) and
usbfs just now. Is that the usbfs work you mentioned?
- Dave
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [linux-usb-devel] [RFC] USB driver conversion to "struct device_driver" for 2.5.32
2002-08-29 23:50 ` [linux-usb-devel] [RFC] USB driver conversion to "struct device_driver" for 2.5.32 David Brownell
@ 2002-08-30 3:46 ` Greg KH
0 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2002-08-30 3:46 UTC (permalink / raw)
To: David Brownell; +Cc: linux-usb-devel, linux-kernel, Patrick Mochel
For the lkml readers, my original post (with patch) didn't seem to go
through to that list, it can be found at:
http://marc.theaimsgroup.com/?l=linux-usb-devel&m=103065990107372
On Thu, Aug 29, 2002 at 04:50:11PM -0700, David Brownell wrote:
> So to be sure I've got this right ... those modified driver
> entry points change things as follows:
>
> >+ int (*probe) (struct usb_interface *intf,
> >+ const struct usb_device_id *id);
>
> (a) the device (for urbs etc) is now implicit:
> struct usb_device *dev = interface_to_usbdev (int):
Yes.
> (b) the interface index should no longer matter
Yes. But for those drivers that do care, they can get it with the new
usb_if_to_ifnum() function. This will provide the _correct_ interface
number, the old interface only provided the index, which people seemed
to use as the ifnum.
> (c) returns 0 (not void *) or -Errno (not null)
Yes.
> (d) that void * handle is explicitly intf->dev.driver_data
Yes. dev.driver_data should be wrapped by a function, like
pci_set_drvdata() and pci_get_drvdata() are for.
> >+ void (*disconnect) (struct usb_interface *intf);
>
> (a) and (d) above: same change
exactly.
> Makes me wonder about intf->private_data, which was the
> original version of intf->dev.driver_data. Shouldn't that
> be removed too?
Yes it should.
> It's only used in the interface claiming calls (shouldn't they fit in
> with the driver model?) and usbfs just now. Is that the usbfs work
> you mentioned?
Yes, that's the part that I am pretty sure is not working properly right
now, and is next on my list of things to clean up.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2002-08-30 3:43 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-22 20:44 [RFC] USB driver conversion to "struct device_driver" for 2.5.31 Greg KH
2002-08-23 19:31 ` Greg KH
[not found] ` <20020829221339.GA5074@kroah.com>
2002-08-29 23:50 ` [linux-usb-devel] [RFC] USB driver conversion to "struct device_driver" for 2.5.32 David Brownell
2002-08-30 3:46 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox