On Thu, May 04, 2000, Dunlap, Randy <[EMAIL PROTECTED]> wrote:
> - decent behavior of USB (minimal oops/bug reports)
> - satisfied users (at least of devices that we have support for)
Completely agreed.
> 1. USB PnP support (usbd etc.); permanence of usbdevfs?
I've been involved in this quite a bit recently.
First off, I've attached a patch to completely nuke usbdevfs's VFS layer in
favor of using devfs for all of that stuff. Nodes are still created, and you
use the same ioctl()'s, you just use a different name and you don't have
to worry about mounting an extra filesystem to get it.
The patch also does a couple of other things:
- Adds a new GET_DRIVER ioctl()
- Set's the address for the device before grabbing the descriptors
This is safe since we need to do the short descriptor read to get the
maximum packet size of the control pipe, however SET_ADDRESS doesn't
have a data transfer stage, so the maximum packet size is never used
Also, I'd like to get my user space driver binding patch included to
appropriately load and bind drivers for devices to minimize problems that the
current scheme has.
> 4. bandwidth allocation in HCDs [needed for USB PlugFest in
> August/2000]
Randy, you wrote the initial implementation. What do you think needs to be
done to get this working correctly per the specs?
I'd also like to add a number 5:
5. Standardize on one UHCI driver
> b. Make sure that the APC workaround works.
This is going to be pretty difficult. Enumeration of the device works by
a fluke that the control pipe's max packet size is 8 bytes and we either
ask for 8 bytes or the entire descriptor.
Unfortunately, it'll babble all over the bus if we ask for less than the
max packet size and there's more data in the descriptor.
The correct fix, if we want the APC devices to work, is to always accept
the entire descriptor.
I haven't looked at the HID code so I don't know how difficult it would
be to get it to do this.
I'm working on another workaround which moves it from the HCD to the core
so it'll work with all devices, but I've been mainly working on other
issues that more important for USB as a whole than a specific device.
> c. Remove some of the backwards-compatibility API.
Which backwards-compatible API are you talking about? I'd like to keep
usb_control_msg and usb_bulk_msg, but nuke usb_request_irq, usb_request_bulk
and usb_terminate_bulk.
According to my sources, the only driver which uses usb_request_irq is
uss720.c and it doesn't seem all too difficult to fix.
usb_control_msg and usb_bulk_msg are more convenience functions to do
synchronous transfers than backward compatible API's.
> Request from Martin Mares:
> - I'd also like to see some support for progress reporting
> on bulk URB's. It's needed for my USB networking
> driver which is close to being finished and I'd like to see
> it in one of the first few 2.4 releases.
Should we create a new API call for this?
usb_status_urb which forces the HC driver to check on the status and
update lengths, status, etc?
JE
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/Config.in
linux-2.3.99-pre7-3/drivers/usb/Config.in
--- linux-2.3.99-pre7-3.orig/drivers/usb/Config.in Fri Apr 21 14:03:01 2000
+++ linux-2.3.99-pre7-3/drivers/usb/Config.in Wed May 3 14:57:34 2000
@@ -8,9 +8,6 @@
if [ ! "$CONFIG_USB" = "n" ]; then
bool ' USB verbose debug messages' CONFIG_USB_DEBUG
-comment 'Miscellaneous USB options'
- bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS
-
comment 'USB Controllers'
if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
dep_tristate ' UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI
$CONFIG_USB
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/Makefile
linux-2.3.99-pre7-3/drivers/usb/Makefile
--- linux-2.3.99-pre7-3.orig/drivers/usb/Makefile Mon Mar 27 14:25:28 2000
+++ linux-2.3.99-pre7-3/drivers/usb/Makefile Wed May 3 14:57:24 2000
@@ -23,13 +23,8 @@
# Multipart objects.
list-multi := usbcore.o
-usbcore-objs := usb.o usb-debug.o usb-core.o hub.o
-
-# Optional parts of multipart objects.
-
-ifeq ($(CONFIG_USB_DEVICEFS),y)
- usbcore-objs += devio.o inode.o drivers.o devices.o
-endif
+usbcore-objs := usb.o usb-debug.o usb-core.o hub.o \
+ usb-devfs.o devio.o drivers.o devices.o
# Object file lists.
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/devio.c
linux-2.3.99-pre7-3/drivers/usb/devio.c
--- linux-2.3.99-pre7-3.orig/drivers/usb/devio.c Wed Apr 26 15:22:55 2000
+++ linux-2.3.99-pre7-3/drivers/usb/devio.c Wed May 3 16:18:19 2000
@@ -21,8 +21,7 @@
*
* $Id: devio.c,v 1.7 2000/02/01 17:28:48 fliegl Exp $
*
- * This file implements the usbdevfs/x/y files, where
- * x is the bus number and y the device number.
+ * This file implements the usb devfs files
*
* It allows user space programs/"drivers" to communicate directly
* with USB devices without intervening kernel driver.
@@ -52,7 +51,7 @@
unsigned int signr;
void *userbuffer;
void *userurb;
- urb_t urb;
+ struct urb urb;
};
/*
@@ -64,14 +63,14 @@
wait_queue_head_t wait;
};
-static void sync_completed(purb_t urb)
+static void sync_completed(struct urb *urb)
{
struct sync *s = (struct sync *)urb->context;
wake_up(&s->wait);
}
-static int do_sync(purb_t urb, int timeout)
+static int do_sync(struct urb *urb, int timeout)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long tm;
@@ -100,7 +99,7 @@
schedule_timeout(tmdiff);
}
ret = urb->status;
- out:
+out:
set_current_state(TASK_RUNNING);
usb_unlink_urb(urb);
remove_wait_queue(&s.wait, &wait);
@@ -110,7 +109,7 @@
static int my_usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8
request, __u8 requesttype,
__u16 value, __u16 index, void *data, __u16 size, int
timeout)
{
- urb_t *urb;
+ struct urb *urb;
int ret;
if (!(urb = usb_alloc_urb(0)))
@@ -144,7 +143,7 @@
static int my_usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
{
- urb_t *urb;
+ struct urb *urb;
int ret;
if (!(urb = usb_alloc_urb(0)))
@@ -187,26 +186,54 @@
ssize_t ret = 0;
unsigned len;
loff_t pos;
+ int i;
pos = *ppos;
down_read(&ps->devsem);
- if (!ps->dev)
+ if (!ps->dev) {
ret = -ENODEV;
- else if (pos < 0)
+ goto err;
+ } else if (pos < 0) {
ret = -EINVAL;
- else if (pos < sizeof(struct usb_device_descriptor)) {
+ goto err;
+ }
+
+ if (pos < sizeof(struct usb_device_descriptor)) {
len = sizeof(struct usb_device_descriptor) - pos;
if (len > nbytes)
len = nbytes;
- if (copy_to_user(buf, ((char *)&ps->dev->descriptor) + pos, len))
+ if (copy_to_user(buf, ((char *)&ps->dev->descriptor) + pos, len)) {
ret = -EFAULT;
- else {
+ goto err;
+ }
+ }
+
+ pos = sizeof(struct usb_device_descriptor);
+ for (i = 0; nbytes && i < ps->dev->descriptor.bNumConfigurations; i++) {
+ struct usb_config_descriptor *config =
+ (struct usb_config_descriptor *)ps->dev->rawdescriptors[i];
+ unsigned int length = le16_to_cpu(config->wTotalLength);
+
+ if (*ppos < pos + length) {
+ len = length - (*ppos - pos);
+ if (len > nbytes)
+ len = nbytes;
+
+ if (copy_to_user(buf, ps->dev->rawdescriptors[i] + (*ppos -
+pos), len)) {
+ ret = -EFAULT;
+ goto err;
+ }
+
*ppos += len;
buf += len;
nbytes -= len;
ret += len;
}
+
+ pos += length;
}
+
+err:
up_read(&ps->devsem);
return ret;
}
@@ -315,7 +342,7 @@
return NULL;
}
-static void async_completed(purb_t urb)
+static void async_completed(struct urb *urb)
{
struct async *as = (struct async *)urb->context;
struct dev_state *ps = as->ps;
@@ -376,12 +403,9 @@
}
struct usb_driver usbdevfs_driver = {
- "usbdevfs",
- driver_probe,
- driver_disconnect,
- LIST_HEAD_INIT(usbdevfs_driver.driver_list),
- NULL,
- 0
+ name: "usbdevfs",
+ probe: driver_probe,
+ disconnect: driver_disconnect,
};
static int claimintf(struct dev_state *ps, unsigned int intf)
@@ -497,9 +521,7 @@
*/
lock_kernel();
ret = -ENOENT;
- if (ITYPE(inode->i_ino) != IDEVICE)
- goto out;
- dev = inode->u.usbdev_i.p.dev;
+ dev = file->private_data;
if (!dev)
goto out;
ret = -ENOMEM;
@@ -520,7 +542,8 @@
wmb();
list_add_tail(&ps->list, &dev->filelist);
file->private_data = ps;
- out:
+
+out:
unlock_kernel();
return ret;
}
@@ -662,6 +685,25 @@
return 0;
}
+static int proc_getdriver(struct dev_state *ps, void *arg)
+{
+ struct usbdevfs_driver gd;
+ struct usb_interface *interface;
+ int ret;
+
+ copy_from_user_ret(&gd, arg, sizeof(gd), -EFAULT);
+ if ((ret = findintfif(ps->dev, gd.interface)) < 0)
+ return ret;
+ interface = usb_ifnum_to_if(ps->dev, gd.interface);
+ if (!interface)
+ return -EINVAL;
+ if (!interface->driver)
+ return -ENODATA;
+ strcpy(gd.driver, interface->driver->name);
+ copy_to_user_ret(arg, &gd, sizeof(gd), -EFAULT);
+ return 0;
+}
+
static int proc_setintf(struct dev_state *ps, void *arg)
{
struct usbdevfs_setinterface setintf;
@@ -942,6 +984,10 @@
ret = proc_resetep(ps, (void *)arg);
if (ret >= 0)
inode->i_mtime = CURRENT_TIME;
+ break;
+
+ case USBDEVFS_GETDRIVER:
+ ret = proc_getdriver(ps, (void *)arg);
break;
case USBDEVFS_SETINTERFACE:
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/inode.c
linux-2.3.99-pre7-3/drivers/usb/inode.c
--- linux-2.3.99-pre7-3.orig/drivers/usb/inode.c Mon Apr 10 22:55:08 2000
+++ linux-2.3.99-pre7-3/drivers/usb/inode.c Wed Dec 31 16:00:00 1969
@@ -1,696 +0,0 @@
-/*****************************************************************************/
-
-/*
- * inode.c -- Inode/Dentry functions for the USB device file system.
- *
- * Copyright (C) 2000
- * Thomas Sailer ([EMAIL PROTECTED])
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: inode.c,v 1.3 2000/01/11 13:58:25 tom Exp $
- *
- * History:
- * 0.1 04.01.2000 Created
- */
-
-/*****************************************************************************/
-
-#define __NO_VERSION__
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/locks.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/usb.h>
-#include <linux/usbdevice_fs.h>
-#include <asm/uaccess.h>
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(superlist);
-
-struct special {
- const char *name;
- struct file_operations *fops;
- struct list_head inodes;
-};
-
-static struct special special[] = {
- { "devices", &usbdevfs_devices_fops, },
- { "drivers", &usbdevfs_drivers_fops, }
-};
-
-#define NRSPECIAL (sizeof(special)/sizeof(special[0]))
-
-/* --------------------------------------------------------------------- */
-
-static int dnumber(struct dentry *dentry)
-{
- const char *name;
- unsigned int s;
-
- if (dentry->d_name.len != 3)
- return -1;
- name = dentry->d_name.name;
- if (name[0] < '0' || name[0] > '9' ||
- name[1] < '0' || name[1] > '9' ||
- name[2] < '0' || name[2] > '9')
- return -1;
- s = name[0] - '0';
- s = s * 10 + name[1] - '0';
- s = s * 10 + name[2] - '0';
- return s;
-}
-
-/*
- * utility functions; should be called with the kernel lock held
- * to protect against busses/devices appearing/disappearing
- */
-
-static void new_dev_inode(struct usb_device *dev, struct super_block *sb)
-{
- struct inode *inode;
- unsigned int devnum = dev->devnum;
- unsigned int busnum = dev->bus->busnum;
-
- if (devnum < 1 || devnum > 127 || busnum > 255)
- return;
- inode = iget(sb, IDEVICE | (busnum << 8) | devnum);
- if (!inode) {
- printk(KERN_ERR "usbdevfs: cannot create inode for bus %u device
%u\n", busnum, devnum);
- return;
- }
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_uid = sb->u.usbdevfs_sb.devuid;
- inode->i_gid = sb->u.usbdevfs_sb.devgid;
- inode->i_mode = sb->u.usbdevfs_sb.devmode | S_IFREG;
- inode->i_fop = &usbdevfs_device_file_operations;
- inode->i_size = sizeof(struct usb_device_descriptor);
- inode->u.usbdev_i.p.dev = dev;
- list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
- list_add_tail(&inode->u.usbdev_i.dlist, &dev->inodes);
-}
-
-static void recurse_new_dev_inode(struct usb_device *dev, struct super_block *sb)
-{
- unsigned int i;
-
- if (!dev)
- return;
- new_dev_inode(dev, sb);
- for (i = 0; i < dev->maxchild; i++) {
- if (!dev->children[i])
- continue;
- recurse_new_dev_inode(dev->children[i], sb);
- }
-}
-
-static void new_bus_inode(struct usb_bus *bus, struct super_block *sb)
-{
- struct inode *inode;
- unsigned int busnum = bus->busnum;
-
- if (busnum > 255)
- return;
- inode = iget(sb, IBUS | (busnum << 8));
- if (!inode) {
- printk(KERN_ERR "usbdevfs: cannot create inode for bus %u\n", busnum);
- return;
- }
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_uid = sb->u.usbdevfs_sb.busuid;
- inode->i_gid = sb->u.usbdevfs_sb.busgid;
- inode->i_mode = sb->u.usbdevfs_sb.busmode | S_IFDIR;
- inode->i_op = &usbdevfs_bus_inode_operations;
- inode->i_fop = &usbdevfs_bus_file_operations;
- inode->u.usbdev_i.p.bus = bus;
- list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
- list_add_tail(&inode->u.usbdev_i.dlist, &bus->inodes);
-}
-
-static void free_inode(struct inode *inode)
-{
- inode->u.usbdev_i.p.bus = NULL;
- inode->u.usbdev_i.p.dev = NULL;
- inode->i_mode &= ~S_IRWXUGO;
- inode->i_uid = inode->i_gid = 0;
- inode->i_size = 0;
- list_del(&inode->u.usbdev_i.slist);
- INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
- list_del(&inode->u.usbdev_i.dlist);
- INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);
- iput(inode);
-}
-
-static struct usb_bus *usbdevfs_findbus(int busnr)
-{
- struct list_head *list;
- struct usb_bus *bus;
-
- for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
- bus = list_entry(list, struct usb_bus, bus_list);
- if (bus->busnum == busnr)
- return bus;
- }
- return NULL;
-}
-
-#if 0
-static struct usb_device *finddev(struct usb_device *dev, int devnr)
-{
- unsigned int i;
- struct usb_device *d2;
-
- if (!dev)
- return NULL;
- if (dev->devnum == devnr)
- return dev;
- for (i = 0; i < dev->maxchild; i++) {
- if (!dev->children[i])
- continue;
- if ((d2 = finddev(dev->children[i], devnr)))
- return d2;
- }
- return NULL;
-}
-
-static struct usb_device *usbdevfs_finddevice(struct usb_bus *bus, int devnr)
-{
- return finddev(bus->root_hub, devnr);
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-
-static int usbdevfs_revalidate(struct dentry *dentry, int flags)
-{
- struct inode *inode = dentry->d_inode;
-
- if (!inode)
- return 0;
- if (ITYPE(inode->i_ino) == IBUS && !inode->u.usbdev_i.p.bus)
- return 0;
- if (ITYPE(inode->i_ino) == IDEVICE && !inode->u.usbdev_i.p.dev)
- return 0;
- return 1;
-}
-
-static struct dentry_operations usbdevfs_dentry_operations = {
- d_revalidate: usbdevfs_revalidate,
-};
-
-static struct dentry *usbdevfs_root_lookup(struct inode *dir, struct dentry *dentry)
-{
- int busnr;
- unsigned long ino = 0;
- unsigned int i;
- struct inode *inode;
-
- /* sanity check */
- if (dir->i_ino != IROOT)
- return ERR_PTR(-EINVAL);
- dentry->d_op = &usbdevfs_dentry_operations;
- busnr = dnumber(dentry);
- if (busnr >= 0 && busnr <= 255)
- ino = IBUS | (busnr << 8);
- if (!ino) {
- for (i = 0; i < NRSPECIAL; i++) {
- if (strlen(special[i].name) == dentry->d_name.len &&
- !strncmp(special[i].name, dentry->d_name.name,
dentry->d_name.len)) {
- ino = ISPECIAL | (i + IROOT + 1);
- break;
- }
- }
- }
- if (!ino)
- return ERR_PTR(-ENOENT);
- inode = iget(dir->i_sb, ino);
- if (!inode)
- return ERR_PTR(-EINVAL);
- if (inode && ITYPE(ino) == IBUS && inode->u.usbdev_i.p.bus == NULL) {
- iput(inode);
- inode = NULL;
- }
- d_add(dentry, inode);
- return NULL;
-}
-
-static struct dentry *usbdevfs_bus_lookup(struct inode *dir, struct dentry *dentry)
-{
- struct inode *inode;
- int devnr;
-
- /* sanity check */
- if (ITYPE(dir->i_ino) != IBUS)
- return ERR_PTR(-EINVAL);
- dentry->d_op = &usbdevfs_dentry_operations;
- devnr = dnumber(dentry);
- if (devnr < 1 || devnr > 127)
- return ERR_PTR(-ENOENT);
- inode = iget(dir->i_sb, IDEVICE | (dir->i_ino & (0xff << 8)) | devnr);
- if (!inode)
- return ERR_PTR(-EINVAL);
- if (inode && inode->u.usbdev_i.p.dev == NULL) {
- iput(inode);
- inode = NULL;
- }
- d_add(dentry, inode);
- return NULL;
-}
-
-static int usbdevfs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
-{
- struct inode *inode = filp->f_dentry->d_inode;
- unsigned long ino = inode->i_ino;
- struct special *spec;
- struct list_head *list;
- struct usb_bus *bus;
- char numbuf[8];
- unsigned int i;
-
- /* sanity check */
- if (ino != IROOT)
- return -EINVAL;
- i = filp->f_pos;
- switch (i) {
- case 0:
- if (filldir(dirent, ".", 1, i, IROOT) < 0)
- return 0;
- filp->f_pos++;
- i++;
- /* fall through */
-
- case 1:
- if (filldir(dirent, "..", 2, i, IROOT) < 0)
- return 0;
- filp->f_pos++;
- i++;
- /* fall through */
-
- default:
-
- while (i >= 2 && i < 2+NRSPECIAL) {
- spec = &special[filp->f_pos-2];
- if (filldir(dirent, spec->name, strlen(spec->name), i,
ISPECIAL | (filp->f_pos-2+IROOT)) < 0)
- return 0;
- filp->f_pos++;
- i++;
- }
- if (i < 2+NRSPECIAL)
- return 0;
- i -= 2+NRSPECIAL;
- lock_kernel();
- for (list = usb_bus_list.next; list != &usb_bus_list; list =
list->next) {
- if (i > 0) {
- i--;
- continue;
- }
- bus = list_entry(list, struct usb_bus, bus_list);
- sprintf(numbuf, "%03d", bus->busnum);
- if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS |
((bus->busnum & 0xff) << 8)) < 0)
- break;
- filp->f_pos++;
- }
- unlock_kernel();
- return 0;
- }
-}
-
-static int bus_readdir(struct usb_device *dev, unsigned long ino, int pos, struct
file *filp, void *dirent, filldir_t filldir)
-{
- char numbuf[8];
- unsigned int i;
-
- if (!dev)
- return pos;
- sprintf(numbuf, "%03d", dev->devnum);
- if (pos > 0)
- pos--;
- else {
- if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum &
0xff)) < 0)
- return -1;
- filp->f_pos++;
- }
- for (i = 0; i < dev->maxchild; i++) {
- if (!dev->children[i])
- continue;
- pos = bus_readdir(dev->children[i], ino, pos, filp, dirent, filldir);
- if (pos < 0)
- return -1;
- }
- return pos;
-}
-
-static int usbdevfs_bus_readdir(struct file *filp, void *dirent, filldir_t filldir)
-{
- struct inode *inode = filp->f_dentry->d_inode;
- unsigned long ino = inode->i_ino;
- struct usb_bus *bus;
-
- /* sanity check */
- if (ITYPE(ino) != IBUS)
- return -EINVAL;
- switch ((unsigned int)filp->f_pos) {
- case 0:
- if (filldir(dirent, ".", 1, filp->f_pos, ino) < 0)
- return 0;
- filp->f_pos++;
- /* fall through */
-
- case 1:
- if (filldir(dirent, "..", 2, filp->f_pos, IROOT) < 0)
- return 0;
- filp->f_pos++;
- /* fall through */
-
- default:
- lock_kernel();
- bus = usbdevfs_findbus(IBUSNR(ino));
- bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8),
filp->f_pos-2, filp, dirent, filldir);
- unlock_kernel();
- return 0;
- }
-}
-
-static struct file_operations usbdevfs_root_file_operations = {
- readdir: usbdevfs_root_readdir,
-};
-
-static struct inode_operations usbdevfs_root_inode_operations = {
- lookup: usbdevfs_root_lookup,
-};
-
-static struct file_operations usbdevfs_bus_file_operations = {
- readdir: usbdevfs_bus_readdir,
-};
-
-static struct inode_operations usbdevfs_bus_inode_operations = {
- lookup: usbdevfs_bus_lookup,
-};
-
-static void usbdevfs_read_inode(struct inode *inode)
-{
- struct special *spec;
-
- inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME;
- inode->i_mode = S_IFREG;
- inode->i_gid = inode->i_uid = 0;
- INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);
- INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
- inode->u.usbdev_i.p.dev = NULL;
- inode->u.usbdev_i.p.bus = NULL;
- switch (ITYPE(inode->i_ino)) {
- case ISPECIAL:
- if (inode->i_ino == IROOT) {
- inode->i_op = &usbdevfs_root_inode_operations;
- inode->i_fop = &usbdevfs_root_file_operations;
- inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
- return;
- }
- if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
- return;
- spec = &special[inode->i_ino-(IROOT+1)];
- inode->i_fop = spec->fops;
- return;
-
- case IDEVICE:
- return;
-
- case IBUS:
- return;
-
- default:
- return;
- }
-}
-
-static void usbdevfs_put_super(struct super_block *sb)
-{
- list_del(&sb->u.usbdevfs_sb.slist);
- INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist);
- while (!list_empty(&sb->u.usbdevfs_sb.ilist))
- free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, struct inode,
u.usbdev_i.slist));
-}
-
-static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf)
-{
- buf->f_type = USBDEVICE_SUPER_MAGIC;
- buf->f_bsize = PAGE_SIZE/sizeof(long); /* ??? */
- buf->f_bfree = 0;
- buf->f_bavail = 0;
- buf->f_ffree = 0;
- buf->f_namelen = NAME_MAX;
- return 0;
-}
-
-static struct super_operations usbdevfs_sops = {
- read_inode: usbdevfs_read_inode,
- put_super: usbdevfs_put_super,
- statfs: usbdevfs_statfs,
-};
-
-struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent)
-{
- struct inode *root_inode, *inode;
- struct list_head *blist;
- struct usb_bus *bus;
- unsigned int i;
- uid_t devuid = 0, busuid = 0, listuid = 0;
- gid_t devgid = 0, busgid = 0, listgid = 0;
- umode_t devmode = S_IWUSR | S_IRUGO, busmode = S_IXUGO | S_IRUGO, listmode =
S_IRUGO;
- char *curopt = NULL, *value;
-
- /* parse options */
- if (data)
- curopt = strtok(data, ",");
- for (; curopt; curopt = strtok(NULL, ",")) {
- if ((value = strchr(curopt, '=')) != NULL)
- *value++ = 0;
- if (!strcmp(curopt, "devuid")) {
- if (!value || !value[0])
- goto opterr;
- devuid = simple_strtoul(value, &value, 0);
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "devgid")) {
- if (!value || !value[0])
- goto opterr;
- devgid = simple_strtoul(value, &value, 0);
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "devmode")) {
- if (!value || !value[0])
- goto opterr;
- devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "busuid")) {
- if (!value || !value[0])
- goto opterr;
- busuid = simple_strtoul(value, &value, 0);
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "busgid")) {
- if (!value || !value[0])
- goto opterr;
- busgid = simple_strtoul(value, &value, 0);
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "busmode")) {
- if (!value || !value[0])
- goto opterr;
- busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "listuid")) {
- if (!value || !value[0])
- goto opterr;
- listuid = simple_strtoul(value, &value, 0);
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "listgid")) {
- if (!value || !value[0])
- goto opterr;
- listgid = simple_strtoul(value, &value, 0);
- if (*value)
- goto opterr;
- }
- if (!strcmp(curopt, "listmode")) {
- if (!value || !value[0])
- goto opterr;
- listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
- if (*value)
- goto opterr;
- }
- }
- /* fill superblock */
- s->s_blocksize = 1024;
- s->s_blocksize_bits = 10;
- s->s_magic = USBDEVICE_SUPER_MAGIC;
- s->s_op = &usbdevfs_sops;
- INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist);
- INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist);
- s->u.usbdevfs_sb.devuid = devuid;
- s->u.usbdevfs_sb.devgid = devgid;
- s->u.usbdevfs_sb.devmode = devmode;
- s->u.usbdevfs_sb.busuid = busuid;
- s->u.usbdevfs_sb.busgid = busgid;
- s->u.usbdevfs_sb.busmode = busmode;
- root_inode = iget(s, IROOT);
- if (!root_inode)
- goto out_no_root;
- s->s_root = d_alloc_root(root_inode);
- if (!s->s_root)
- goto out_no_root;
- list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);
- for (i = 0; i < NRSPECIAL; i++) {
- if (!(inode = iget(s, IROOT+1+i)))
- continue;
- inode->i_uid = listuid;
- inode->i_gid = listgid;
- inode->i_mode = listmode | S_IFREG;
- list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
- list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);
- }
- lock_kernel();
- for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {
- bus = list_entry(blist, struct usb_bus, bus_list);
- new_bus_inode(bus, s);
- recurse_new_dev_inode(bus->root_hub, s);
- }
- unlock_kernel();
- return s;
-
- out_no_root:
- printk("usbdevfs_read_super: get root inode failed\n");
- iput(root_inode);
- return NULL;
-
- opterr:
- printk(KERN_WARNING "usbdevfs: mount parameter error\n");
- return NULL;
-}
-
-static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, 0);
-
-/* --------------------------------------------------------------------- */
-
-void usbdevfs_add_bus(struct usb_bus *bus)
-{
- struct list_head *slist;
-
- lock_kernel();
- for (slist = superlist.next; slist != &superlist; slist = slist->next)
- new_bus_inode(bus, list_entry(slist, struct super_block,
u.usbdevfs_sb.slist));
- unlock_kernel();
- usbdevfs_conn_disc_event();
-}
-
-void usbdevfs_remove_bus(struct usb_bus *bus)
-{
- lock_kernel();
- while (!list_empty(&bus->inodes))
- free_inode(list_entry(bus->inodes.next, struct inode,
u.usbdev_i.dlist));
- unlock_kernel();
- usbdevfs_conn_disc_event();
-}
-
-void usbdevfs_add_device(struct usb_device *dev)
-{
- struct list_head *slist;
-
- lock_kernel();
- for (slist = superlist.next; slist != &superlist; slist = slist->next)
- new_dev_inode(dev, list_entry(slist, struct super_block,
u.usbdevfs_sb.slist));
- unlock_kernel();
- usbdevfs_conn_disc_event();
-}
-
-void usbdevfs_remove_device(struct usb_device *dev)
-{
- struct dev_state *ds;
- struct siginfo sinfo;
-
- lock_kernel();
- while (!list_empty(&dev->inodes))
- free_inode(list_entry(dev->inodes.next, struct inode,
u.usbdev_i.dlist));
- while (!list_empty(&dev->filelist)) {
- ds = list_entry(dev->filelist.next, struct dev_state, list);
- list_del(&ds->list);
- INIT_LIST_HEAD(&ds->list);
- down_write(&ds->devsem);
- ds->dev = NULL;
- up_write(&ds->devsem);
- if (ds->discsignr) {
- sinfo.si_signo = SIGPIPE;
- sinfo.si_errno = EPIPE;
- sinfo.si_code = SI_ASYNCIO;
- sinfo.si_addr = ds->disccontext;
- send_sig_info(ds->discsignr, &sinfo, ds->disctask);
- }
- }
- unlock_kernel();
- usbdevfs_conn_disc_event();
-}
-
-/* --------------------------------------------------------------------- */
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *usbdir = NULL;
-#endif
-
-int __init usbdevfs_init(void)
-{
- int ret;
-
- for (ret = 0; ret < NRSPECIAL; ret++) {
- INIT_LIST_HEAD(&special[ret].inodes);
- }
- if ((ret = usb_register(&usbdevfs_driver)))
- return ret;
- if ((ret = register_filesystem(&usbdevice_fs_type)))
- usb_deregister(&usbdevfs_driver);
-#ifdef CONFIG_PROC_FS
- /* create mount point for usbdevfs */
- usbdir = proc_mkdir("usb", proc_bus);
-#endif
- return ret;
-}
-
-void __exit usbdevfs_cleanup(void)
-{
- usb_deregister(&usbdevfs_driver);
- unregister_filesystem(&usbdevice_fs_type);
-#ifdef CONFIG_PROC_FS
- if (usbdir)
- remove_proc_entry("usb", proc_bus);
-#endif
-}
-
-#if 0
-module_init(usbdevfs_init);
-module_exit(usbdevfs_cleanup);
-#endif
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/usb-core.c
linux-2.3.99-pre7-3/drivers/usb/usb-core.c
--- linux-2.3.99-pre7-3.orig/drivers/usb/usb-core.c Fri Apr 21 14:03:00 2000
+++ linux-2.3.99-pre7-3/drivers/usb/usb-core.c Wed May 3 15:08:31 2000
@@ -65,7 +65,7 @@
#endif
{
usb_major_init();
- usbdevfs_init();
+ usbdevfs_init();
usb_hub_init();
#ifndef CONFIG_USB_MODULE
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/usb-devfs.c
linux-2.3.99-pre7-3/drivers/usb/usb-devfs.c
--- linux-2.3.99-pre7-3.orig/drivers/usb/usb-devfs.c Wed Dec 31 16:00:00 1969
+++ linux-2.3.99-pre7-3/drivers/usb/usb-devfs.c Wed May 3 19:08:42 2000
@@ -0,0 +1,150 @@
+/*****************************************************************************/
+/*
+ * usb-devfs.c -- Create devfs nodes for busses/devices
+ *
+ * Copyright (C) 2000
+ * Thomas Sailer ([EMAIL PROTECTED])
+ * Johannes Erdfelt ([EMAIL PROTECTED])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * History:
+ * 0.1 04.01.2000 Created
+ */
+
+/*****************************************************************************/
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/locks.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/usb.h>
+#include <linux/usbdevice_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/uaccess.h>
+
+/* --------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------- */
+
+void usbdevfs_add_bus(struct usb_bus *bus)
+{
+#ifdef CONFIG_DEVFS_FS
+ char bus_path[100];
+
+ sprintf(bus_path, "usb/bus%d", bus->busnum);
+ bus->devfs_handle = devfs_mk_dir(NULL, bus_path, 0, bus);
+#endif
+
+ usbdevfs_conn_disc_event();
+}
+
+void usbdevfs_remove_bus(struct usb_bus *bus)
+{
+#ifdef CONFIG_DEVFS_FS
+ devfs_unregister(bus->devfs_handle);
+ bus->devfs_handle = NULL;
+#endif
+
+ usbdevfs_conn_disc_event();
+}
+
+void usbdevfs_add_device(struct usb_device *dev)
+{
+#ifdef CONFIG_DEVFS_FS
+ char dev_path[100];
+
+ sprintf(dev_path, "device%d", dev->devnum);
+
+ dev->devfs_handle = devfs_register(dev->bus->devfs_handle, dev_path,
+ 0, DEVFS_FL_REMOVABLE, 0, 0, S_IFREG | S_IRUGO | S_IWUSR, 0, 0,
+ &usbdevfs_device_file_operations, dev);
+ if (!dev->devfs_handle) {
+ err("couldn't allocate devfs file %s", dev_path);
+ return;
+ }
+#endif
+
+ usbdevfs_conn_disc_event();
+}
+
+void usbdevfs_remove_device(struct usb_device *dev)
+{
+ struct dev_state *ds;
+ struct siginfo sinfo;
+
+#ifdef CONFIG_DEVFS_FS
+ devfs_unregister(dev->devfs_handle);
+ dev->devfs_handle = NULL;
+#endif
+
+ lock_kernel();
+ while (!list_empty(&dev->filelist)) {
+ ds = list_entry(dev->filelist.next, struct dev_state, list);
+ list_del(&ds->list);
+ INIT_LIST_HEAD(&ds->list);
+ down_write(&ds->devsem);
+ ds->dev = NULL;
+ up_write(&ds->devsem);
+ if (ds->discsignr) {
+ sinfo.si_signo = SIGPIPE;
+ sinfo.si_errno = EPIPE;
+ sinfo.si_code = SI_ASYNCIO;
+ sinfo.si_addr = ds->disccontext;
+ send_sig_info(ds->discsignr, &sinfo, ds->disctask);
+ }
+ }
+ unlock_kernel();
+ usbdevfs_conn_disc_event();
+}
+
+/* --------------------------------------------------------------------- */
+
+#ifdef CONFIG_DEVFS_FS
+static devfs_handle_t devices_devfs_handle = NULL;
+static devfs_handle_t drivers_devfs_handle = NULL;
+#endif
+
+int __init usbdevfs_init(void)
+{
+ int ret;
+
+ if ((ret = usb_register(&usbdevfs_driver)))
+ return ret;
+#ifdef CONFIG_DEVFS_FS
+ devices_devfs_handle = devfs_register(NULL, "usb/devices", 0,
+ DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUGO | S_IWUSR, 0, 0,
+ &usbdevfs_devices_fops, NULL);
+ drivers_devfs_handle = devfs_register(NULL, "usb/drivers", 0,
+ DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUGO | S_IWUSR, 0, 0,
+ &usbdevfs_drivers_fops, NULL);
+#endif
+ return ret;
+}
+
+void __exit usbdevfs_cleanup(void)
+{
+ usb_deregister(&usbdevfs_driver);
+#ifdef CONFIG_DEVFS_FS
+ devfs_unregister(devices_devfs_handle);
+ devfs_unregister(drivers_devfs_handle);
+#endif
+}
+
diff -urN linux-2.3.99-pre7-3.orig/drivers/usb/usb.c
linux-2.3.99-pre7-3/drivers/usb/usb.c
--- linux-2.3.99-pre7-3.orig/drivers/usb/usb.c Tue Apr 11 16:56:26 2000
+++ linux-2.3.99-pre7-3/drivers/usb/usb.c Wed May 3 19:53:30 2000
@@ -48,6 +48,17 @@
static struct usb_driver *usb_minors[16];
+struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
+{
+ int i;
+
+ for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
+ if (dev->actconfig->interface[i].altsetting[0]. bInterfaceNumber ==
+ifnum)
+ return &dev->actconfig->interface[i];
+
+ return NULL;
+}
+
int usb_register(struct usb_driver *new_driver)
{
struct list_head *tmp;
@@ -242,7 +253,6 @@
bus->bandwidth_isoc_reqs = 0;
INIT_LIST_HEAD(&bus->bus_list);
- INIT_LIST_HEAD(&bus->inodes);
return bus;
}
@@ -452,8 +462,7 @@
dev->bus = bus;
dev->parent = parent;
atomic_set(&dev->refcnt, 1);
- INIT_LIST_HEAD(&dev->inodes);
- INIT_LIST_HEAD(&dev->filelist);
+ INIT_LIST_HEAD(&dev->filelist);
dev->bus->op->allocate(dev);
@@ -981,7 +990,7 @@
begin = buffer;
numskipped = 0;
- /* Skip over at Interface class or vendor descriptors */
+ /* Skip over any interface, class or vendor descriptors */
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
@@ -1142,6 +1151,13 @@
if (!dev->config)
return;
+ if (dev->rawdescriptors) {
+ for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+ kfree(dev->rawdescriptors[i]);
+
+ kfree(dev->rawdescriptors);
+ }
+
for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
struct usb_config_descriptor *cf = &dev->config[c];
@@ -1297,15 +1313,13 @@
usb_disconnect(child);
}
- /* remove /proc/bus/usb entry */
- usbdevfs_remove_device(dev);
+ usbdevfs_remove_device(dev);
/* Free up the device itself, including its device number */
if (dev->devnum > 0)
clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
-
+
usb_free_dev(dev);
-
}
/*
@@ -1492,15 +1506,10 @@
int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
- struct usb_interface *iface = NULL;
- int ret, i;
+ struct usb_interface *iface;
+ int ret;
- for (i=0; i<dev->actconfig->bNumInterfaces; i++) {
- if (dev->actconfig->interface[i].altsetting->bInterfaceNumber ==
interface) {
- iface = &dev->actconfig->interface[i];
- break;
- }
- }
+ iface = usb_ifnum_to_if(dev, interface);
if (!iface) {
warn("selecting invalid interface %d", interface);
return -EINVAL;
@@ -1562,11 +1571,10 @@
int usb_get_configuration(struct usb_device *dev)
{
- int result;
- unsigned int cfgno;
+ int result;
+ unsigned int cfgno, length;
unsigned char buffer[8];
unsigned char *bigbuffer;
- unsigned int tmp;
struct usb_config_descriptor *desc =
(struct usb_config_descriptor *)buffer;
@@ -1590,9 +1598,14 @@
memset(dev->config, 0, dev->descriptor.bNumConfigurations *
sizeof(struct usb_config_descriptor));
- for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
-
+ dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
+ dev->descriptor.bNumConfigurations, GFP_KERNEL);
+ if (!dev->rawdescriptors) {
+ err("out of memory");
+ return -1;
+ }
+ for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
/* We grab the first 8 bytes so we know how long the whole */
/* configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
@@ -1600,41 +1613,41 @@
if (result < 0)
err("unable to get descriptor");
else
- err("config descriptor too short (expected %i, got
%i)",8,result);
+ err("config descriptor too short (expected %i, got
+%i)", 8, result);
goto err;
}
/* Get the full buffer */
- le16_to_cpus(&desc->wTotalLength);
+ length = le16_to_cpu(desc->wTotalLength);
- bigbuffer = kmalloc(desc->wTotalLength, GFP_KERNEL);
+ bigbuffer = kmalloc(length, GFP_KERNEL);
if (!bigbuffer) {
err("unable to allocate memory for configuration descriptors");
- result=-ENOMEM;
+ result = -ENOMEM;
goto err;
}
- tmp=desc->wTotalLength;
+
/* Now that we know the length, get the whole thing */
- result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer,
desc->wTotalLength);
+ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer,
+length);
if (result < 0) {
err("couldn't get all of config descriptors");
kfree(bigbuffer);
goto err;
}
-
- if (result < tmp) {
- err("config descriptor too short (expected %i, got
%i)",tmp,result);
+
+ if (result < length) {
+ err("config descriptor too short (expected %i, got %i)",
+length, result);
kfree(bigbuffer);
goto err;
}
- result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer);
- kfree(bigbuffer);
+ dev->rawdescriptors[cfgno] = bigbuffer;
+
+ result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer);
if (result > 0)
dbg("descriptor data left");
- else if (result < 0)
- {
- result=-1;
+ else if (result < 0) {
+ result = -1;
goto err;
}
}
@@ -1715,8 +1728,7 @@
*/
int usb_new_device(struct usb_device *dev)
{
- int addr, err;
- int tmp;
+ int err;
info("USB new device connect, assigned device number %d", dev->devnum);
@@ -1727,10 +1739,15 @@
dev->epmaxpacketin [0] = 8;
dev->epmaxpacketout[0] = 8;
- /* Even though we have assigned an address for the device, we */
- /* haven't told it what it's address is yet */
- addr = dev->devnum;
- dev->devnum = 0;
+ err = usb_set_address(dev);
+ if (err < 0) {
+ err("USB device not accepting new address (error=%d)", err);
+ clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
+ dev->devnum = -1;
+ return 1;
+ }
+
+ wait_ms(10); /* Let the SET_ADDRESS settle */
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
if (err < 8) {
@@ -1738,34 +1755,19 @@
err("USB device not responding, giving up (error=%d)", err);
else
err("USB device descriptor short read (expected %i, got
%i)",8,err);
- clear_bit(addr, &dev->bus->devmap.devicemap);
+ clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
}
dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
- dev->devnum = addr;
-
- err = usb_set_address(dev);
-
- if (err < 0) {
- err("USB device not accepting new address (error=%d)", err);
- clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
- dev->devnum = -1;
- return 1;
- }
-
- wait_ms(10); /* Let the SET_ADDRESS settle */
-
- tmp = sizeof(dev->descriptor);
-
err = usb_get_device_descriptor(dev);
- if (err < tmp) {
+ if (err < sizeof(dev->descriptor)) {
if (err < 0)
- err("unable to get device descriptor (error=%d)",err);
+ err("unable to get device descriptor (error=%d)", err);
else
- err("USB device descriptor short read (expected %i, got
%i)",tmp,err);
+ err("USB device descriptor short read (expected %i, got %i)",
+sizeof(dev->descriptor), err);
clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
dev->devnum = -1;
@@ -1800,8 +1802,8 @@
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
#endif
- /* now that the basic setup is over, add a /proc/bus/usb entry */
- usbdevfs_add_device(dev);
+ /* now that the basic setup is over, add a /dev/usb entry */
+ usbdevfs_add_device(dev);
/* find drivers willing to handle this device */
usb_find_drivers(dev);
@@ -1859,6 +1861,8 @@
* into the kernel, and other device drivers are built as modules,
* then these symbols need to be exported for the modules to use.
*/
+EXPORT_SYMBOL(usb_ifnum_to_if);
+
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
EXPORT_SYMBOL(usb_alloc_bus);
diff -urN linux-2.3.99-pre7-3.orig/include/linux/fs.h
linux-2.3.99-pre7-3/include/linux/fs.h
--- linux-2.3.99-pre7-3.orig/include/linux/fs.h Thu May 4 11:33:15 2000
+++ linux-2.3.99-pre7-3/include/linux/fs.h Wed May 3 15:48:20 2000
@@ -277,7 +277,6 @@
#include <linux/udf_fs_i.h>
#include <linux/ncp_fs_i.h>
#include <linux/proc_fs_i.h>
-#include <linux/usbdev_fs_i.h>
/*
* Attribute flags. These should be or-ed together to figure out what
@@ -431,7 +430,6 @@
struct ncp_inode_info ncpfs_i;
struct proc_inode_info proc_i;
struct socket socket_i;
- struct usbdev_inode_info usbdev_i;
void *generic_ip;
} u;
};
@@ -601,7 +599,6 @@
#include <linux/bfs_fs_sb.h>
#include <linux/udf_fs_sb.h>
#include <linux/ncp_fs_sb.h>
-#include <linux/usbdev_fs_sb.h>
extern struct list_head super_blocks;
@@ -648,7 +645,6 @@
struct bfs_sb_info bfs_sb;
struct udf_sb_info udf_sb;
struct ncp_sb_info ncpfs_sb;
- struct usbdev_sb_info usbdevfs_sb;
void *generic_sbp;
} u;
/*
diff -urN linux-2.3.99-pre7-3.orig/include/linux/usb.h
linux-2.3.99-pre7-3/include/linux/usb.h
--- linux-2.3.99-pre7-3.orig/include/linux/usb.h Thu May 4 11:33:15 2000
+++ linux-2.3.99-pre7-3/include/linux/usb.h Wed May 3 16:17:15 2000
@@ -132,6 +132,7 @@
#include <linux/interrupt.h> /* for in_interrupt() */
#include <linux/config.h>
#include <linux/list.h>
+#include <linux/devfs_fs_kernel.h>
#define USB_MAJOR 180
@@ -491,8 +492,9 @@
int bandwidth_int_reqs; /* number of Interrupt requesters */
int bandwidth_isoc_reqs; /* number of Isoc. requesters */
- /* usbdevfs inode list */
- struct list_head inodes;
+#ifdef CONFIG_DEVFS_FS
+ devfs_handle_t devfs_handle;
+#endif
};
#define USB_MAXCHILDREN (8) /* This is arbitrary */
@@ -506,7 +508,6 @@
unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] =
OUT) */
unsigned int halted[2]; /* endpoint halts; one bit per endpoint # &
direction; */
/* [0] = IN, [1] = OUT */
- struct usb_config_descriptor *actconfig;/* the active configuration */
int epmaxpacketin[16]; /* INput endpoint specific maximums */
int epmaxpacketout[16]; /* OUTput endpoint specific maximums */
@@ -515,6 +516,9 @@
struct usb_device_descriptor descriptor;/* Descriptor */
struct usb_config_descriptor *config; /* All of the configs */
+ struct usb_config_descriptor *actconfig;/* the active configuration */
+
+ char **rawdescriptors; /* Raw descriptors for each config */
int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */
@@ -522,8 +526,11 @@
void *hcpriv; /* Host Controller private data */
/* usbdevfs inode list */
- struct list_head inodes;
- struct list_head filelist;
+ struct list_head filelist;
+
+#ifdef CONFIG_DEVFS_FS
+ devfs_handle_t devfs_handle;
+#endif
/*
* Child devices - these can be either new devices
@@ -537,6 +544,8 @@
struct usb_device *children[USB_MAXCHILDREN];
};
+extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
+
extern int usb_register(struct usb_driver *);
extern void usb_deregister(struct usb_driver *);
@@ -743,11 +752,10 @@
* USB device fs stuff
*/
-#ifdef CONFIG_USB_DEVICEFS
-
/*
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
+ * make sure this is true --jerdfelt
*/
extern void usbdevfs_add_bus(struct usb_bus *bus);
extern void usbdevfs_remove_bus(struct usb_bus *bus);
@@ -756,18 +764,6 @@
extern int usbdevfs_init(void);
extern void usbdevfs_cleanup(void);
-
-#else /* CONFIG_USB_DEVICEFS */
-
-extern inline void usbdevfs_add_bus(struct usb_bus *bus) {}
-extern inline void usbdevfs_remove_bus(struct usb_bus *bus) {}
-extern inline void usbdevfs_add_device(struct usb_device *dev) {}
-extern inline void usbdevfs_remove_device(struct usb_device *dev) {}
-
-extern inline int usbdevfs_init(void) { return 0; }
-extern inline void usbdevfs_cleanup(void) { }
-
-#endif /* CONFIG_USB_DEVICEFS */
#endif /* __KERNEL__ */
diff -urN linux-2.3.99-pre7-3.orig/include/linux/usbdev_fs_i.h
linux-2.3.99-pre7-3/include/linux/usbdev_fs_i.h
--- linux-2.3.99-pre7-3.orig/include/linux/usbdev_fs_i.h Mon Jan 10 11:32:48
2000
+++ linux-2.3.99-pre7-3/include/linux/usbdev_fs_i.h Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-struct usb_device;
-struct usb_bus;
-
-struct usbdev_inode_info {
- struct list_head dlist;
- struct list_head slist;
- union {
- struct usb_device *dev;
- struct usb_bus *bus;
- } p;
-};
diff -urN linux-2.3.99-pre7-3.orig/include/linux/usbdev_fs_sb.h
linux-2.3.99-pre7-3/include/linux/usbdev_fs_sb.h
--- linux-2.3.99-pre7-3.orig/include/linux/usbdev_fs_sb.h Mon Jan 10 11:32:48
2000
+++ linux-2.3.99-pre7-3/include/linux/usbdev_fs_sb.h Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-struct usbdev_sb_info {
- struct list_head slist;
- struct list_head ilist;
- uid_t devuid;
- gid_t devgid;
- umode_t devmode;
- uid_t busuid;
- gid_t busgid;
- umode_t busmode;
-};
diff -urN linux-2.3.99-pre7-3.orig/include/linux/usbdevice_fs.h
linux-2.3.99-pre7-3/include/linux/usbdevice_fs.h
--- linux-2.3.99-pre7-3.orig/include/linux/usbdevice_fs.h Mon Apr 10 22:55:08
2000
+++ linux-2.3.99-pre7-3/include/linux/usbdevice_fs.h Wed May 3 16:16:44 2000
@@ -33,8 +33,6 @@
/* --------------------------------------------------------------------- */
-#define USBDEVICE_SUPER_MAGIC 0x9fa2
-
/* usbdevfs ioctl codes */
struct usbdevfs_ctrltransfer {
@@ -64,6 +62,13 @@
void *context;
};
+#define USBDEVFS_MAXDRIVERNAME 255
+
+struct usbdevfs_driver {
+ unsigned int interface;
+ char driver[USBDEVFS_MAXDRIVERNAME + 1];
+};
+
#define USBDEVFS_URB_DISABLE_SPD 1
#define USBDEVFS_URB_ISO_ASAP 2
@@ -99,6 +104,7 @@
#define USBDEVFS_RESETEP _IOR('U', 3, unsigned int)
#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
#define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int)
+#define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_driver)
#define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb)
#define USBDEVFS_DISCARDURB _IO('U', 11)
#define USBDEVFS_REAPURB _IOW('U', 12, void *)
@@ -115,18 +121,6 @@
#include <asm/semaphore.h>
/*
- * inode number macros
- */
-#define ITYPE(x) ((x)&(0xf<<28))
-#define ISPECIAL (0<<28)
-#define IBUS (1<<28)
-#define IDEVICE (2<<28)
-#define IBUSNR(x) (((x)>>8)&0xff)
-#define IDEVNR(x) ((x)&0xff)
-
-#define IROOT 1
-
-/*
* sigh. rwsemaphores do not (yet) work from modules
*/
@@ -158,11 +152,7 @@
extern struct file_operations usbdevfs_drivers_fops;
extern struct file_operations usbdevfs_devices_fops;
extern struct file_operations usbdevfs_device_file_operations;
-extern struct inode_operations usbdevfs_device_inode_operations;
-extern struct inode_operations usbdevfs_bus_inode_operations;
-extern struct file_operations usbdevfs_bus_file_operations;
extern void usbdevfs_conn_disc_event(void);
-
#endif /* __KERNEL__ */
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]