2002-09-27 19:33:48

by Greg KH

[permalink] [raw]
Subject: [BK PATCH] More USB changes for 2.5.38

Hi,

This series includes some USB changes, and my changes to the driver core
to move /sbin/hotplug notification there, and out of the USB and PCI
cores. This patch has been previously posted and discussed.

Please pull from: bk://linuxusb.bkbits.net/linus-2.5

thanks,

greg k-h

drivers/base/Makefile | 2
drivers/base/base.h | 10 ++
drivers/base/core.c | 6 +
drivers/base/hotplug.c | 103 +++++++++++++++++++++++
drivers/net/irda/irda-usb.c | 65 ++++++++------
drivers/pci/hotplug.c | 96 ++++++++++++---------
drivers/pci/pci-driver.c | 6 -
drivers/pci/pci.h | 5 +
drivers/usb/core/usb.c | 163 ++++++++++++++++++-------------------
drivers/usb/storage/sddr55.c | 2
drivers/usb/storage/transport.c | 8 +
drivers/usb/storage/unusual_devs.h | 15 ++-
drivers/usb/usb-skeleton.c | 37 ++++----
include/linux/device.h | 2
include/net/irda/irda-usb.h | 2
15 files changed, 343 insertions(+), 179 deletions(-)
-----

[email protected], 2002-09-27 11:32:53-07:00, [email protected]
converted PCI to use the driver core's hotplug call.

drivers/pci/hotplug.c | 96 ++++++++++++++++++++++++++---------------------
drivers/pci/pci-driver.c | 6 +-
drivers/pci/pci.h | 5 ++
3 files changed, 63 insertions(+), 44 deletions(-)
------

[email protected], 2002-09-27 11:29:36-07:00, [email protected]
converted USB to use the driver core's hotplug call.

drivers/usb/core/usb.c | 163 ++++++++++++++++++++++++-------------------------
1 files changed, 81 insertions(+), 82 deletions(-)
------

[email protected], 2002-09-27 11:21:46-07:00, [email protected]
add hotplug support to the driver core for devices, if their bus type supports it.

drivers/base/Makefile | 2
drivers/base/base.h | 10 ++++
drivers/base/core.c | 6 ++
drivers/base/hotplug.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/device.h | 2
5 files changed, 123 insertions(+)
------

[email protected], 2002-09-26 23:07:16-07:00, [email protected]
[PATCH] USB storage: Another (!) patch for the abort handler

This is a simple, obvious patch for the abort handler. I don't know how
we missed it before.

Fix abort problem: us->srb was used after it was erased.

drivers/usb/storage/transport.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
------

[email protected], 2002-09-26 23:03:01-07:00, [email protected]
[PATCH] USB 2.0 HDD Walker / ST-HW-818SLIM usb-storage fix


drivers/usb/storage/unusual_devs.h | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
------

[email protected], 2002-09-26 23:01:59-07:00, [email protected]
[PATCH] fix compares of jiffies

on rechecking the current stable kernel code, I found some places where jiffies
were compared in a way that seems to break when they wrap. For these,
I made up patches to use the macros "time_before()" or "time_after()"
that are supposed to handle wraparound correctly.

drivers/usb/storage/sddr55.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
------

[email protected], 2002-09-26 23:01:20-07:00, [email protected]
[PATCH] Update for JMTek USBDrive

Attached is a patch against the 2.4.19 linux kernel. It adds an entry
for another version of the JMTek USBDrive (driverless), and also updates
my email address.

drivers/usb/storage/unusual_devs.h | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
------

[email protected], 2002-09-26 17:17:41-07:00, [email protected]
USB: fix ifnum usage that was missed in the previous irda-usb patch

drivers/net/irda/irda-usb.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
------

[email protected], 2002-09-26 16:11:18-07:00, [email protected]
USB: convert the usb-skeleton.c driver to work with the latest USB core changes.

drivers/usb/usb-skeleton.c | 37 ++++++++++++++++++++++---------------
1 files changed, 22 insertions(+), 15 deletions(-)
------

[email protected], 2002-09-26 15:35:06-07:00, [email protected]
USB: convert the irda-usb driver to work properly with the new USB core changes.

drivers/net/irda/irda-usb.c | 63 ++++++++++++++++++++++++--------------------
include/net/irda/irda-usb.h | 2 -
2 files changed, 36 insertions(+), 29 deletions(-)
------


2002-09-27 19:35:23

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611 -> 1.611.1.1
# drivers/net/irda/irda-usb.c 1.24 -> 1.25
# include/net/irda/irda-usb.h 1.6 -> 1.7
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.1
# USB: convert the irda-usb driver to work properly with the new USB core changes.
# --------------------------------------------
#
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c Fri Sep 27 12:30:28 2002
+++ b/drivers/net/irda/irda-usb.c Fri Sep 27 12:30:28 2002
@@ -36,14 +36,11 @@
* This driver has been tested SUCCESSFULLY with the following drivers :
* o usb-uhci-hcd (For Intel/Via USB controllers)
* o uhci-hcd (Alternate/JE driver for Intel/Via USB controllers)
+ * o ohci-hcd (For other USB controllers)
*
* This driver has NOT been tested with the following drivers :
* o ehci-hcd (USB 2.0 controllers)
*
- * This driver DOESN'T SEEM TO WORK with the following drivers :
- * o ohci-hcd (For other USB controllers)
- * The first outgoing URB never calls its completion/failure callback.
- *
* Note that all HCD drivers do USB_ZERO_PACKET and timeout properly,
* so we don't have to worry about that anymore.
* One common problem is the failure to set the address on the dongle,
@@ -104,8 +101,8 @@

/*------------------------------------------------------------------*/

-static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum);
-static void irda_usb_disconnect(struct usb_device *dev, void *ptr);
+static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
+static void irda_usb_disconnect(struct usb_interface *intf);
static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
static int irda_usb_open(struct irda_usb_cb *self);
@@ -1340,7 +1337,7 @@

/*------------------------------------------------------------------*/
/*
- * Function irda_usb_find_class_desc(dev, ifnum)
+ * Function irda_usb_find_class_desc(intf)
*
* Returns instance of IrDA class descriptor, or NULL if not found
*
@@ -1348,8 +1345,9 @@
* offer to us, describing their IrDA characteristics. We will use that in
* irda_usb_init_qos()
*/
-static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
+static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf)
{
+ struct usb_device *dev = interface_to_usbdev (intf);
struct irda_class_desc *desc;
int ret;

@@ -1368,7 +1366,8 @@
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
IU_REQ_GET_CLASS_DESC,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, ifnum, desc, sizeof(*desc), MSECS_TO_JIFFIES(500));
+ 0, intf->altsetting->bInterfaceNumber, desc,
+ sizeof(*desc), MSECS_TO_JIFFIES(500));

IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret);
if (ret < sizeof(*desc)) {
@@ -1403,9 +1402,10 @@
* Note : it might be worth protecting this function by a global
* spinlock... Or not, because maybe USB already deal with that...
*/
-static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
+static int irda_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct usb_device *dev = interface_to_usbdev(intf);
struct irda_usb_cb *self = NULL;
struct usb_interface_descriptor *interface;
struct irda_class_desc *irda_desc;
@@ -1430,7 +1430,7 @@
(irda->present == 0) &&
(irda->netopen == 0)) {
IRDA_DEBUG(0, "%s(), found a zombie instance !!!\n", __FUNCTION__);
- irda_usb_disconnect(irda->usbdev, (void *) irda);
+ irda_usb_disconnect(irda->usbintf);
}
}

@@ -1445,7 +1445,7 @@
if(self == NULL) {
WARNING("Too many USB IrDA devices !!! (max = %d)\n",
NIRUSB);
- return NULL;
+ return -ENFILE;
}

/* Reset the instance */
@@ -1459,34 +1459,34 @@
int j;
for (j = 0; j < i; j++)
usb_free_urb(self->rx_urb[j]);
- return NULL;
+ return -ENOMEM;
}
}
self->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!self->tx_urb) {
for (i = 0; i < IU_MAX_RX_URBS; i++)
usb_free_urb(self->rx_urb[i]);
- return NULL;
+ return -ENOMEM;
}
self->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!self->speed_urb) {
for (i = 0; i < IU_MAX_RX_URBS; i++)
usb_free_urb(self->rx_urb[i]);
usb_free_urb(self->tx_urb);
- return NULL;
+ return -ENOMEM;
}

/* Is this really necessary? */
if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
err("set_configuration failed");
- return NULL;
+ return -EIO;
}

/* Is this really necessary? */
/* Note : some driver do hardcode the interface number, some others
* specify an alternate, but very few driver do like this.
* Jean II */
- ret = usb_set_interface(dev, ifnum, 0);
+ ret = usb_set_interface(dev, intf->altsetting->bInterfaceNumber, 0);
IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret);
switch (ret) {
case 0:
@@ -1497,33 +1497,35 @@
break;
default:
IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret);
- return NULL;
+ return -EIO;
break;
}

/* Find our endpoints */
- interface = &dev->actconfig->interface[ifnum].altsetting[0];
+ interface = &intf->altsetting[0];
if(!irda_usb_parse_endpoints(self, interface->endpoint,
interface->bNumEndpoints)) {
ERROR("%s(), Bogus endpoints...\n", __FUNCTION__);
- return NULL;
+ return -EIO;
}

/* Find IrDA class descriptor */
- irda_desc = irda_usb_find_class_desc(dev, ifnum);
+ irda_desc = irda_usb_find_class_desc(intf);
if (irda_desc == NULL)
- return NULL;
+ return -ENODEV;

self->irda_desc = irda_desc;
self->present = 1;
self->netopen = 0;
self->capability = id->driver_info;
self->usbdev = dev;
+ self->usbintf = intf;
ret = irda_usb_open(self);
if (ret)
- return NULL;
+ return -ENOMEM;

- return self;
+ dev_set_drvdata(&intf->dev, self);
+ return 0;
}

/*------------------------------------------------------------------*/
@@ -1538,14 +1540,18 @@
* So, we must make bloody sure that everything gets deactivated.
* Jean II
*/
-static void irda_usb_disconnect(struct usb_device *dev, void *ptr)
+static void irda_usb_disconnect(struct usb_interface *intf)
{
unsigned long flags;
- struct irda_usb_cb *self = (struct irda_usb_cb *) ptr;
+ struct irda_usb_cb *self = dev_get_drvdata (&intf->dev);
int i;

IRDA_DEBUG(1, "%s()\n", __FUNCTION__);

+ dev_set_drvdata(&intf->dev, NULL);
+ if (!self)
+ return;
+
/* Make sure that the Tx path is not executing. - Jean II */
spin_lock_irqsave(&self->lock, flags);

@@ -1577,6 +1583,7 @@
irda_usb_close(self);
/* No longer attached to USB bus */
self->usbdev = NULL;
+ self->usbintf = NULL;

/* Clean up our urbs */
for (i = 0; i < IU_MAX_RX_URBS; i++)
@@ -1635,7 +1642,7 @@
/* If the Device is zombie */
if((irda->usbdev != NULL) && (irda->present == 0)) {
IRDA_DEBUG(0, "%s(), disconnect zombie now !\n", __FUNCTION__);
- irda_usb_disconnect(irda->usbdev, (void *) irda);
+ irda_usb_disconnect(irda->usbintf);
}
}

diff -Nru a/include/net/irda/irda-usb.h b/include/net/irda/irda-usb.h
--- a/include/net/irda/irda-usb.h Fri Sep 27 12:30:28 2002
+++ b/include/net/irda/irda-usb.h Fri Sep 27 12:30:28 2002
@@ -127,7 +127,7 @@
struct irda_usb_cb {
struct irda_class_desc *irda_desc;
struct usb_device *usbdev; /* init: probe_irda */
- unsigned int ifnum; /* Interface number of the USB dev. */
+ struct usb_interface *usbintf; /* init: probe_irda */
int netopen; /* Device is active for network */
int present; /* Device is present on the bus */
__u32 capability; /* Capability of the hardware */

2002-09-27 19:36:49

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.1 -> 1.611.1.2
# drivers/usb/usb-skeleton.c 1.15 -> 1.16
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.2
# USB: convert the usb-skeleton.c driver to work with the latest USB core changes.
# --------------------------------------------
#
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c Fri Sep 27 12:30:25 2002
+++ b/drivers/usb/usb-skeleton.c Fri Sep 27 12:30:25 2002
@@ -1,12 +1,11 @@
/*
- * USB Skeleton driver - 0.7
+ * USB Skeleton driver - 0.8
*
- * Copyright (c) 2001 Greg Kroah-Hartman ([email protected])
+ * Copyright (c) 2001-2002 Greg Kroah-Hartman ([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.
+ * published by the Free Software Foundation, version 2.
*
*
* This driver is to be used as a skeleton driver to be able to create a
@@ -22,6 +21,8 @@
*
* History:
*
+ * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device
+ * driver.
* 2002_02_12 - 0.7 - zero out dev in probe function for devices that do
* not have both a bulk in and bulk out endpoint.
* Thanks to Holger Waechtler for the fix.
@@ -133,8 +134,8 @@
static int skel_open (struct inode *inode, struct file *file);
static int skel_release (struct inode *inode, struct file *file);

-static void * skel_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);
-static void skel_disconnect (struct usb_device *dev, void *ptr);
+static int skel_probe (struct usb_interface *intf, const struct usb_device_id *id);
+static void skel_disconnect (struct usb_interface *intf);

static void skel_write_bulk_callback (struct urb *urb);

@@ -509,10 +510,10 @@
* Called by the usb core when a new device is connected that it thinks
* this driver might be interested in.
*/
-static void * skel_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
+ struct usb_device *udev = interface_to_usbdev(interface);
struct usb_skel *dev = NULL;
- struct usb_interface *interface;
struct usb_interface_descriptor *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int minor;
@@ -525,7 +526,7 @@
/* See if the device offered us matches what we can accept */
if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) ||
(udev->descriptor.idProduct != USB_SKEL_PRODUCT_ID)) {
- return NULL;
+ return -ENODEV;
}

down (&minor_table_mutex);
@@ -545,8 +546,6 @@
memset (dev, 0x00, sizeof (*dev));
minor_table[minor] = dev;

- interface = &udev->actconfig->interface[ifnum];
-
init_MUTEX (&dev->sem);
dev->udev = udev;
dev->interface = interface;
@@ -619,7 +618,11 @@

exit:
up (&minor_table_mutex);
- return dev;
+ if (dev) {
+ dev_set_drvdata (&interface->dev, dev);
+ return 0;
+ }
+ return -ENODEV;
}


@@ -628,13 +631,17 @@
*
* Called by the usb core when the device is removed from the system.
*/
-static void skel_disconnect(struct usb_device *udev, void *ptr)
+static void skel_disconnect(struct usb_interface *interface)
{
struct usb_skel *dev;
int minor;

- dev = (struct usb_skel *)ptr;
-
+ dev = dev_get_drvdata (&interface->dev);
+ dev_set_drvdata (&interface->dev, NULL);
+
+ if (!dev)
+ return;
+
down (&minor_table_mutex);
down (&dev->sem);

2002-09-27 19:37:17

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.2 -> 1.611.1.3
# drivers/net/irda/irda-usb.c 1.25 -> 1.26
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.3
# USB: fix ifnum usage that was missed in the previous irda-usb patch
# --------------------------------------------
#
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c Fri Sep 27 12:30:22 2002
+++ b/drivers/net/irda/irda-usb.c Fri Sep 27 12:30:22 2002
@@ -1487,7 +1487,7 @@
* specify an alternate, but very few driver do like this.
* Jean II */
ret = usb_set_interface(dev, intf->altsetting->bInterfaceNumber, 0);
- IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret);
+ IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->bInterfaceNumber, ret);
switch (ret) {
case 0:
break;

2002-09-27 19:39:30

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.4 -> 1.611.1.5
# drivers/usb/storage/sddr55.c 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.5
# [PATCH] fix compares of jiffies
#
# on rechecking the current stable kernel code, I found some places where jiffies
# were compared in a way that seems to break when they wrap. For these,
# I made up patches to use the macros "time_before()" or "time_after()"
# that are supposed to handle wraparound correctly.
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
--- a/drivers/usb/storage/sddr55.c Fri Sep 27 12:30:17 2002
+++ b/drivers/usb/storage/sddr55.c Fri Sep 27 12:30:17 2002
@@ -788,7 +788,7 @@
/* only check card status if the map isn't allocated, ie no card seen yet
* or if it's been over half a second since we last accessed it
*/
- if (info->lba_to_pba == NULL || jiffies > (info->last_access + HZ/2)) {
+ if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {

/* check to see if a card is fitted */
result = sddr55_status (us);

2002-09-27 19:42:59

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.8 -> 1.611.1.9
# drivers/usb/core/usb.c 1.87 -> 1.88
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/27 [email protected] 1.611.1.9
# converted USB to use the driver core's hotplug call.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Fri Sep 27 12:30:06 2002
+++ b/drivers/usb/core/usb.c Fri Sep 27 12:30:06 2002
@@ -510,57 +510,42 @@
* cases, we know no other thread can recycle our address, since we must
* already have been serialized enough to prevent that.
*/
-static void call_policy (char *verb, struct usb_device *dev)
+static int usb_hotplug (struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
{
- char *argv [3], **envp, *buf, *scratch;
- int i = 0, value;
+ struct usb_interface *intf;
+ struct usb_device *usb_dev;
+ char *scratch;
+ int i = 0;
+ int length = 0;

- if (!hotplug_path [0])
- return;
- if (in_interrupt ()) {
- dbg ("In_interrupt");
- return;
- }
- if (!current->fs->root) {
- /* statically linked USB is initted rather early */
- dbg ("call_policy %s, num %d -- no FS yet", verb, dev->devnum);
- return;
- }
- if (dev->devnum < 0) {
+ dbg ("%s", __FUNCTION__);
+
+ if (!dev)
+ return -ENODEV;
+
+ /* check for generic driver, we do not call do hotplug calls for it */
+ if (dev->driver == &usb_generic_driver)
+ return -ENODEV;
+
+ intf = to_usb_interface(dev);
+ if (!intf)
+ return -ENODEV;
+
+ usb_dev = interface_to_usbdev (intf);
+ if (!usb_dev)
+ return -ENODEV;
+
+ if (usb_dev->devnum < 0) {
dbg ("device already deleted ??");
- return;
+ return -ENODEV;
}
- if (!(envp = (char **) kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
- dbg ("enomem");
- return;
- }
- if (!(buf = kmalloc (256, GFP_KERNEL))) {
- kfree (envp);
- dbg ("enomem2");
- return;
+ if (!usb_dev->bus) {
+ dbg ("bus already removed?");
+ return -ENODEV;
}

- /* only one standardized param to hotplug command: type */
- argv [0] = hotplug_path;
- argv [1] = "usb";
- argv [2] = 0;
-
- /* minimal command environment */
- envp [i++] = "HOME=/";
- envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
-#ifdef DEBUG
- /* hint that policy agent should enter no-stdout debug mode */
- envp [i++] = "DEBUG=kernel";
-#endif
- /* extensible set of named bus-specific parameters,
- * supporting multiple driver selection algorithms.
- */
- scratch = buf;
-
- /* action: add, remove */
- envp [i++] = scratch;
- scratch += sprintf (scratch, "ACTION=%s", verb) + 1;
+ scratch = buffer;

#ifdef CONFIG_USB_DEVICEFS
/* If this is available, userspace programs can directly read
@@ -569,27 +554,48 @@
*
* FIXME reduce hardwired intelligence here
*/
- envp [i++] = "DEVFS=/proc/bus/usb";
envp [i++] = scratch;
- scratch += sprintf (scratch, "DEVICE=/proc/bus/usb/%03d/%03d",
- dev->bus->busnum, dev->devnum) + 1;
+ length += snprintf (scratch, buffer_size - length,
+ "%s", "DEVFS=/proc/bus/usb");
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ envp [i++] = scratch;
+ length += snprintf (scratch, buffer_size - length,
+ "DEVICE=/proc/bus/usb/%03d/%03d",
+ usb_dev->bus->busnum, usb_dev->devnum);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
#endif

/* per-device configuration hacks are common */
envp [i++] = scratch;
- scratch += sprintf (scratch, "PRODUCT=%x/%x/%x",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- dev->descriptor.bcdDevice) + 1;
+ length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x",
+ usb_dev->descriptor.idVendor,
+ usb_dev->descriptor.idProduct,
+ usb_dev->descriptor.bcdDevice);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;

/* class-based driver binding models */
envp [i++] = scratch;
- scratch += sprintf (scratch, "TYPE=%d/%d/%d",
- dev->descriptor.bDeviceClass,
- dev->descriptor.bDeviceSubClass,
- dev->descriptor.bDeviceProtocol) + 1;
- if (dev->descriptor.bDeviceClass == 0) {
- int alt = dev->actconfig->interface [0].act_altsetting;
+ length += snprintf (scratch, buffer_size - length, "TYPE=%d/%d/%d",
+ usb_dev->descriptor.bDeviceClass,
+ usb_dev->descriptor.bDeviceSubClass,
+ usb_dev->descriptor.bDeviceProtocol);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ if (usb_dev->descriptor.bDeviceClass == 0) {
+ int alt = intf->act_altsetting;

/* a simple/common case: one config, one interface, one driver
* with current altsetting being a reasonable setting.
@@ -597,31 +603,29 @@
* device-specific binding policies.
*/
envp [i++] = scratch;
- scratch += sprintf (scratch, "INTERFACE=%d/%d/%d",
- dev->actconfig->interface [0].altsetting [alt].bInterfaceClass,
- dev->actconfig->interface [0].altsetting [alt].bInterfaceSubClass,
- dev->actconfig->interface [0].altsetting [alt].bInterfaceProtocol)
- + 1;
- /* INTERFACE-0, INTERFACE-1, ... ? */
+ length += snprintf (scratch, buffer_size - length,
+ "INTERFACE=%d/%d/%d",
+ intf->altsetting[alt].bInterfaceClass,
+ intf->altsetting[alt].bInterfaceSubClass,
+ intf->altsetting[alt].bInterfaceProtocol);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
}
envp [i++] = 0;
- /* assert: (scratch - buf) < sizeof buf */

- /* NOTE: user mode daemons can call the agents too */
-
- dbg ("kusbd: %s %s %d", argv [0], verb, dev->devnum);
- value = call_usermodehelper (argv [0], argv, envp);
- kfree (buf);
- kfree (envp);
- if (value != 0)
- dbg ("kusbd policy returned 0x%x", value);
+ return 0;
}

#else

-static inline void
-call_policy (char *verb, struct usb_device *dev)
-{ }
+static int usb_hotplug (struct device *dev, char **envp,
+ char *buffer, int buffer_size)
+{
+ return -ENODEV;
+}

#endif /* CONFIG_HOTPLUG */

@@ -894,9 +898,6 @@
put_device(&dev->dev);
}

- /* Let policy agent unload modules etc */
- call_policy ("remove", dev);
-
/* Decrement the reference count, it'll auto free everything when */
/* it hits 0 which could very well be now */
usb_put_dev(dev);
@@ -1174,9 +1175,6 @@
/* add a /proc/bus/usb entry */
usbfs_add_device(dev);

- /* userspace may load modules and/or configure further */
- call_policy ("add", dev);
-
return 0;
}

@@ -1439,6 +1437,7 @@
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
+ .hotplug = usb_hotplug,
};

/*

2002-09-27 19:46:23

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.9 -> 1.611.1.10
# drivers/pci/pci-driver.c 1.18 -> 1.19
# drivers/pci/hotplug.c 1.5 -> 1.6
# (new) -> 1.1 drivers/pci/pci.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/27 [email protected] 1.611.1.10
# converted PCI to use the driver core's hotplug call.
# --------------------------------------------
#
diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
--- a/drivers/pci/hotplug.c Fri Sep 27 12:30:03 2002
+++ b/drivers/pci/hotplug.c Fri Sep 27 12:30:03 2002
@@ -1,52 +1,68 @@
#include <linux/pci.h>
#include <linux/module.h>
-#include <linux/kmod.h> /* for hotplug_path */
+#include "pci.h"

-#ifndef FALSE
-#define FALSE (0)
-#define TRUE (!FALSE)
-#endif

#ifdef CONFIG_HOTPLUG
-static void run_sbin_hotplug(struct pci_dev *pdev, int insert)
+int pci_hotplug (struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
{
- int i;
- char *argv[3], *envp[8];
- char id[20], sub_id[24], bus_id[24], class_id[20];
-
- if (!hotplug_path[0])
- return;
+ struct pci_dev *pdev;
+ char *scratch;
+ int i = 0;
+ int length = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ pdev = to_pci_dev(dev);
+ if (!pdev)
+ return -ENODEV;
+
+ scratch = buffer;
+
+ /* stuff we want to pass to /sbin/hotplug */
+ envp[i++] = scratch;
+ length += snprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
+ pdev->class);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ envp[i++] = scratch;
+ length += snprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
+ pdev->vendor, pdev->device);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ envp[i++] = scratch;
+ length += snprintf (scratch, buffer_size - length,
+ "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
+ pdev->subsystem_device);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ envp[i++] = scratch;
+ length += snprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
+ pdev->slot_name);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;

- sprintf(class_id, "PCI_CLASS=%04X", pdev->class);
- sprintf(id, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device);
- sprintf(sub_id, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, pdev->subsystem_device);
- sprintf(bus_id, "PCI_SLOT_NAME=%s", pdev->slot_name);
-
- i = 0;
- argv[i++] = hotplug_path;
- argv[i++] = "pci";
- argv[i] = 0;
-
- i = 0;
- /* minimal command environment */
- envp[i++] = "HOME=/";
- envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
- /* other stuff we want to pass to /sbin/hotplug */
- envp[i++] = class_id;
- envp[i++] = id;
- envp[i++] = sub_id;
- envp[i++] = bus_id;
- if (insert)
- envp[i++] = "ACTION=add";
- else
- envp[i++] = "ACTION=remove";
envp[i] = 0;

- call_usermodehelper (argv [0], argv, envp);
+ return 0;
}
#else
-static void run_sbin_hotplug(struct pci_dev *pdev, int insert) { }
+int pci_hotplug (struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ return -ENODEV;
+}
#endif

/**
@@ -66,8 +82,6 @@
#ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev);
#endif
- /* notify userspace of new hotplug device */
- run_sbin_hotplug(dev, TRUE);
}

static void
@@ -99,8 +113,6 @@
#ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev);
#endif
- /* notify userspace of hotplug device removal */
- run_sbin_hotplug(dev, FALSE);
}

#ifdef CONFIG_HOTPLUG
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c Fri Sep 27 12:30:03 2002
+++ b/drivers/pci/pci-driver.c Fri Sep 27 12:30:03 2002
@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/init.h>
+#include "pci.h"

/*
* Registration of PCI drivers and handling of hot-pluggable devices.
@@ -199,8 +200,9 @@
}

struct bus_type pci_bus_type = {
- name: "pci",
- match: pci_bus_match,
+ name: "pci",
+ match: pci_bus_match,
+ hotplug: pci_hotplug,
};

static int __init pci_driver_init(void)
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/pci/pci.h Fri Sep 27 12:30:03 2002
@@ -0,0 +1,5 @@
+/* Functions internal to the PCI core code */
+
+extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size);
+

2002-09-27 19:39:29

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.3 -> 1.611.1.4
# drivers/usb/storage/unusual_devs.h 1.18 -> 1.19
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.4
# [PATCH] Update for JMTek USBDrive
#
# Attached is a patch against the 2.4.19 linux kernel. It adds an entry
# for another version of the JMTek USBDrive (driverless), and also updates
# my email address.
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h Fri Sep 27 12:30:19 2002
+++ b/drivers/usb/storage/unusual_devs.h Fri Sep 27 12:30:19 2002
@@ -548,17 +548,22 @@
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ),

-/* Submitted by Brian Hall <[email protected]>
+/* Submitted by Brian Hall <[email protected]>
* Needed for START_STOP flag */
UNUSUAL_DEV( 0x0c76, 0x0003, 0x0100, 0x0100,
"JMTek",
"USBDrive",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP ),
+UNUSUAL_DEV( 0x0c76, 0x0005, 0x0100, 0x0100,
+ "JMTek",
+ "USBDrive",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ US_FL_START_STOP ),

/* Reported by Dan Pilone <[email protected]>
* The device needs the flags only.
- * Also reported by Brian Hall <[email protected]>, again for flags.
+ * Also reported by Brian Hall <[email protected]>, again for flags.
* I also suspect this device may have a broken serial number.
*/
UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x9999,

2002-09-27 19:41:47

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.5 -> 1.611.1.6
# drivers/usb/storage/unusual_devs.h 1.19 -> 1.20
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.6
# [PATCH] USB 2.0 HDD Walker / ST-HW-818SLIM usb-storage fix
#
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h Fri Sep 27 12:30:14 2002
+++ b/drivers/usb/storage/unusual_devs.h Fri Sep 27 12:30:14 2002
@@ -331,8 +331,10 @@
* Like the SIIG unit above, this unit needs an INQUIRY to ask for exactly
* 36 bytes of data. No more, no less. That is the only reason this entry
* is needed.
- */
-UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
+ *
+ * ST818 slim drives (rev 0.02) don't need special care.
+*/
+UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0x0001,
"EagleTec",
"External Hard Disk",
US_SC_SCSI, US_PR_BULK, NULL,

2002-09-27 19:41:48

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.7 -> 1.611.1.8
# drivers/base/core.c 1.39 -> 1.40
# drivers/base/Makefile 1.13 -> 1.14
# drivers/base/base.h 1.12 -> 1.13
# include/linux/device.h 1.38 -> 1.39
# (new) -> 1.1 drivers/base/hotplug.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/27 [email protected] 1.611.1.8
# add hotplug support to the driver core for devices, if their bus type supports it.
# --------------------------------------------
#
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile Fri Sep 27 12:30:08 2002
+++ b/drivers/base/Makefile Fri Sep 27 12:30:08 2002
@@ -6,6 +6,8 @@

obj-y += fs/

+obj-$(CONFIG_HOTPLUG) += hotplug.o
+
export-objs := core.o power.o sys.o bus.o driver.o \
class.o intf.o platform.o cpu.o

diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h Fri Sep 27 12:30:08 2002
+++ b/drivers/base/base.h Fri Sep 27 12:30:08 2002
@@ -50,3 +50,13 @@

extern int driver_attach(struct device_driver * drv);
extern void driver_detach(struct device_driver * drv);
+
+#ifdef CONFIG_HOTPLUG
+extern int dev_hotplug(struct device *dev, const char *action);
+#else
+static inline int dev_hotplug(struct device *dev, const char *action)
+{
+ return 0;
+}
+#endif
+
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c Fri Sep 27 12:30:08 2002
+++ b/drivers/base/core.c Fri Sep 27 12:30:08 2002
@@ -200,6 +200,9 @@
if (platform_notify)
platform_notify(dev);

