Hi,
Here's Pat Mochel's patch to convert the USB core to using the new
driver model core. It's against 2.5.20, and has been forward ported
from 2.5.15, so some things might not be working properly. Also parts
of it are not good at all (the fs.c split is not ok to do for example).
I'm posting it here as an example of what needs to be done to convert
USB to this model.
If someone wants to take parts of this patch, test them, and then send
them to me / the list, I would really appreciate it. I've also put them
in a bk tree at:
bk://linuxusb.bkbits.net/usb-2.5-driverfs/
if people like to work with that.
The patch is also available at:
http://www.kernel.org/pub/linux/kernel/people/gregkh/usb/2.5/usb-driverfs-2.5.20.patch
thanks,
greg k-h
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/Makefile
linux-2.5-driverfs/drivers/usb/core/Makefile
--- ../linux-2.5/drivers/usb/core/Makefile Mon Jun 3 10:01:01 2002
+++ linux-2.5-driverfs/drivers/usb/core/Makefile Wed Jun 5 09:40:29 2002
@@ -11,6 +11,10 @@
usbcore-objs += devio.o inode.o drivers.o devices.o
endif
+ifeq ($(CONFIG_DEVFS),y)
+ usbcore-objs += fs.o
+endif
+
obj-$(CONFIG_USB) += usbcore.o
include $(TOPDIR)/Rules.make
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/devio.c
linux-2.5-driverfs/drivers/usb/core/devio.c
--- ../linux-2.5/drivers/usb/core/devio.c Tue May 28 09:11:55 2002
+++ linux-2.5-driverfs/drivers/usb/core/devio.c Mon Jun 3 11:29:16 2002
@@ -431,9 +431,9 @@
return -ENOENT;
}
+#if 0
extern struct list_head usb_driver_list;
-#if 0
static int finddriver(struct usb_driver **driver, char *name)
{
struct list_head *tmp;
@@ -1096,6 +1096,7 @@
else switch (ctrl.ioctl_code) {
/* disconnect kernel driver from interface, leaving it unbound. */
+#if 0
case USBDEVFS_DISCONNECT:
driver = ifp->driver;
if (driver) {
@@ -1113,7 +1114,7 @@
case USBDEVFS_CONNECT:
usb_find_interface_driver_for_ifnum (ps->dev, ctrl.ifno);
break;
-
+#endif
/* talk directly to the interface's driver */
default:
driver = ifp->driver;
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/drivers.c
linux-2.5-driverfs/drivers/usb/core/drivers.c
--- ../linux-2.5/drivers/usb/core/drivers.c Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/core/drivers.c Mon Jun 3 11:29:16 2002
@@ -50,7 +50,7 @@
*/
static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff_t
*ppos)
{
- struct list_head *tmp = usb_driver_list.next;
+ struct list_head *tmp = &usb_bus_type.drivers.next
char *page, *start, *end;
ssize_t ret = 0;
unsigned int pos, len;
@@ -66,7 +66,7 @@
start = page;
end = page + (PAGE_SIZE - 100);
pos = *ppos;
- for (; tmp != &usb_driver_list; tmp = tmp->next) {
+ for (; tmp != &usb_bus_type.drivers; tmp = tmp->next) {
struct usb_driver *driver = list_entry(tmp, struct usb_driver,
driver_list);
int minor = driver->fops ? driver->minor : -1;
if (minor == -1)
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/fs.c
linux-2.5-driverfs/drivers/usb/core/fs.c
--- ../linux-2.5/drivers/usb/core/fs.c Wed Dec 31 16:00:00 1969
+++ linux-2.5-driverfs/drivers/usb/core/fs.c Mon Jun 3 11:09:08 2002
@@ -0,0 +1,61 @@
+
+#include <linux/usb.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/module.h>
+
+devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
+
+
+static int usb_open(struct inode * inode, struct file * file)
+{
+ int minor = minor(inode->i_rdev);
+ struct usb_driver *c;
+ int err = -ENODEV;
+ struct file_operations *old_fops, *new_fops = NULL;
+
+ spin_lock (&minor_lock);
+ c = usb_minors[minor];
+ spin_unlock (&minor_lock);
+
+ if (!c || !(new_fops = fops_get(c->fops)))
+ return err;
+ old_fops = file->f_op;
+ file->f_op = new_fops;
+ /* Curiouser and curiouser... NULL ->open() as "no device" ? */
+ if (file->f_op->open)
+ err = file->f_op->open(inode,file);
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
+ return err;
+}
+
+static struct file_operations usb_fops = {
+ owner: THIS_MODULE,
+ open: usb_open,
+};
+
+static int __init usb_major_init(void)
+{
+ if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) {
+ err("unable to get major %d for usb devices", USB_MAJOR);
+ return -EBUSY;
+ }
+
+ usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
+
+ return 0;
+}
+
+static void __exit usb_major_cleanup(void)
+{
+ devfs_unregister(usb_devfs_handle);
+ devfs_unregister_chrdev(USB_MAJOR, "usb");
+}
+
+subsys_initcall(usb_major_init);
+module_exit(usb_major_cleanup);
+
+EXPORT_SYMBOL(usb_devfs_handle);
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hcd.c
linux-2.5-driverfs/drivers/usb/core/hcd.c
--- ../linux-2.5/drivers/usb/core/hcd.c Wed May 29 12:39:43 2002
+++ linux-2.5-driverfs/drivers/usb/core/hcd.c Mon Jun 3 11:29:16 2002
@@ -730,15 +730,7 @@
*/
int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev)
{
- 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);
- if (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 ../dontdiff ../linux-2.5/drivers/usb/core/hcd.h
linux-2.5-driverfs/drivers/usb/core/hcd.h
--- ../linux-2.5/drivers/usb/core/hcd.h Mon Jun 3 10:24:32 2002
+++ linux-2.5-driverfs/drivers/usb/core/hcd.h Mon Jun 3 11:29:16 2002
@@ -182,7 +182,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 **);
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hub.c
linux-2.5-driverfs/drivers/usb/core/hub.c
--- ../linux-2.5/drivers/usb/core/hub.c Wed May 29 12:39:43 2002
+++ linux-2.5-driverfs/drivers/usb/core/hub.c Mon Jun 3 11:29:16 2002
@@ -250,49 +250,17 @@
/* Enable power to the ports */
dbg("enabling power on all ports");
for (i = 0; i < hub->descriptor->bNbrPorts; i++)
- usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+ usb_set_port_feature(hub->intf->usb_device, i + 1,
+USB_PORT_FEAT_POWER);
/* Wait for power to be enabled */
wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
}
-static int usb_hub_configure(struct usb_hub *hub,
- struct usb_endpoint_descriptor *endpoint)
+static void usb_hub_report(struct usb_hub * hub)
{
- struct usb_device *dev = hub->dev;
- struct usb_hub_status hubstatus;
+ struct usb_device *dev = hub->intf->usb_device;
char portstr[USB_MAXCHILDREN + 1];
- unsigned int pipe;
- int i, maxp, ret;
-
- hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
- if (!hub->descriptor) {
- err("Unable to kmalloc %Zd bytes for hub descriptor",
- sizeof(*hub->descriptor));
- return -1;
- }
-
- /* Request the entire hub descriptor.
- * hub->descriptor can handle USB_MAXCHILDREN ports,
- * but the hub can/will return fewer bytes here.
- */
- ret = usb_get_hub_descriptor(dev, hub->descriptor,
- sizeof(*hub->descriptor));
- if (ret < 0) {
- err("Unable to get hub descriptor (err = %d)", ret);
- kfree(hub->descriptor);
- return -1;
- } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
- err("Hub is too big! %d children", hub->descriptor->bNbrPorts);
- kfree(hub->descriptor);
- return -1;
- }
-
- dev->maxchild = hub->descriptor->bNbrPorts;
- info("%d port%s detected", dev->maxchild,
- (dev->maxchild == 1) ? "" : "s");
-
- le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+ int i;
if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
dbg("part of a compound device");
@@ -376,14 +344,51 @@
[((i + 1) / 8)] & (1 << ((i + 1) % 8))
? 'F' : 'R';
portstr[dev->maxchild] = 0;
-
dbg("port removable status: %s", portstr);
+}
+
+static int usb_hub_configure(struct usb_hub *hub,
+ struct usb_endpoint_descriptor *endpoint)
+{
+ struct usb_device *dev = hub->intf->usb_device;
+ struct usb_hub_status hubstatus;
+ unsigned int pipe;
+ int maxp, ret;
+ int error = -EIO;
+
+ hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+ if (!hub->descriptor) {
+ err("Unable to kmalloc %Zd bytes for hub descriptor",
+ sizeof(*hub->descriptor));
+ goto Done;
+ }
+
+ /* Request the entire hub descriptor.
+ * hub->descriptor can handle USB_MAXCHILDREN ports,
+ * but the hub can/will return fewer bytes here.
+ */
+ ret = usb_get_hub_descriptor(dev, hub->descriptor,
+ sizeof(*hub->descriptor));
+ if (ret < 0) {
+ err("Unable to get hub descriptor (err = %d)", ret);
+ goto Done;
+ } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
+ err("Hub is too big! %d children", hub->descriptor->bNbrPorts);
+ goto Done;
+ }
+
+ dev->maxchild = hub->descriptor->bNbrPorts;
+ info("%d port%s detected", dev->maxchild,
+ (dev->maxchild == 1) ? "" : "s");
+
+ le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+
+ usb_hub_report(hub);
ret = usb_get_hub_status(dev, &hubstatus);
if (ret < 0) {
err("Unable to get hub status (err = %d)", ret);
- kfree(hub->descriptor);
- return -1;
+ goto Done;
}
le16_to_cpus(&hubstatus.wHubStatus);
@@ -405,147 +410,135 @@
hub->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!hub->urb) {
err("couldn't allocate interrupt urb");
- kfree(hub->descriptor);
- return -1;
+ goto Done;
}
FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
hub, endpoint->bInterval);
ret = usb_submit_urb(hub->urb, GFP_KERNEL);
- if (ret) {
+ if (!ret) {
+ /* Wake up khubd */
+ wake_up(&khubd_wait);
+
+ usb_hub_power_on(hub);
+ error = 0;
+ } else
err("usb_submit_urb failed (%d)", ret);
+ Done:
+ if (error && hub->descriptor)
kfree(hub->descriptor);
- return -1;
+ return error;
+}
+
+static void hub_disconnect(struct usb_interface *intf)
+{
+ 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_init(&hub->event_list);
+ list_del_init(&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);
+
+ if (hub->urb) {
+ usb_unlink_urb(hub->urb);
+ usb_free_urb(hub->urb);
+ hub->urb = NULL;
}
-
- /* Wake up khubd */
- wake_up(&khubd_wait);
- usb_hub_power_on(hub);
+ if (hub->descriptor) {
+ kfree(hub->descriptor);
+ hub->descriptor = NULL;
+ }
- return 0;
+ /* Free the memory */
+ kfree(hub);
+ intf->dev.driver_data = NULL;
}
-static void *hub_probe(struct usb_device *dev, unsigned int i,
- const struct usb_device_id *id)
+static int hub_probe(struct usb_interface * intf)
{
- struct usb_interface_descriptor *interface;
+ struct usb_interface_descriptor *desc;
struct usb_endpoint_descriptor *endpoint;
- struct usb_hub *hub;
- unsigned long flags;
- interface = &dev->actconfig->interface[i].altsetting[0];
+ desc = intf->altsetting + intf->act_altsetting;
/* 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, intf->usb_device->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, intf->usb_device->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;
+ intf->usb_device->devnum);
+ return -EIO;
}
/* If it's not an interrupt endpoint, we'd better punt! */
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
!= USB_ENDPOINT_XFER_INT) {
err("Device #%d is hub class, but endpoint is not interrupt?",
- dev->devnum);
- return NULL;
+ intf->usb_device->devnum);
+ return -EIO;
}
/* We found a hub */
- info("USB hub found at %s", dev->devpath);
+ info("USB hub found at %s", intf->usb_device->devpath);
+
+ return 0;
+}
+
+static int hub_init(struct usb_interface * intf)
+{
+ struct usb_hub * hub;
+ unsigned long flags;
+ struct usb_endpoint_descriptor *endpoint;
+
+ endpoint = intf->altsetting[intf->act_altsetting].endpoint;
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 */
spin_lock_irqsave(&hub_event_lock, flags);
- INIT_LIST_HEAD(&hub->hub_list);
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)
- return hub;
-
- err("hub configuration failed for device at %s", dev->devpath);
-
- /* free hub, but first clean up its list. */
- 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);
-
- 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;
- }
+ return 0;
- /* Free the memory */
- kfree(hub);
+ err("hub configuration failed for device at %s", intf->usb_device->devpath);
+ hub_disconnect(intf);
+ return -ENODEV;
}
static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
@@ -582,7 +575,7 @@
static int usb_hub_reset(struct usb_hub *hub)
{
- struct usb_device *dev = hub->dev;
+ struct usb_device *dev = hub->intf->usb_device;
int i;
/* Disconnect any attached devices */
@@ -793,7 +786,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 = hubstate->intf->usb_device;
struct usb_device *dev;
unsigned int delay = HUB_SHORT_RESET_TIME;
int i;
@@ -884,22 +877,8 @@
info("new USB device %s-%s, assigned address %d",
dev->bus->bus_name, dev->devpath, dev->devnum);
- /* put the device in the global device tree */
- dev->dev.parent = &dev->parent->dev;
- sprintf (&dev->dev.name[0], "USB device %04x:%04x",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
- /* find the number of the port this device is connected to */
- sprintf (&dev->dev.bus_id[0], "unknown_port_%03d", dev->devnum);
- for (i = 0; i < USB_MAXCHILDREN; ++i) {
- if (dev->parent->children[i] == dev) {
- sprintf (&dev->dev.bus_id[0], "%02d", i);
- break;
- }
- }
-
/* 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 */
@@ -944,7 +923,7 @@
tmp = hub_event_list.next;
hub = list_entry(tmp, struct usb_hub, event_list);
- dev = hub->dev;
+ dev = hub->intf->usb_device;
list_del(tmp);
INIT_LIST_HEAD(tmp);
@@ -1088,20 +1067,21 @@
static struct usb_driver hub_driver = {
name: "hub",
- probe: hub_probe,
+ new_probe: hub_probe,
+ init: hub_init,
ioctl: hub_ioctl,
- disconnect: hub_disconnect,
+ new_disco: hub_disconnect,
id_table: hub_id_table,
};
/*
* This should be a separate module.
*/
-int usb_hub_init(void)
+static int __init usb_hub_init(void)
{
int pid;
- if (usb_register(&hub_driver) < 0) {
+ if (usb_driver_register(&hub_driver) < 0) {
err("Unable to register USB hub driver");
return -1;
}
@@ -1121,7 +1101,7 @@
return -1;
}
-void usb_hub_cleanup(void)
+static void __exit usb_hub_cleanup(void)
{
int ret;
@@ -1138,7 +1118,10 @@
* individual hub resources. -greg
*/
usb_deregister(&hub_driver);
-} /* usb_hub_cleanup() */
+}
+
+module_init(usb_hub_init);
+module_exit(usb_hub_cleanup);
/*
* WARNING - If a driver calls usb_reset_device, you should simulate a
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hub.h
linux-2.5-driverfs/drivers/usb/core/hub.h
--- ../linux-2.5/drivers/usb/core/hub.h Mon Jun 3 10:24:22 2002
+++ linux-2.5-driverfs/drivers/usb/core/hub.h Mon Jun 3 11:29:16 2002
@@ -134,7 +134,7 @@
__u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
} __attribute__ ((packed));
-struct usb_device;
+struct usb_interface;
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
@@ -165,7 +165,7 @@
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_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 ../dontdiff ../linux-2.5/drivers/usb/core/usb.c
linux-2.5-driverfs/drivers/usb/core/usb.c
--- ../linux-2.5/drivers/usb/core/usb.c Mon Jun 3 10:01:01 2002
+++ linux-2.5-driverfs/drivers/usb/core/usb.c Mon Jun 3 11:29:16 2002
@@ -30,7 +30,6 @@
#include <linux/interrupt.h> /* for in_interrupt() */
#include <linux/kmod.h>
#include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
@@ -43,23 +42,6 @@
#include "hcd.h"
-extern int usb_hub_init(void);
-extern void usb_hub_cleanup(void);
-
-/*
- * Prototypes for the device driver probing/loading functions
- */
-static void usb_find_drivers(struct usb_device *);
-static int usb_find_interface_driver(struct usb_device *, unsigned int);
-static void usb_check_support(struct usb_device *);
-
-/*
- * We have a per-interface "registered driver" list.
- */
-LIST_HEAD(usb_driver_list);
-
-devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
-
#define MAX_USB_MINORS 256
static struct usb_driver *usb_minors[MAX_USB_MINORS];
static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
@@ -102,6 +84,51 @@
spin_unlock (&minor_lock);
}
+static int usb_device_probe(struct device * dev)
+{
+ struct usb_interface * intf = list_entry(dev,struct usb_interface,dev);
+ struct usb_driver * drv = list_entry(dev->driver,struct usb_driver,driver);
+ int error = -ENODEV;
+
+ if (drv->new_probe)
+ error = drv->new_probe(intf);
+ if (!error)
+ intf->driver = drv;
+ return error;
+}
+
+static int usb_device_init(struct device * dev)
+{
+ struct usb_interface * intf = list_entry(dev,struct usb_interface, dev);
+ struct usb_driver * drv = intf->driver;
+
+ return (drv->init) ? drv->init(intf) : 0;
+}
+
+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;
+}
+
+int usb_driver_register(struct usb_driver * drv)
+{
+ drv->driver.name = drv->name;
+ drv->driver.bus = &usb_bus_type;
+ drv->driver.probe = usb_device_probe;
+ drv->driver.init = usb_device_init;
+ drv->driver.remove = usb_device_remove;
+
+ info("registered new driver %s", drv->name);
+
+ init_MUTEX(&drv->serialize);
+
+ return driver_register(&drv->driver);
+}
+
/**
* usb_register - register a USB driver
* @new_driver: USB operations for the driver
@@ -128,14 +155,17 @@
}
#endif
+ new_driver->driver.name = new_driver->name;
+ new_driver->driver.bus = &usb_bus_type;
+ new_driver->driver.probe = usb_device_probe;
+ new_driver->driver.init = usb_device_init;
+ new_driver->driver.remove = usb_device_remove;
+
info("registered new driver %s", new_driver->name);
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();
+ driver_register(&new_driver->driver);
usbfs_update_special();
@@ -228,75 +258,6 @@
}
#endif /* CONFIG_USB_DYNAMIC_MINORS */
-
-/**
- * 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);
-}
-
-/*
- * 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) {
- if (driver->owner)
- __MOD_INC_USE_COUNT(driver->owner);
- down(&driver->serialize);
- driver->disconnect(dev, interface->private_data);
- up(&driver->serialize);
- if (driver->owner)
- __MOD_DEC_USE_COUNT(driver->owner);
- /* 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, i);
- }
- }
-}
-
/**
* usb_deregister - unregister a USB driver
* @driver: USB operations of the driver to unregister
@@ -306,8 +267,6 @@
*/
void usb_deregister(struct usb_driver *driver)
{
- struct list_head *tmp;
-
info("deregistering driver %s", driver->name);
#ifndef CONFIG_USB_DYNAMIC_MINORS
@@ -315,21 +274,7 @@
usb_deregister_minors (driver, driver->num_minors, driver->minor);
#endif
- /*
- * 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);
+ put_driver(&driver->driver);
usbfs_update_special();
}
@@ -410,33 +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, i);
-}
-
-
/**
* usb_driver_claim_interface - bind a driver to an interface
* @driver: the driver to be bound
@@ -468,7 +386,7 @@
iface->driver = driver;
iface->private_data = priv;
-} /* usb_driver_claim_interface() */
+}
/**
* usb_interface_claimed - returns true iff an interface is claimed
@@ -487,7 +405,7 @@
return 0;
return (iface->driver != NULL);
-} /* usb_interface_claimed() */
+}
/**
* usb_driver_release_interface - unbind a driver from an interface
@@ -645,110 +563,70 @@
return NULL;
}
-/*
- * This entrypoint gets called for each new device.
- *
- * 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
- */
-static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum)
+static int usb_device_bind(struct device * dev, struct device_driver * drv)
{
- struct list_head *tmp;
- struct usb_interface *interface;
- void *private;
- const struct usb_device_id *id;
- struct usb_driver *driver;
- int i;
-
- if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) {
- err("bad find_interface_driver params");
- return -1;
- }
-
- down(&dev->serialize);
-
- interface = dev->actconfig->interface + ifnum;
-
- if (usb_interface_claimed(interface))
- goto out_err;
-
- private = NULL;
- for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) {
- driver = list_entry(tmp, struct usb_driver, driver_list);
- tmp = tmp->next;
-
- if (driver->owner)
- __MOD_INC_USE_COUNT(driver->owner);
- id = driver->id_table;
- /* new style driver? */
- if (id) {
- for (i = 0; i < interface->num_altsetting; i++) {
- interface->act_altsetting = i;
- id = usb_match_id(dev, interface, id);
- if (id) {
- down(&driver->serialize);
- private = driver->probe(dev,ifnum,id);
- up(&driver->serialize);
- if (private != NULL)
- break;
- }
- }
+ struct usb_interface * intf = list_entry(dev,struct usb_interface,dev);
+ struct usb_interface_descriptor * desc =
+&intf->altsetting[intf->act_altsetting];
+ struct usb_device * usb_dev = intf->usb_device;
+ struct usb_driver * usb_drv = list_entry(drv,struct usb_driver,driver);
+ const struct usb_device_id * id = usb_drv->id_table;
- /* if driver not bound, leave defaults unchanged */
- if (private == NULL)
- interface->act_altsetting = 0;
- } else { /* "old style" driver */
- down(&driver->serialize);
- private = driver->probe(dev, ifnum, NULL);
- up(&driver->serialize);
- }
- if (driver->owner)
- __MOD_DEC_USE_COUNT(driver->owner);
+ /* It is important to check that id->driver_info is nonzero,
+ since an entry that is all zeroes except for a nonzero
+ id->driver_info is the way to create an entry that
+ indicates that the driver want to examine every
+ device and interface. */
+ for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+ id->driver_info; id++) {
- /* probe() may have changed the config on us */
- interface = dev->actconfig->interface + ifnum;
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+ id->idVendor != usb_dev->descriptor.idVendor)
+ continue;
- if (private) {
- usb_driver_claim_interface(driver, interface, private);
- up(&dev->serialize);
- return 0;
- }
- }
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+ id->idProduct != usb_dev->descriptor.idProduct)
+ continue;
-out_err:
- up(&dev->serialize);
- return -1;
-}
+ /* No need to test id->bcdDevice_lo != 0, since 0 is never
+ greater than any unsigned number. */
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
+ (id->bcdDevice_lo > usb_dev->descriptor.bcdDevice))
+ continue;
-/**
- * usb_find_interface_driver_for_ifnum - finds a usb interface driver for the
specified ifnum
- * @dev: the device to use
- * @ifnum: the interface number (bInterfaceNumber); not interface position!
- *
- * This converts a ifnum to ifpos via a call to usb_ifnum_to_ifpos and then
- * calls usb_find_interface_driver() with the found ifpos. Note
- * usb_find_interface_driver's ifnum parameter is actually interface position.
- */
-int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned ifnum)
-{
- int ifpos = usb_ifnum_to_ifpos(dev, ifnum);
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+ (id->bcdDevice_hi < usb_dev->descriptor.bcdDevice))
+ continue;
- if (0 > ifpos)
- return -EINVAL;
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+ (id->bDeviceClass != usb_dev->descriptor.bDeviceClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+ (id->bDeviceSubClass!= usb_dev->descriptor.bDeviceSubClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+ (id->bDeviceProtocol != usb_dev->descriptor.bDeviceProtocol))
+ continue;
- return usb_find_interface_driver(dev, ifpos);
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+ (id->bInterfaceClass != desc->bInterfaceClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+ (id->bInterfaceSubClass != desc->bInterfaceSubClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+ (id->bInterfaceProtocol != desc->bInterfaceProtocol))
+ continue;
+
+ return 1;
+ }
+ return 0;
}
+
#ifdef CONFIG_HOTPLUG
/*
@@ -886,51 +764,6 @@
#endif /* CONFIG_HOTPLUG */
-
-/*
- * 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;
-
- for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
- struct usb_interface *interface = &dev->actconfig->interface[ifnum];
-
- /* register this interface with driverfs */
- interface->dev.parent = &dev->dev;
- interface->dev.bus = &usb_bus_type;
- sprintf (&interface->dev.bus_id[0], "%03d%03d", dev->devnum,ifnum);
- sprintf (&interface->dev.name[0], "figure out some name...");
- device_register (&interface->dev);
-
- /* if this interface hasn't already been claimed */
- if (!usb_interface_claimed(interface)) {
- if (usb_find_interface_driver(dev, ifnum))
- 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
@@ -1034,7 +867,6 @@
/*-------------------------------------------------------------------*/
-
/* for returning string descriptors in UTF-16LE */
static int ascii2utf (char *ascii, __u8 *utf, int utfmax)
{
@@ -1171,7 +1003,6 @@
if (dev->devnum > 0) {
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
usbfs_remove_device(dev);
- put_device(&dev->dev);
}
/* Decrement the reference count, it'll auto free everything when */
@@ -1220,21 +1051,6 @@
}
/*
- * These are the actual routines to send
- * and receive control messages.
- */
-
-// hub-only!! ... and only exported for reset/reinit path.
-// otherwise used internally, for usb_new_device()
-int usb_set_address(struct usb_device *dev)
-{
- return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
- // FIXME USB_CTRL_SET_TIMEOUT
- 0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
-}
-
-
-/*
* By the time we get here, the device has gotten a new device ID
* and is in the default state. We need to identify the thing and
* get the ball rolling..
@@ -1248,7 +1064,7 @@
*/
#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;
@@ -1339,78 +1155,32 @@
if (dev->descriptor.iSerialNumber)
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
#endif
-
- /* register this device in the driverfs tree */
- err = device_register (&dev->dev);
- if (err)
- return err;
-
/* now that the basic setup is over, add a /proc/bus/usb entry */
usbfs_add_device(dev);
- /* find drivers willing to handle this device */
- usb_find_drivers(dev);
-
- /* userspace may load modules and/or configure further */
- call_policy ("add", dev);
-
- return 0;
-}
-
-static int usb_open(struct inode * inode, struct file * file)
-{
- int minor = minor(inode->i_rdev);
- struct usb_driver *c;
- int err = -ENODEV;
- struct file_operations *old_fops, *new_fops = NULL;
-
- spin_lock (&minor_lock);
- c = usb_minors[minor];
- spin_unlock (&minor_lock);
-
- if (!c || !(new_fops = fops_get(c->fops)))
- return err;
- old_fops = file->f_op;
- file->f_op = new_fops;
- /* Curiouser and curiouser... NULL ->open() as "no device" ? */
- if (file->f_op->open)
- err = file->f_op->open(inode,file);
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
- }
- fops_put(old_fops);
- return err;
-}
-
-static struct file_operations usb_fops = {
- owner: THIS_MODULE,
- open: usb_open,
-};
+ for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
+ struct usb_interface *interface = &dev->actconfig->interface[ifnum];
+ int _err;
-int usb_major_init(void)
-{
- if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) {
- err("unable to get major %d for usb devices", USB_MAJOR);
- return -EBUSY;
+ /* register this interface with driverfs */
+ interface->usb_device = dev;
+ interface->dev.parent = parent;
+ interface->dev.bus = &usb_bus_type;
+ sprintf (interface->dev.bus_id, "%03d%03d", dev->devnum,ifnum);
+ sprintf (interface->dev.name, "figure out some name...");
+ device_register (&interface->dev);
}
- usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
+ /* userspace may load modules and/or configure further */
+ call_policy ("add", dev);
return 0;
}
-void usb_major_cleanup(void)
-{
- devfs_unregister(usb_devfs_handle);
- devfs_unregister_chrdev(USB_MAJOR, "usb");
-}
-
-
#ifdef CONFIG_PROC_FS
struct list_head *usb_driver_get_list(void)
{
- return &usb_driver_list;
+ return &usb_bus_type.drivers;
}
struct list_head *usb_bus_get_list(void)
@@ -1421,6 +1191,7 @@
struct bus_type usb_bus_type = {
name: "usb",
+ bind: usb_device_bind,
};
/*
@@ -1429,10 +1200,7 @@
static int __init usb_init(void)
{
bus_register(&usb_bus_type);
- usb_major_init();
usbfs_init();
- usb_hub_init();
-
return 0;
}
@@ -1441,10 +1209,7 @@
*/
static void __exit usb_exit(void)
{
- put_bus(&usb_bus_type);
- usb_major_cleanup();
usbfs_cleanup();
- usb_hub_cleanup();
}
subsys_initcall(usb_init);
@@ -1461,7 +1226,6 @@
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
-EXPORT_SYMBOL(usb_scan_devices);
#ifdef CONFIG_USB_DYNAMIC_MINORS
EXPORT_SYMBOL(usb_register_dev);
@@ -1473,7 +1237,6 @@
EXPORT_SYMBOL(usb_get_dev);
EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
-EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum);
EXPORT_SYMBOL(usb_driver_claim_interface);
EXPORT_SYMBOL(usb_interface_claimed);
EXPORT_SYMBOL(usb_driver_release_interface);
@@ -1489,5 +1252,4 @@
EXPORT_SYMBOL(usb_get_current_frame_number);
-EXPORT_SYMBOL(usb_devfs_handle);
MODULE_LICENSE("GPL");
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid-core.c
linux-2.5-driverfs/drivers/usb/input/hid-core.c
--- ../linux-2.5/drivers/usb/input/hid-core.c Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/input/hid-core.c Mon Jun 3 11:29:16 2002
@@ -1013,7 +1013,7 @@
hid_output_report(report, hid->outbuf);
hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1;
- hid->urbout->dev = hid->dev;
+ hid->urbout->dev = hid->intf->usb_device;
dbg("submitting out urb");
@@ -1037,13 +1037,15 @@
hid_output_report(report, hid->ctrlbuf);
hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 +
((report->id > 0) && (dir != USB_DIR_OUT));
- hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? usb_sndctrlpipe(hid->dev, 0) :
usb_rcvctrlpipe(hid->dev, 0);
- hid->urbctrl->dev = hid->dev;
+ hid->urbctrl->pipe = (dir == USB_DIR_OUT) ?
+ usb_sndctrlpipe(hid->intf->usb_device, 0) :
+ usb_rcvctrlpipe(hid->intf->usb_device, 0);
+ hid->urbctrl->dev = hid->intf->usb_device;
hid->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
hid->cr.bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT :
HID_REQ_GET_REPORT;
hid->cr.wValue = ((report->type + 1) << 8) | report->id;
- hid->cr.wIndex = cpu_to_le16(hid->ifnum);
+ hid->cr.wIndex = cpu_to_le16(hid->intf->ifnum);
hid->cr.wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length);
dbg("submitting ctrl urb");
@@ -1199,7 +1201,7 @@
if (hid->open++)
return 0;
- hid->urbin->dev = hid->dev;
+ hid->urbin->dev = hid->intf->usb_device;
if (usb_submit_urb(hid->urbin, GFP_KERNEL))
return -EIO;
@@ -1252,9 +1254,9 @@
len = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
if (len > hid->urbin->transfer_buffer_length)
hid->urbin->transfer_buffer_length = len < HID_BUFFER_SIZE ?
len : HID_BUFFER_SIZE;
- usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+ usb_control_msg(hid->intf->usb_device,
+usb_sndctrlpipe(hid->intf->usb_device, 0),
0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id,
- hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+ hid->intf->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
list = list->next;
}
}
@@ -1293,9 +1295,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 + 0;
+ struct usb_device * dev = intf->usb_device;
struct hid_descriptor *hdesc;
struct hid_device *hid;
unsigned quirks = 0, rsize = 0;
@@ -1385,8 +1388,11 @@
hid->version = hdesc->bcdHID;
hid->country = hdesc->bCountryCode;
+/*
hid->dev = dev;
hid->ifnum = interface->bInterfaceNumber;
+*/
+ hid->intf = intf;
hid->name[0] = 0;
@@ -1395,18 +1401,7 @@
if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) {
strcat(hid->name, buf);
- if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) {
- n = snprintf(hid->name, sizeof(hid->name)-1, "%s %s",
hid->name, buf);
- hid->name[n] = 0;
- }
- } else {
- n = snprintf(hid->name, sizeof(hid->name)-1, "%04x:%04x",
dev->descriptor.idVendor, dev->descriptor.idProduct);
- hid->name[n] = 0;
- }
-
- usb_make_path(dev, buf, 64);
- n = snprintf(hid->phys, sizeof(hid->phys)-1, "%s/input%d", buf, ifnum);
- hid->phys[n] = 0;
+ snprintf(hid->phys, 64, "%s/input%d", buf, intf->ifnum);
if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
hid->uniq[0] = 0;
@@ -1428,18 +1423,18 @@
return 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)
{
+ struct usb_device * dev = intf->usb_device;
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 -ENODEV;
hid_init_reports(hid);
hid_dump_device(hid);
@@ -1451,7 +1446,7 @@
if (!hid->claimed) {
hid_free_device(hid);
- return NULL;
+ return -ENODEV;
}
printk(KERN_INFO);
@@ -1475,12 +1470,14 @@
printk(": USB HID v%x.%02x %s [%s] on %s\n",
hid->version >> 8, hid->version & 0xff, c, hid->name, path);
- return hid;
+ intf->dev.driver_data = hid;
+
+ return 0;
}
-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;
dbg("cleanup called");
usb_unlink_urb(hid->urbin);
@@ -1509,15 +1506,25 @@
static struct usb_driver hid_driver = {
name: "hid",
- probe: hid_probe,
- disconnect: hid_disconnect,
id_table: hid_usb_ids,
+ new_probe: hid_probe,
+ new_disco: hid_disconnect,
+
+#if 0
+ driver: {
+ name: "hid",
+ id_table: hid_usb_ids,
+ bus: &usb_bus_type,
+ devclass: &input_devclass,
+ probe: hid_dev_probe,
+ },
+#endif
};
static int __init hid_init(void)
{
hiddev_init();
- usb_register(&hid_driver);
+ usb_driver_register(&hid_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid-input.c
linux-2.5-driverfs/drivers/usb/input/hid-input.c
--- ../linux-2.5/drivers/usb/input/hid-input.c Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/input/hid-input.c Mon Jun 3 11:29:16 2002
@@ -411,7 +411,7 @@
int hidinput_connect(struct hid_device *hid)
{
- struct usb_device *dev = hid->dev;
+ struct usb_device *dev = hid->intf->usb_device;
struct hid_report_enum *report_enum;
struct hid_report *report;
struct list_head *list;
@@ -436,6 +436,7 @@
hid->input.idvendor = dev->descriptor.idVendor;
hid->input.idproduct = dev->descriptor.idProduct;
hid->input.idversion = dev->descriptor.bcdDevice;
+ hid->input.dev = &hid->intf->dev;
for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
report_enum = hid->report_enum + k;
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid.h
linux-2.5-driverfs/drivers/usb/input/hid.h
--- ../linux-2.5/drivers/usb/input/hid.h Mon Jun 3 10:25:15 2002
+++ linux-2.5-driverfs/drivers/usb/input/hid.h Mon Jun 3 11:29:16 2002
@@ -325,9 +325,11 @@
unsigned country; /* HID country
*/
struct hid_report_enum report_enum[HID_REPORT_TYPES];
+ struct usb_interface * intf;
+#if 0
struct usb_device *dev; /* USB device
*/
int ifnum; /* USB
interface number */
-
+#endif
unsigned long iofl; /* I/O flags
(CTRL_RUNNING, OUT_RUNNING) */
struct urb *urbin; /* Input URB */
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/usbmouse.c
linux-2.5-driverfs/drivers/usb/input/usbmouse.c
--- ../linux-2.5/drivers/usb/input/usbmouse.c Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/input/usbmouse.c Mon Jun 3 11:29:16 2002
@@ -149,6 +149,7 @@
mouse->dev.idvendor = dev->descriptor.idVendor;
mouse->dev.idproduct = dev->descriptor.idProduct;
mouse->dev.idversion = dev->descriptor.bcdDevice;
+ mouse->dev.dev = &mouse->usbdev->dev;
if (!(buf = kmalloc(63, GFP_KERNEL))) {
kfree(mouse);
diff -Naur -X ../dontdiff ../linux-2.5/include/linux/usb.h
linux-2.5-driverfs/include/linux/usb.h
--- ../linux-2.5/include/linux/usb.h Mon Jun 3 12:03:57 2002
+++ linux-2.5-driverfs/include/linux/usb.h Mon Jun 3 11:29:30 2002
@@ -248,11 +248,13 @@
struct usb_interface {
struct usb_interface_descriptor *altsetting;
+ int ifnum; /* interface number of device */
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 usb_device *usb_device; /* device this interface is on */
struct device dev; /* interface specific device info */
void *private_data;
};
@@ -394,8 +396,6 @@
struct usb_device *parent; /* our hub, unless we're the root */
struct usb_bus *bus; /* Bus we're part of */
- struct device dev; /* Generic device interface */
-
struct usb_device_descriptor descriptor;/* Descriptor */
struct usb_config_descriptor *config; /* All of the configs */
struct usb_config_descriptor *actconfig;/* the active configuration */
@@ -683,6 +683,12 @@
struct module *owner;
const char *name;
+ int (*new_probe)(struct usb_interface * intf);
+ int (*init)(struct usb_interface * intf);
+ void (*new_disco)(struct usb_interface * intf);
+
+ struct device_driver driver;
+
void *(*probe)(
struct usb_device *dev, /* the device */
unsigned intf, /* what interface */
@@ -722,6 +728,10 @@
extern int usb_register(struct usb_driver *);
extern void usb_deregister(struct usb_driver *);
+/* new school */
+extern int usb_driver_register(struct usb_driver *);
+extern void usb_driver_unregister(struct usb_driver *);
+
#ifndef CONFIG_USB_DYNAMIC_MINORS
static inline int usb_register_dev(struct usb_driver *new_driver, int num_minors, int
*start_minor) { return -ENODEV; }
static inline void usb_deregister_dev(struct usb_driver *driver, int num_minors, int
start_minor) {}
_______________________________________________________________
Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel