More USB changes for 2.5.38
Subsystems (6)
PATCH 1/1 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(-)
------
# 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. # --------------------------------------------
#
drivers/net/irda/irda-usb.c +35 -28
@@ -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); } }
include/net/irda/irda-usb.h +1 -1
@@ -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 */
# 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. # --------------------------------------------
#
drivers/usb/usb-skeleton.c +22 -15
@@ -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);
# 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 # --------------------------------------------
#
drivers/net/irda/irda-usb.c +1 -1
@@ -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 ;
# 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,
# 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);
# 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
#
# --------------------------------------------
#
drivers/usb/storage/unusual_devs.h +4 -2
@@ -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,
# 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);
}
/*
# 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
drivers/base/base.h +10 -0
@@ -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 +
drivers/base/core.c +6 -0
@@ -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);
drivers/base/hotplug.c new file +103 -0
103 lines not on this page · raw message
include/linux/device.h +2 -0
@@ -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); };
# 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,
};
/*
# 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
drivers/pci/pci-driver.c +4 -2
@@ -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 )
drivers/pci/pci.h new file +5 -0
@@ -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); +