+ /* notify userspace of device entry */
+ dev_hotplug(dev, "add");
+
register_done:
if (error) {
spin_lock(&device_lock);
@@ -254,6 +257,9 @@
*/
if (platform_notify_remove)
platform_notify_remove(dev);
+
+ /* notify userspace that this device is about to disappear */
+ dev_hotplug (dev, "remove");

device_detach(dev);
bus_remove_device(dev);
diff -Nru a/drivers/base/hotplug.c b/drivers/base/hotplug.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/base/hotplug.c Fri Sep 27 12:30:08 2002
@@ -0,0 +1,103 @@
+/*
+ * drivers/base/hotplug.c - hotplug call code
+ *
+ * Copyright (c) 2000-2001 David Brownell
+ * Copyright (c) 2002 Greg Kroah-Hartman
+ * Copyright (c) 2002 IBM Corp.
+ *
+ * Based off of drivers/usb/core/usb.c:call_agent(), which was
+ * written by David Brownell.
+ *
+ */
+
+#define DEBUG 0
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/kmod.h>
+#include <linux/interrupt.h>
+#include "base.h"
+
+/*
+ * hotplugging invokes what /proc/sys/kernel/hotplug says (normally
+ * /sbin/hotplug) when devices get added or removed.
+ *
+ * This invokes a user mode policy agent, typically helping to load driver
+ * or other modules, configure the device, and more. Drivers can provide
+ * a MODULE_DEVICE_TABLE to help with module loading subtasks.
+ */
+#define BUFFER_SIZE 1024 /* should be enough memory for the env */
+#define NUM_ENVP 32 /* number of env pointers */
+int dev_hotplug (struct device *dev, const char *action)
+{
+ char *argv [3], **envp, *buffer, *scratch;
+ int retval;
+ int i = 0;
+
+ pr_debug ("%s\n", __FUNCTION__);
+ if (!dev)
+ return -ENODEV;
+
+ if (!dev->bus || !dev->bus->hotplug)
+ return -ENODEV;
+
+ if (!hotplug_path [0])
+ return -ENODEV;
+
+ if (in_interrupt ()) {
+ pr_debug ("%s - in_interrupt, not allowed!", __FUNCTION__);
+ return -EIO;
+ }
+
+ if (!current->fs->root) {
+ /* don't try to do anything unless we have a root partition */
+ pr_debug ("%s - %s -- no FS yet\n", __FUNCTION__, action);
+ return -EIO;
+ }
+
+ envp = (char **) kmalloc (NUM_ENVP * sizeof (char *), GFP_KERNEL);
+ if (!envp)
+ return -ENOMEM;
+
+ buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
+ if (!buffer) {
+ kfree (envp);
+ return -ENOMEM;
+ }
+
+ /* only one standardized param to hotplug command: the bus name */
+ argv [0] = hotplug_path;
+ argv [1] = dev->bus->name;
+ argv [2] = 0;
+
+ /* minimal command environment */
+ envp [i++] = "HOME=/";
+ envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+
+ scratch = buffer;
+
+ /* action: add, remove */
+ envp [i++] = scratch;
+ scratch += sprintf (scratch, "ACTION=%s", action) + 1;
+
+ /* have the bus specific function set up the rest of the environment */
+ retval = dev->bus->hotplug (dev, &envp[i], NUM_ENVP - i,
+ scratch, BUFFER_SIZE - (scratch - buffer));
+ if (retval) {
+ pr_debug ("%s - hotplug() returned %d\n", __FUNCTION__, retval);
+ goto exit;
+ }
+
+ pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv [0], argv[1],
+ action, envp[0], envp[1], envp[2]);
+ retval = call_usermodehelper (argv [0], argv, envp);
+ if (retval)
+ pr_debug ("%s - call_usermodehelper returned %d\n",
+ __FUNCTION__, retval);
+
+exit:
+ kfree (buffer);
+ kfree (envp);
+ return retval;
+}
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h Fri Sep 27 12:30:08 2002
+++ b/include/linux/device.h Fri Sep 27 12:30:08 2002
@@ -67,6 +67,8 @@

int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id);
+ int (*hotplug) (struct device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
};


2002-09-27 19:41:47

by Greg KH

[permalink] [raw]
Subject: Re: [BK PATCH] More USB changes for 2.5.38

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.611.1.6 -> 1.611.1.7
# drivers/usb/storage/transport.c 1.35 -> 1.36
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26 [email protected] 1.611.1.7
# [PATCH] USB storage: Another (!) patch for the abort handler
#
# This is a simple, obvious patch for the abort handler. I don't know how
# we missed it before.
#
# Fix abort problem: us->srb was used after it was erased.
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c Fri Sep 27 12:30:11 2002
+++ b/drivers/usb/storage/transport.c Fri Sep 27 12:30:11 2002
@@ -859,6 +859,7 @@
* This must be called with scsi_lock(us->srb->host) held */
void usb_stor_abort_transport(struct us_data *us)
{
+ struct Scsi_Host *host;
int state = atomic_read(&us->sm_state);

US_DEBUGP("usb_stor_abort_transport called\n");
@@ -870,7 +871,8 @@

/* set state to abort and release the lock */
atomic_set(&us->sm_state, US_STATE_ABORTING);
- scsi_unlock(us->srb->host);
+ host = us->srb->host;
+ scsi_unlock(host);

/* If the state machine is blocked waiting for an URB or an IRQ,
* let's wake it up */
@@ -892,8 +894,8 @@
/* Wait for the aborted command to finish */
wait_for_completion(&us->notify);

- /* Reacquire the lock */
- scsi_lock(us->srb->host);
+ /* Reacquire the lock: note that us->srb is now NULL */
+ scsi_lock(host);
}

/*