Commit 54fa1ff0 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/linus-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents eab53a50 b97fe142
......@@ -2750,6 +2750,10 @@ E: wsalamon@tislabs.com
E: wsalamon@nai.com
D: portions of the Linux Security Module (LSM) framework and security modules
N: Robert Sanders
E: gt8134b@prism.gatech.edu
D: Dosemu
N: Duncan Sands
E: duncan.sands@wanadoo.fr
W: http://topo.math.u-psud.fr/~sands
......@@ -2758,10 +2762,6 @@ S: 69 rue Dunois
S: 75013 Paris
S: France
N: Robert Sanders
E: gt8134b@prism.gatech.edu
D: Dosemu
N: Hannu Savolainen
E: hannu@opensound.com
D: Maintainer of the sound drivers until 2.1.x days.
......
This diff is collapsed.
......@@ -598,7 +598,7 @@ static struct kobj_type ktype_edd = {
.default_attrs = def_attrs,
};
static decl_subsys(edd,&ktype_edd);
static decl_subsys(edd,&ktype_edd,NULL);
/**
......
......@@ -676,7 +676,7 @@ acpi_bus_init (void)
return_VALUE(-ENODEV);
}
decl_subsys(acpi,NULL);
decl_subsys(acpi,NULL,NULL);
static int __init acpi_init (void)
{
......
......@@ -18,13 +18,8 @@ extern void interface_remove_dev(struct device *);
#ifdef CONFIG_HOTPLUG
extern int dev_hotplug(struct device *dev, const char *action);
extern int class_hotplug(struct device *dev, const char *action);
#else
static inline int dev_hotplug(struct device *dev, const char *action)
{
return 0;
}
static inline int class_hotplug(struct device *dev, const char *action)
{
return 0;
......
......@@ -132,7 +132,7 @@ static struct kobj_type ktype_bus = {
};
decl_subsys(bus,&ktype_bus);
decl_subsys(bus,&ktype_bus,NULL);
/**
* bus_for_each_dev - device iterator.
......
......@@ -49,7 +49,9 @@ static struct kobj_type ktype_devclass = {
.sysfs_ops = &class_sysfs_ops,
};
static decl_subsys(class,&ktype_devclass);
/* Classes can't use the kobject hotplug logic, as
* they do not add new kobjects to the system */
static decl_subsys(class,&ktype_devclass,NULL);
static int devclass_dev_link(struct device_class * cls, struct device * dev)
......
......@@ -23,13 +23,12 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
DECLARE_MUTEX(device_sem);
#define to_dev(obj) container_of(obj,struct device,kobj)
/*
* sysfs bindings for devices.
*/
#define to_dev(obj) container_of(obj,struct device,kobj)
#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
extern struct attribute * dev_default_attrs[];
......@@ -86,11 +85,55 @@ static struct kobj_type ktype_device = {
.default_attrs = dev_default_attrs,
};
static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
if (ktype == &ktype_device) {
struct device *dev = to_dev(kobj);
if (dev->bus)
return 1;
}
return 0;
}
static char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
return dev->bus->name;
}
static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct device *dev = to_dev(kobj);
int retval = 0;
if (dev->bus->hotplug) {
/* have the bus specific function add its stuff */
retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
if (retval) {
pr_debug ("%s - hotplug() returned %d\n",
__FUNCTION__, retval);
}
}
return retval;
}
static struct kset_hotplug_ops device_hotplug_ops = {
.filter = dev_hotplug_filter,
.name = dev_hotplug_name,
.hotplug = dev_hotplug,
};
/**
* device_subsys - structure to be registered with kobject core.
*/
decl_subsys(devices,&ktype_device);
decl_subsys(devices, &ktype_device, &device_hotplug_ops);
/**
......@@ -192,9 +235,6 @@ int device_add(struct device *dev)
if (platform_notify)
platform_notify(dev);
/* notify userspace of device entry */
dev_hotplug(dev, "add");
devclass_add_device(dev);
register_done:
if (error && parent)
......@@ -278,9 +318,6 @@ void device_del(struct device * dev)
if (platform_notify_remove)
platform_notify_remove(dev);
/* notify userspace that this device is about to disappear */
dev_hotplug (dev, "remove");
bus_remove_device(dev);
kobject_del(&dev->kobj);
......
......@@ -6,7 +6,7 @@
#include <linux/module.h>
#include <linux/init.h>
static decl_subsys(firmware,NULL);
static decl_subsys(firmware,NULL,NULL);
int firmware_register(struct subsystem * s)
{
......
......@@ -2,8 +2,8 @@
* drivers/base/hotplug.c - hotplug call code
*
* Copyright (c) 2000-2001 David Brownell
* Copyright (c) 2002 Greg Kroah-Hartman
* Copyright (c) 2002 IBM Corp.
* Copyright (c) 2002-2003 Greg Kroah-Hartman
* Copyright (c) 2002-2003 IBM Corp.
*
* Based off of drivers/usb/core/usb.c:call_agent(), which was
* written by David Brownell.
......@@ -53,17 +53,6 @@ static int do_hotplug (struct device *dev, char *argv1, const char *action,
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;
......@@ -128,23 +117,6 @@ static int do_hotplug (struct device *dev, char *argv1, const char *action,
return retval;
}
/*
* dev_hotplug - called when any device is added or removed from a bus
*/
int dev_hotplug (struct device *dev, const char *action)
{
pr_debug ("%s\n", __FUNCTION__);
if (!dev)
return -ENODEV;
if (!dev->bus)
return -ENODEV;
return do_hotplug (dev, dev->bus->name, action, dev->bus->hotplug);
}
/*
* class_hotplug - called when a class is added or removed from a device
*/
......
......@@ -525,9 +525,21 @@ static struct kobj_type ktype_block = {
.default_attrs = default_attrs,
};
extern struct kobj_type ktype_part;
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype == &ktype_block) || (ktype == &ktype_part));
}
static struct kset_hotplug_ops block_hotplug_ops = {
.filter = block_hotplug_filter,
};
/* declare block_subsys. */
static decl_subsys(block,&ktype_block);
static decl_subsys(block, &ktype_block, &block_hotplug_ops);
struct gendisk *alloc_disk(int minors)
......
......@@ -100,7 +100,7 @@ static struct kobj_type hotplug_slot_ktype = {
.sysfs_ops = &hotplug_slot_sysfs_ops
};
static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL);
/* these strings match up with the values in pci_bus_speed */
......
......@@ -99,6 +99,8 @@
* for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
* 2001-06-16: Bryce Nesbitt <bryce@obviously.com>
* Fix SNDCTL_DSP_STEREO API violation
* 2003-04-08: Oliver Neukum (oliver@neukum.name):
* Setting a configuration is done by usbcore and must not be overridden
*/
/*
......@@ -3790,10 +3792,6 @@ static int usb_audio_probe(struct usb_interface *intf,
*/
i = dev->actconfig - config;
if (usb_set_configuration(dev, config->desc.bConfigurationValue) < 0) {
printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->desc.bConfigurationValue);
return -EIO;
}
ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8);
if (ret < 0) {
printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
......
......@@ -1806,22 +1806,6 @@ static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struc
printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n",
d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
for ( i=0 ; i < d->descriptor.bNumConfigurations ; i++ ) {
if ( d->config+i == c ) goto configfound;
}
printk(KERN_INFO "usb-midi: Config not found.\n");
return -EINVAL;
configfound:
/* this may not be necessary. */
if ( usb_set_configuration( d, c->desc.bConfigurationValue ) < 0 ) {
printk(KERN_INFO "usb-midi: Could not set config.\n");
return -EINVAL;
}
ret = usb_get_descriptor( d, USB_DT_CONFIG, i, buf, USB_DT_CONFIG_SIZE );
if ( ret < 0 ) {
printk(KERN_INFO "usb-midi: Could not get config (error=%d).\n", ret);
......@@ -1916,21 +1900,6 @@ static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct
printk(KERN_INFO "usb-midi: Found MIDISTREAMING on dev %04x:%04x, iface %d\n",
d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
for ( i=0 ; i < d->descriptor.bNumConfigurations ; i++ ) {
if ( d->config+i == c ) goto configfound;
}
printk(KERN_INFO "usb-midi: Config not found.\n");
return -EINVAL;
configfound:
/* this may not be necessary. */
if ( usb_set_configuration( d, c->desc.bConfigurationValue ) < 0 ) {
printk(KERN_INFO "usb-midi: Could not set config.\n");
return -EINVAL;
}
/* From USB Spec v2.0, Section 9.5.
If the class or vendor specific descriptors use the same format
......
......@@ -1175,8 +1175,10 @@ void usb_hub_cleanup(void)
*
* Take a look at proc_resetdevice in devio.c for some sample code to
* do this.
* Use this only from within your probe function, otherwise use
* usb_reset_device() below, which ensure proper locking
*/
int usb_reset_device(struct usb_device *dev)
int usb_physical_reset_device(struct usb_device *dev)
{
struct usb_device *parent = dev->parent;
struct usb_device_descriptor *descriptor;
......@@ -1306,3 +1308,16 @@ int usb_reset_device(struct usb_device *dev)
return 0;
}
int usb_reset_device(struct usb_device *udev)
{
struct device *gdev = &udev->dev;
int r;
down_read(&gdev->bus->subsys.rwsem);
r = usb_physical_reset_device(udev);
up_read(&gdev->bus->subsys.rwsem);
return r;
}
......@@ -930,6 +930,8 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
/* reset more hc/hcd endpoint state */
dev->toggle[0] = 0;
dev->toggle[1] = 0;
dev->halted[0] = 0;
dev->halted[1] = 0;
usb_set_maxpacket(dev);
return 0;
......
......@@ -89,11 +89,6 @@ int usb_device_probe(struct device *dev)
if (!driver->probe)
return error;
if (!try_module_get(driver->owner)) {
dev_err (dev, "Can't get a module reference for %s\n", driver->name);
return error;
}
id = usb_match_id (intf, driver->id_table);
if (id) {
dev_dbg (dev, "%s - got id\n", __FUNCTION__);
......@@ -104,8 +99,6 @@ int usb_device_probe(struct device *dev)
if (!error)
intf->driver = driver;
module_put(driver->owner);
return error;
}
......@@ -117,22 +110,6 @@ int usb_device_remove(struct device *dev)
intf = list_entry(dev,struct usb_interface,dev);
driver = to_usb_driver(dev->driver);
if (!driver) {
dev_err(dev, "%s does not have a valid driver to work with!",
__FUNCTION__);
return -ENODEV;
}
if (!try_module_get(driver->owner)) {
// FIXME this happens even when we just rmmod
// drivers that aren't in active use...
dev_err(dev, "Dieing driver still bound to device.\n");
return -EIO;
}
/* if we sleep here on an umanaged driver
* the holder of the lock guards against
* module unload */
down(&driver->serialize);
if (intf->driver && intf->driver->disconnect)
......@@ -143,7 +120,6 @@ int usb_device_remove(struct device *dev)
usb_driver_release_interface(driver, intf);
up(&driver->serialize);
module_put(driver->owner);
return 0;
}
......@@ -498,9 +474,6 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev)
continue;
intf = to_usb_interface(dev);
if (!intf)
continue;
if (kdev_same(intf->kdev,kdev)) {
return intf;
}
......@@ -566,12 +539,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
return 0;
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 ??");
......@@ -748,8 +716,6 @@ static void usb_release_dev(struct device *dev)
struct usb_device *udev;
udev = to_usb_device(dev);
if (!udev)
return;
if (udev->bus && udev->bus->op && udev->bus->op->deallocate)
udev->bus->op->deallocate(udev);
......
......@@ -62,6 +62,7 @@ static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
{
memset (qtd, 0, sizeof *qtd);
qtd->qtd_dma = dma;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
qtd->hw_next = EHCI_LIST_END;
qtd->hw_alt_next = EHCI_LIST_END;
INIT_LIST_HEAD (&qtd->qtd_list);
......
......@@ -137,7 +137,10 @@ static void qtd_copy_status (
if (QTD_CERR (token))
urb->status = -EPIPE;
else {
dbg ("3strikes");
ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",
urb->dev->devpath,
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out");
urb->status = -EPROTO;
}
/* CERR nonzero + no errors + halt --> stall */
......@@ -213,7 +216,6 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
/* complete() can reenter this HCD */
spin_unlock (&ehci->lock);
usb_hcd_giveback_urb (&ehci->hcd, urb, regs);
spin_lock (&ehci->lock);
}
......@@ -827,7 +829,7 @@ static struct ehci_qh *qh_append_tds (
* HC is allowed to fetch the old dummy (4.10.2).
*/
token = qtd->hw_token;
qtd->hw_token = 0;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
wmb ();
dummy = qh->dummy;
......@@ -879,8 +881,7 @@ submit_async (
if (usb_pipein (urb->pipe) && !usb_pipecontrol (urb->pipe))
epnum |= 0x10;
vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]",
hcd_to_bus (&ehci->hcd)->bus_name,
ehci_vdbg (ehci, "submit_async urb %p len %d ep%d%s qtd %p [qh %p]\n",
urb, urb->transfer_buffer_length,
epnum & 0x0f, (epnum & 0x10) ? "in" : "out",
qtd, dev ? dev->ep [epnum] : (void *)~0);
......@@ -916,7 +917,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
del_timer (&ehci->watchdog);
qh->hw_next = cpu_to_le32 (qh->qh_dma);
// qh->hw_next = cpu_to_le32 (qh->qh_dma);
qh->qh_state = QH_STATE_IDLE;
qh->qh_next.qh = 0;
qh_put (ehci, qh); // refcount from reclaim
......
......@@ -429,6 +429,8 @@ static int hc_reset (struct ohci_hcd *ohci)
ohci->hc_control = readl (&ohci->regs->control);
ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */
writel (ohci->hc_control, &ohci->regs->control);
// flush those pci writes
(void) readl (&ohci->regs->control);
wait_ms (50);
/* HC Reset requires max 10 us delay */
......@@ -450,6 +452,8 @@ static int hc_reset (struct ohci_hcd *ohci)
* this if we write fmInterval after we're OPERATIONAL.
*/
writel (ohci->hc_control, &ohci->regs->control);
// flush those pci writes
(void) readl (&ohci->regs->control);
return 0;
}
......@@ -524,6 +528,8 @@ static int hc_start (struct ohci_hcd *ohci)
writel (tmp, &ohci->regs->roothub.a);
writel (RH_HS_LPSC, &ohci->regs->roothub.status);
writel (0, &ohci->regs->roothub.b);
// flush those pci writes
(void) readl (&ohci->regs->control);
// POTPGT delay is bits 24-31, in 2 ms units.
mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
......@@ -610,6 +616,8 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
writel (ints, &regs->intrstatus);
writel (OHCI_INTR_MIE, &regs->intrenable);
// flush those pci writes
(void) readl (&ohci->regs->control);
}
/*-------------------------------------------------------------------------*/
......
......@@ -446,6 +446,8 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
if (!ohci->sleeping) {
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
// flush those pci writes
(void) readl (&ohci->regs->control);
}
}
......
......@@ -1664,6 +1664,9 @@ static struct usb_driver hid_driver = {
.probe = hid_probe,
.disconnect = hid_disconnect,
.id_table = hid_usb_ids,
.driver = {
.devclass = &input_devclass,
},
};
static int __init hid_init(void)
......
......@@ -91,7 +91,7 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
}
struct usb_device_id kbtab_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), driver_info : 0 },
{ USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 },
{ }
};
......
......@@ -359,6 +359,9 @@ static struct usb_driver usb_kbd_driver = {
.probe = usb_kbd_probe,
.disconnect = usb_kbd_disconnect,
.id_table = usb_kbd_id_table,
.driver = {
.devclass = &input_devclass,
},
};
static int __init usb_kbd_init(void)
......
......@@ -242,6 +242,9 @@ static struct usb_driver usb_mouse_driver = {
.probe = usb_mouse_probe,
.disconnect = usb_mouse_disconnect,
.id_table = usb_mouse_id_table,
.driver = {
.devclass = &input_devclass,
},
};
static int __init usb_mouse_init(void)
......
......@@ -94,7 +94,7 @@ config USB_LCD
a module, say M here and read <file:Documentation/modules.txt>.
config USB_SPEEDTOUCH
tristate "Alcatel Speedtouch ADSL USB Modem"
tristate "Alcatel Speedtouch USB support"
depends on USB && ATM
help
Say Y here if you have an Alcatel SpeedTouch USB or SpeedTouch 330
......
......@@ -933,15 +933,24 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
if (vcc->qos.aal != ATM_AAL5)
return -EINVAL;
if (!instance->firmware_loaded) {
dbg ("firmware not loaded!");
return -EAGAIN;
}
MOD_INC_USE_COUNT;
down (&instance->serialize); /* vs self, udsl_atm_close */
if (udsl_find_vcc (instance, vpi, vci)) {
up (&instance->serialize);
MOD_DEC_USE_COUNT;
return -EADDRINUSE;
}
if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
up (&instance->serialize);
MOD_DEC_USE_COUNT;
return -ENOMEM;
}
......@@ -967,9 +976,6 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
dbg ("Allocated new SARLib vcc 0x%p with vpi %d vci %d", new, vpi, vci);
MOD_INC_USE_COUNT;
if (instance->firmware_loaded)
udsl_fire_receivers (instance);
dbg ("udsl_atm_open successful");
......@@ -1034,6 +1040,24 @@ static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
** USB **
**********/
static int udsl_set_alternate (struct udsl_instance_data *instance)
{
down (&instance->serialize); /* vs self */
if (!instance->firmware_loaded) {
int ret;
if ((ret = usb_set_interface (instance->usb_dev, 1, 1)) < 0) {
dbg ("usb_set_interface returned %d!", ret);
up (&instance->serialize);
return ret;
}
instance->firmware_loaded = 1;
}
up (&instance->serialize);
udsl_fire_receivers (instance);
return 0;
}
static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
{
struct udsl_instance_data *instance = usb_get_intfdata (intf);
......@@ -1048,14 +1072,7 @@ static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *
switch (code) {
case UDSL_IOCTL_START:
instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
down (&instance->serialize); /* vs self */
if (!instance->firmware_loaded) {
usb_set_interface (instance->usb_dev, 1, 1);
instance->firmware_loaded = 1;
}
up (&instance->serialize);
udsl_fire_receivers (instance);
return 0;
return udsl_set_alternate (instance);
case UDSL_IOCTL_STOP:
instance->atm_dev->signal = ATM_PHY_SIG_LOST;
return 0;
......
......@@ -493,54 +493,42 @@ static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer
return rlen;
}
void parport_uss720_inc_use_count(void)
{
MOD_INC_USE_COUNT;
}
void parport_uss720_dec_use_count(void)
{
MOD_DEC_USE_COUNT;
}
/* --------------------------------------------------------------------- */
static struct parport_operations parport_uss720_ops =
{
parport_uss720_write_data,
parport_uss720_read_data,
parport_uss720_write_control,
parport_uss720_read_control,
parport_uss720_frob_control,
.owner = THIS_MODULE,
.write_data = parport_uss720_write_data,
.read_data = parport_uss720_read_data,
parport_uss720_read_status,
.write_control = parport_uss720_write_control,
.read_control = parport_uss720_read_control,
.frob_control = parport_uss720_frob_control,
parport_uss720_enable_irq,
parport_uss720_disable_irq,
.read_status = parport_uss720_read_status,
parport_uss720_data_forward,
parport_uss720_data_reverse,
.enable_irq = parport_uss720_enable_irq,
.disable_irq = parport_uss720_disable_irq,
parport_uss720_init_state,
parport_uss720_save_state,
parport_uss720_restore_state,
.data_forward = parport_uss720_data_forward,
.data_reverse = parport_uss720_data_reverse,
parport_uss720_inc_use_count,
parport_uss720_dec_use_count,
.init_state = parport_uss720_init_state,
.save_state = parport_uss720_save_state,
.restore_state = parport_uss720_restore_state,
parport_uss720_epp_write_data,
parport_uss720_epp_read_data,
parport_uss720_epp_write_addr,
parport_uss720_epp_read_addr,
.epp_write_data = parport_uss720_epp_write_data,
.epp_read_data = parport_uss720_epp_read_data,
.epp_write_addr = parport_uss720_epp_write_addr,
.epp_read_addr = parport_uss720_epp_read_addr,
parport_uss720_ecp_write_data,
parport_uss720_ecp_read_data,
parport_uss720_ecp_write_addr,
.ecp_write_data = parport_uss720_ecp_write_data,
.ecp_read_data = parport_uss720_ecp_read_data,
.ecp_write_addr = parport_uss720_ecp_write_addr,
parport_uss720_write_compat,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
.compat_write_data = parport_uss720_write_compat,
.nibble_read_data = parport_ieee1284_read_nibble,
.byte_read_data = parport_ieee1284_read_byte,
};
/* --------------------------------------------------------------------- */
......@@ -607,7 +595,6 @@ static int uss720_probe(struct usb_interface *intf,
parport_proc_register(pp);
parport_announce_port(pp);
MOD_INC_USE_COUNT;
usb_set_intfdata (intf, pp);
return 0;
......@@ -635,7 +622,6 @@ static void uss720_disconnect(struct usb_interface *intf)
parport_proc_unregister(pp);
parport_unregister_port(pp);
kfree(priv);
MOD_DEC_USE_COUNT;
}
}
......@@ -652,6 +638,7 @@ MODULE_DEVICE_TABLE (usb, uss720_table);
static struct usb_driver uss720_driver = {
.owner = THIS_MODULE,
.name = "uss720",
.probe = uss720_probe,
.disconnect = uss720_disconnect,
......
......@@ -45,7 +45,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.5.9 (2002/12/31)"
#define DRIVER_VERSION "v0.5.10 (2003/04/01)"
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
......@@ -121,7 +121,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
char *buffer;
DECLARE_WAITQUEUE(wait, current);
buffer = kmalloc(size, GFP_KERNEL);
buffer = kmalloc(size, GFP_DMA);
if (!buffer) {
warn("%s: looks like we're out of memory", __FUNCTION__);
return -ENOMEM;
......@@ -170,7 +170,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
char *buffer;
DECLARE_WAITQUEUE(wait, current);
buffer = kmalloc(size, GFP_KERNEL);
buffer = kmalloc(size, GFP_DMA);
if (!buffer) {
warn("%s: looks like we're out of memory", __FUNCTION__);
return -ENOMEM;
......@@ -218,7 +218,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
char *tmp;
DECLARE_WAITQUEUE(wait, current);
tmp = kmalloc(1, GFP_KERNEL);
tmp = kmalloc(1, GFP_DMA);
if (!tmp) {
warn("%s: looks like we're out of memory", __FUNCTION__);
return -ENOMEM;
......@@ -233,7 +233,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
pegasus->dr.bRequest = PEGASUS_REQ_SET_REG;
pegasus->dr.wValue = cpu_to_le16p(&data);
pegasus->dr.wValue = cpu_to_le16(data);
pegasus->dr.wIndex = cpu_to_le16p(&indx);
pegasus->dr.wLength = cpu_to_le16(1);
pegasus->ctrl_urb->transfer_buffer_length = 1;
......@@ -711,11 +711,11 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
pegasus->stats.tx_aborted_errors++;
if (d[0] & LATE_COL)
pegasus->stats.tx_window_errors++;
if (d[0] & (NO_CARRIER | LOSS_CARRIER)) {
if (d[5] & LINK_STATUS) {
netif_carrier_on(net);
} else {
pegasus->stats.tx_carrier_errors++;
netif_carrier_off(net);
} else {
netif_carrier_on(net);
}
}
......@@ -1171,10 +1171,6 @@ static int pegasus_probe(struct usb_interface *intf,
pegasus_t *pegasus;
int dev_index = id - pegasus_ids;
if (usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue)) {
err("usb_set_configuration() failed");
return -ENODEV;
}
if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) {
err("out of memory allocating device structure");
return -ENOMEM;
......
......@@ -52,6 +52,8 @@
#define LOSS_CARRIER 0x08
#define JABBER_TIMEOUT 0x04
#define LINK_STATUS 0x01
#define PEGASUS_REQT_READ 0xc0
#define PEGASUS_REQT_WRITE 0x40
#define PEGASUS_REQ_GET_REGS 0xf0
......
......@@ -791,10 +791,6 @@ static int rtl8150_probe(struct usb_interface *intf,
rtl8150_t *dev;
struct net_device *netdev;
if (usb_set_configuration(udev, udev->config[0].desc.bConfigurationValue)) {
err("usb_set_configuration() failed");
return -EIO;
}
dev = kmalloc(sizeof(rtl8150_t), GFP_KERNEL);
if (!dev) {
err("Out of memory");
......
This diff is collapsed.
......@@ -25,6 +25,10 @@
*
* Version history:
*
* 2003_04_03 al borchers
* - fixed a bug (that shows up with dosemu) where the tty struct is
* used in a callback after it has been freed
*
* 2.3 2002_03_08 greg kroah-hartman
* - fixed bug when multiple devices were attached at the same time.
*
......@@ -918,7 +922,7 @@ static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs)
tty = edge_port->port->tty;
if (tty) {
if (tty && edge_port->open) {
/* let the tty driver wakeup if it has a special write_wakeup function */
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
(tty->ldisc.write_wakeup)(tty);
......@@ -975,7 +979,7 @@ static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs)
tty = edge_port->port->tty;
/* tell the tty driver that something has changed */
if (tty)
if (tty && edge_port->open)
wake_up_interruptible(&tty->write_wait);
/* we have completed the command */
......
......@@ -131,6 +131,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) },
{ USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) },
{ USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) },
{ USB_DEVICE(ASUS_VENDOR_ID, ASUS_A600_PRODUCT_ID) },
{ } /* Terminating entry */
};
......
......@@ -77,6 +77,9 @@
#define NEC_VENDOR_ID 0x0409
#define NEC_PRODUCT_ID 0x00d5
#define ASUS_VENDOR_ID 0x0b05
#define ASUS_A600_PRODUCT_ID 0x4201
/*
* Since we can't queue our bulk write urbs (don't know why - it just
* doesn't work), we can send down only one write urb at a time. The simplistic
......
......@@ -411,19 +411,19 @@ static const struct keyspan_device_details usa49w_device_details = {
};
static const struct keyspan_device_details usa49wlc_device_details = {
product_id: keyspan_usa49wlc_product_id,
msg_format: msg_usa49,
num_ports: 4,
indat_endp_flip: 0,
outdat_endp_flip: 0,
indat_endpoints: {0x81, 0x82, 0x83, 0x84},
outdat_endpoints: {0x01, 0x02, 0x03, 0x04},
inack_endpoints: {-1, -1, -1, -1},
outcont_endpoints: {-1, -1, -1, -1},
instat_endpoint: 0x87,
glocont_endpoint: 0x07,
calculate_baud_rate: keyspan_usa19w_calc_baud,
baudclk: KEYSPAN_USA19W_BAUDCLK,
.product_id = keyspan_usa49wlc_product_id,
.msg_format = msg_usa49,
.num_ports = 4,
.indat_endp_flip = 0,
.outdat_endp_flip = 0,
.indat_endpoints = {0x81, 0x82, 0x83, 0x84},
.outdat_endpoints = {0x01, 0x02, 0x03, 0x04},
.inack_endpoints = {-1, -1, -1, -1},
.outcont_endpoints = {-1, -1, -1, -1},
.instat_endpoint = 0x87,
.glocont_endpoint = 0x07,
.calculate_baud_rate = keyspan_usa19w_calc_baud,
.baudclk = KEYSPAN_USA19W_BAUDCLK,
};
static const struct keyspan_device_details *keyspan_devices[] = {
......
......@@ -531,7 +531,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
dbg("%s - port %d", __FUNCTION__, port->number);
/* if disconnect beat us to the punch here, there's nothing to do */
if (tty->driver_data) {
if (tty && tty->driver_data) {
__serial_close(port, filp);
}
}
......@@ -830,6 +830,7 @@ static void destroy_serial (struct kobject *kobj)
while (port->open_count > 0) {
__serial_close(port, NULL);
}
port->tty = NULL;
}
}
......
......@@ -141,13 +141,19 @@ static int usb_storage_release(struct Scsi_Host *psh)
static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
{
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int state = atomic_read(&us->sm_state);
US_DEBUGP("queuecommand() called\n");
srb->host_scribble = (unsigned char *)us;
/* enqueue the command */
BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE);
BUG_ON(us->srb != NULL);
if (state != US_STATE_IDLE || us->srb != NULL) {
printk(KERN_ERR USB_STORAGE "Error in %s: "
"state = %d, us->srb = %p\n",
__FUNCTION__, state, us->srb);
return SCSI_MLQUEUE_HOST_BUSY;
}
srb->scsi_done = done;
us->srb = srb;
......@@ -175,8 +181,7 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb )
return FAILED;
}
usb_stor_abort_transport(us);
return SUCCESS;
return usb_stor_abort_transport(us);
}
/* This invokes the transport reset mechanism to reset the state of the
......@@ -185,10 +190,15 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb )
static int usb_storage_device_reset( Scsi_Cmnd *srb )
{
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int state = atomic_read(&us->sm_state);
int result;
US_DEBUGP("device_reset() called\n" );
BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE);
if (state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state);
return FAILED;
}
/* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RESETTING);
......@@ -260,6 +270,7 @@ static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
struct us_data *us;
char *pos = buffer;
struct Scsi_Host *hostptr;
unsigned long f;
/* if someone is sending us data, just throw it away */
if (inout)
......@@ -274,6 +285,7 @@ static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
/* if we couldn't find it, we return an error */
if (!us) {
scsi_host_put(hostptr);
return -ESRCH;
}
......@@ -289,6 +301,24 @@ static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
SPRINTF(" Protocol: %s\n", us->protocol_name);
SPRINTF(" Transport: %s\n", us->transport_name);
/* show the device flags */
if (pos < buffer + length) {
pos += sprintf(pos, " Quirks:");
f = us->flags;
#define DO_FLAG(a) if (f & US_FL_##a) pos += sprintf(pos, " " #a)
DO_FLAG(SINGLE_LUN);
DO_FLAG(MODE_XLATE);
DO_FLAG(START_STOP);
DO_FLAG(IGNORE_SER);
DO_FLAG(SCM_MULT_TARG);
DO_FLAG(FIX_INQUIRY);
DO_FLAG(FIX_CAPACITY);
#undef DO_FLAG
*(pos++) = '\n';
}
/* release the reference count on this host */
scsi_host_put(hostptr);
......
......@@ -297,10 +297,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
/* stalled */
case -EPIPE:
/* for control endpoints, a stall indicates a protocol error */
/* for control endpoints, (used by CB[I]) a stall indicates
* a failed command */
if (usb_pipecontrol(pipe)) {
US_DEBUGP("-- stall on control pipe\n");
return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED;
}
/* for other sorts of endpoint, clear the stall */
......@@ -691,7 +692,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
/* Abort the currently running scsi command or device reset.
* This must be called with scsi_lock(us->srb->host) held */
void usb_stor_abort_transport(struct us_data *us)
int usb_stor_abort_transport(struct us_data *us)
{
struct Scsi_Host *host;
int state = atomic_read(&us->sm_state);
......@@ -701,7 +702,11 @@ void usb_stor_abort_transport(struct us_data *us)
/* Normally the current state is RUNNING. If the control thread
* hasn't even started processing this command, the state will be
* IDLE. Anything else is a bug. */
BUG_ON((state != US_STATE_RUNNING && state != US_STATE_IDLE));
if (state != US_STATE_RUNNING && state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state);
return FAILED;
}
/* set state to abort and release the lock */
atomic_set(&us->sm_state, US_STATE_ABORTING);
......@@ -730,6 +735,7 @@ void usb_stor_abort_transport(struct us_data *us)
/* Reacquire the lock: note that us->srb is now NULL */
scsi_lock(host);
return SUCCESS;
}
/*
......@@ -750,8 +756,14 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
/* check the return code for the command */
US_DEBUGP("Call to usb_stor_ctrl_transfer() returned %d\n", result);
if (result != USB_STOR_XFER_GOOD) {
/* if we stalled the command, it means command failed */
if (result == USB_STOR_XFER_STALLED) {
return USB_STOR_TRANSPORT_FAILED;
}
/* Uh oh... serious problem here */
if (result != USB_STOR_XFER_GOOD) {
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -834,8 +846,14 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
/* check the return code for the command */
US_DEBUGP("Call to usb_stor_ctrl_transfer() returned %d\n", result);
if (result != USB_STOR_XFER_GOOD) {
/* if we stalled the command, it means command failed */
if (result == USB_STOR_XFER_STALLED) {
return USB_STOR_TRANSPORT_FAILED;
}
/* Uh oh... serious problem here */
if (result != USB_STOR_XFER_GOOD) {
return USB_STOR_TRANSPORT_ERROR;
}
......
......@@ -154,7 +154,7 @@ extern int usb_stor_Bulk_max_lun(struct us_data*);
extern int usb_stor_Bulk_reset(struct us_data*);
extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*);
extern void usb_stor_abort_transport(struct us_data*);
extern int usb_stor_abort_transport(struct us_data*);
extern int usb_stor_bulk_msg(struct us_data *us, void *data,
unsigned int pipe, unsigned int len, unsigned int *act_len);
......
......@@ -286,6 +286,19 @@ UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
"USB Hard Disk",
US_SC_RBC, US_PR_CB, NULL, 0 ),
/* This Pentax still camera is not conformant
* to the USB storage specification: -
* - It does not like the INQUIRY command. So we must handle this command
* of the SCSI layer ourselves.
* Tested on Rev. 10.00 (0x1000)
* Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
*/
UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
"ASAHI PENTAX",
"PENTAX OPTIO 430",
US_SC_8070, US_PR_CBI, NULL,
US_FL_FIX_INQUIRY ),
#ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,
"In-System",
......
This diff is collapsed.
......@@ -61,7 +61,7 @@ static struct file_system_type **find_filesystem(const char *name)
/* define fs_subsys */
static decl_subsys(fs, NULL);
static decl_subsys(fs, NULL, NULL);
static int register_fs_subsys(struct file_system_type * fs)
{
......
......@@ -248,7 +248,7 @@ static struct attribute * default_attrs[] = {
extern struct subsystem block_subsys;
static struct kobj_type ktype_part = {
struct kobj_type ktype_part = {
.default_attrs = default_attrs,
.sysfs_ops = &part_sysfs_ops,
};
......
......@@ -57,12 +57,24 @@ struct kobj_type {
* of object; multiple ksets can belong to one subsystem. All
* ksets of a subsystem share the subsystem's lock.
*
* Each kset can support hotplugging; if it does, it will be given
* the opportunity to filter out specific kobjects from being
* reported, as well as to add its own "data" elements to the
* environment being passed to the hotplug helper.
*/
struct kset_hotplug_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
char *(*name)(struct kset *kset, struct kobject *kobj);
int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size);
};
struct kset {
struct subsystem * subsys;
struct kobj_type * ktype;
struct list_head list;
struct kobject kobj;
struct kset_hotplug_ops * hotplug_ops;
};
......@@ -86,6 +98,13 @@ static inline void kset_put(struct kset * k)
kobject_put(&k->kobj);
}
static inline struct kobj_type * get_ktype(struct kobject * k)
{
if (k->kset && k->kset->ktype)
return k->kset->ktype;
else
return k->ktype;
}
extern struct kobject * kset_find_obj(struct kset *, const char *);
......@@ -95,11 +114,12 @@ struct subsystem {
struct rw_semaphore rwsem;
};
#define decl_subsys(_name,_type) \
#define decl_subsys(_name,_type,_hotplug_ops) \
struct subsystem _name##_subsys = { \
.kset = { \
.kobj = { .name = __stringify(_name) }, \
.ktype = _type, \
.hotplug_ops =_hotplug_ops, \
} \
}
......
......@@ -11,14 +11,6 @@
static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
static inline struct kobj_type * get_ktype(struct kobject * k)
{
if (k->kset && k->kset->ktype)
return k->kset->ktype;
else
return k->ktype;
}
/**
* populate_dir - populate directory with attributes.
* @kobj: object we're working on.
......@@ -67,6 +59,140 @@ static inline struct kobject * to_kobj(struct list_head * entry)
}
#ifdef CONFIG_HOTPLUG
static int get_kobj_path_length(struct kset *kset, struct kobject *kobj)
{
int length = 1;
struct kobject * parent = kobj;
/* walk up the ancestors until we hit the one pointing to the
* root.
* Add 1 to strlen for leading '/' of each level.
*/
do {
length += strlen (parent->name) + 1;
parent = parent->parent;
} while (parent);
return length;
}
static void fill_kobj_path(struct kset *kset, struct kobject *kobj, char *path, int length)
{
struct kobject * parent;
--length;
for (parent = kobj; parent; parent = parent->parent) {
int cur = strlen (parent->name);
/* back up enough to print this name with '/' */
length -= cur;
strncpy (path + length, parent->name, cur);
*(path + --length) = '/';
}
pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
}
#define BUFFER_SIZE 1024 /* should be enough memory for the env */
#define NUM_ENVP 32 /* number of env pointers */
static void kset_hotplug(const char *action, struct kset *kset,
struct kobject *kobj)
{
char *argv [3];
char **envp;
char *buffer;
char *scratch;
int i = 0;
int retval;
int kobj_path_length;
char *kobj_path;
char *name = NULL;
/* If the kset has a filter operation, call it. If it returns
failure, no hotplug event is required. */
if (kset->hotplug_ops->filter) {
if (!kset->hotplug_ops->filter(kset, kobj))
return;
}
pr_debug ("%s\n", __FUNCTION__);
if (!hotplug_path[0])
return;
envp = (char **)kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
if (!envp)
return;
memset (envp, 0x00, NUM_ENVP * sizeof (char *));
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if (!buffer) {
kfree(envp);
return;
}
if (kset->hotplug_ops->name)
name = kset->hotplug_ops->name(kset, kobj);
if (name == NULL)
name = kset->kobj.name;
argv [0] = hotplug_path;
argv [1] = name;
argv [2] = 0;
/* minimal command environment */
envp [i++] = "HOME=/";
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
scratch = buffer;
envp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action) + 1;
kobj_path_length = get_kobj_path_length (kset, kobj);
kobj_path = kmalloc (kobj_path_length, GFP_KERNEL);
if (!kobj_path) {
kfree (buffer);
kfree (envp);
return;
}
memset (kobj_path, 0x00, kobj_path_length);
fill_kobj_path (kset, kobj, kobj_path, kobj_path_length);
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1;
if (kset->hotplug_ops->hotplug) {
/* have the kset specific function add its stuff */
retval = kset->hotplug_ops->hotplug (kset, kobj,
&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],
envp[0], envp[1], envp[2], envp[3]);
retval = call_usermodehelper (argv[0], argv, envp, 0);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
__FUNCTION__, retval);
exit:
kfree (kobj_path);
kfree (buffer);
return;
}
#else
static void kset_hotplug(const char *action, struct kset *kset,
struct kobject *kobj)
{
return 0;
}
#endif /* CONFIG_HOTPLUG */
/**
* kobject_init - initialize object.
* @kobj: object in question.
......@@ -111,6 +237,7 @@ int kobject_add(struct kobject * kobj)
{
int error = 0;
struct kobject * parent;
struct kobject * top_kobj;
if (!(kobj = kobject_get(kobj)))
return -ENOENT;
......@@ -134,6 +261,19 @@ int kobject_add(struct kobject * kobj)
error = create_dir(kobj);
if (error)
unlink(kobj);
else {
/* If this kobj does not belong to a kset,
try to find a parent that does. */
top_kobj = kobj;
if (!top_kobj->kset && top_kobj->parent) {
do {
top_kobj = top_kobj->parent;
} while (!top_kobj->kset && top_kobj->parent);
}
if (top_kobj->kset && top_kobj->kset->hotplug_ops)
kset_hotplug("add", top_kobj->kset, kobj);
}
return error;
}
......@@ -162,6 +302,20 @@ int kobject_register(struct kobject * kobj)
void kobject_del(struct kobject * kobj)
{
struct kobject * top_kobj;
/* If this kobj does not belong to a kset,
try to find a parent that does. */
top_kobj = kobj;
if (!top_kobj->kset && top_kobj->parent) {
do {
top_kobj = top_kobj->parent;
} while (!top_kobj->kset && top_kobj->parent);
}
if (top_kobj->kset && top_kobj->kset->hotplug_ops)
kset_hotplug("remove", top_kobj->kset, kobj);
sysfs_remove_dir(kobj);
unlink(kobj);
}
......
......@@ -2816,7 +2816,7 @@ extern void ip_auto_config(void);
extern void dv_init(void);
#endif /* CONFIG_NET_DIVERT */
static decl_subsys(net,NULL);
static decl_subsys(net,NULL,NULL);
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment