2002-10-01 00:28:04

by Greg KH

[permalink] [raw]
Subject: [BK PATCH] USB changes for 2.5.39

This series also includes a patch to the driver core that enables
/sbin/hotplug events for all devices in the system (add and remove).

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

thanks,

greg k-h

drivers/base/hotplug.c | 40 +++-
drivers/usb/class/bluetty.c | 4
drivers/usb/class/cdc-acm.c | 3
drivers/usb/core/Makefile | 2
drivers/usb/core/devio.c | 36 ++--
drivers/usb/core/driverfs.c | 177 +++++++++++++++++++++
drivers/usb/core/hcd.c | 24 +-
drivers/usb/core/hub.c | 7
drivers/usb/core/message.c | 327 ++++++++++++++++++++++++++++++++++++++++
drivers/usb/core/urb.c | 31 +--
drivers/usb/core/usb.c | 110 -------------
drivers/usb/core/usb.h | 5
drivers/usb/host/ehci-hcd.c | 2
drivers/usb/host/ehci-q.c | 47 ++---
drivers/usb/host/hc_sl811.c | 3
drivers/usb/host/ohci-hcd.c | 6
drivers/usb/host/ohci-mem.c | 8
drivers/usb/host/ohci-q.c | 5
drivers/usb/serial/cyberjack.c | 14 -
drivers/usb/serial/empeg.c | 6
drivers/usb/serial/ftdi_sio.c | 4
drivers/usb/serial/ipaq.c | 6
drivers/usb/serial/ir-usb.c | 5
drivers/usb/serial/keyspan.c | 6
drivers/usb/serial/kl5kusb105.c | 5
drivers/usb/serial/mct_u232.c | 3
drivers/usb/serial/omninet.c | 5
drivers/usb/serial/pl2303.c | 5
drivers/usb/serial/usbserial.c | 7
drivers/usb/serial/visor.c | 11 -
drivers/usb/serial/visor.h | 1
drivers/usb/serial/whiteheat.c | 5
drivers/usb/storage/transport.c | 2
include/linux/usb.h | 77 +++++++--
include/linux/usbdevice_fs.h | 2
35 files changed, 723 insertions(+), 278 deletions(-)
-----

[email protected], 2002-09-30 16:50:31-07:00, [email protected]
[PATCH] hc_sl811 build and memory leak

It needs s/malloc.h/slab.h/ .
It also forgets to free some memory on an error exit patch.
Patch for 2.5.39 follows.

drivers/usb/host/hc_sl811.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)
------

[email protected], 2002-09-30 16:45:33-07:00, [email protected]
[PATCH] usb_sg_{init,wait,cancel}()

Here are the scatterlist primitives there's been mail about before.
Now the code has passed basic sanity testing, and is ready to merge
into Linus' tree to start getting wider use. Greg, please merge!

To recap, the routines are a utility layer packaging several usb
core facilities to improve system performance. It's synchronous.
The code uses functionality that drivers could use already, but
generally haven't:

- Request queueing. This is a big performance win. It lets
device drivers help the hcds avoid wasted i/o bandwidth, by
eliminating irq and scheduling latencies between requests. It
can make a huge difference at high speed, when the latencies
often exceed the time to handle each i/o request!

- The new usb_map_sg() primitives, leveraging IOMMU hardware
if it's there (better than entry-at-a-time mapping).

- URB_NO_INTERRUPT transfer flag, a hint to hcds that they
can avoid a 'success irq' for this urb. Only the urb for
the last scatterlist entry really needs an IRQ, the others
can be eliminated or delayed. (OHCI uses this today, and
any HCD can safely ignore it.)

The particular functionality in these APIs seemed to meet Matt's
requirements for usb-storage, so I'd hope the 2.5 usb-storage
code will start to use these routines in a while. (And maybe
those two scanner drivers: hpusbscsi, microtek.)

Brief summary of testing: this code seems correct for normal
reads and writes, but the fault paths (including cancelation)
haven't been tested yet. Both EHCI and OHCI seem to be mostly
OK with these more aggressive queued loads, but may need small
updates (like the two I sent yesterday). Unfortunately I have
to report that UHCI and urb queueing will sometimes lock up my
hardware (PIIX4), so while we're lots better than 2.4 this is
still a bit of a trouble spot for now.

I'll be making some testing software available shortly, which
will help track down remaining HCD level problems by giving the
queuing APIs (and some others!) a more strenuous workout than
most drivers will, in their day-to-day usage.

- Dave

drivers/usb/core/message.c | 321 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/usb.h | 52 +++++++
2 files changed, 373 insertions(+)
------

[email protected], 2002-09-30 16:43:41-07:00, [email protected]
[PATCH] USB-storage: problem clearing halts

Greg, attached is a patch designed for diagnostic purposes. Please apply
to the 2.5 tree -- yes, we'll be removing this at some point in the future.

It appears that we have a problem clearing halts. This patch causes a very
clear message to be printed whenever a usb_stor_clear_halt() manages to
work. So far, I haven't seen such a thing happen. And I've seen _lots_ of
STALL conditions.

This problem has likely been around for a while... however, it hasn't been
noticed before because usb-storage was difficult to use because of other
bugs. Heck, the most recent 'bk pull' is the first one for me in _months_
which let me boot all the way into X11.

I'm going to hold my patch queue until this is resolved. On my test setup,
it's easy to see this failing. I've tried with 4 different devices, with
both UHCI and EHCI drivers. I don't want to confuse this problem with
other patches...

'result' in this function always seems to be -32. Which is odd, because
control endpoints shouldn't do that.

I'm open to suggestions as to where to look for this bug, but my instincts
are telling me that this is a core or HCD issue, not a usb-storage issue.

On a positive note, this means that the error-recovery system gets a good
workout.

drivers/usb/storage/transport.c | 2 ++
1 files changed, 2 insertions(+)
------

[email protected], 2002-09-30 16:41:46-07:00, [email protected]
[PATCH] ohci-hcd, paranoia

In a test where some memory corruption happened, I noticed an
oops (null pointer exception in_irq) that's avoidable. Here's
a patch that avoids it ... anyone seeing the err() is likely
to hang some process, but that's better than the alternative.
(Also inlines some used-once routines, saving a bit of space
to make up for the new diagnostic.)

drivers/usb/host/ohci-mem.c | 8 ++++----
drivers/usb/host/ohci-q.c | 5 +++++
2 files changed, 9 insertions(+), 4 deletions(-)
------

[email protected], 2002-09-30 16:41:16-07:00, [email protected]
[PATCH] ehci-hcd, urb queuing

In doing some more extensive testing of the urb queueing behavior,
I noticed that (a) IOC wasn't always being set for each urb, while
for now it needs to be set; (b) a qh patchup wasn't done quite
where it should be. This resolves those two issues, as well
as making it a bit less noisy to unlink lots of urbs at the once.

drivers/usb/host/ehci-hcd.c | 2 -
drivers/usb/host/ehci-q.c | 47 ++++++++++++++++++--------------------------
2 files changed, 21 insertions(+), 28 deletions(-)
------

[email protected], 2002-09-30 16:40:06-07:00, [email protected]
USB: fix typo from previous schedule_task() patch.

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

[email protected], 2002-09-30 16:28:15-07:00, [email protected]
[PATCH] usbcore misc cleanup

This has minor usbcore cleanups:

DOC:
- the changes passing a usb_interface to driver probe() and disconnect()
weren't reflected in their adjacent docs. likewise they still said
it was possible to get a null usb_device_id (no more).

- the (root) hub API restrictions from rmk's ARM patch weren't
flagged

- mention the non-dma-coherent cache issue for usb_buffer_alloc()

- mention disconnect() cleanup issue with usb_{control,bulk}_msg()
[ you can't cancel those urbs from disconnect() ]

CODE
- make driver ioctl() use 'usb_interface' too ... this update
also resolves an old 'one instance per device' bad assumption

- module locking on driver->ioctl() was goofy, kept BKL way too
long and didn't try_inc_mod_count() like the rest of usbcore

- hcd unlink code treated iso inappropriately like interrupt;
only interrupt still wants that automagic mode

- move iso init out of ohci into shared submit_urb logic

- remove interrupt transfer length restriction; hcds that don't
handle packetization (just like bulk :) should be updated,
but device drivers won't care for now.

drivers/usb/core/devio.c | 36 +++++++++++++++++++++---------------
drivers/usb/core/hcd.c | 24 +++++++++++++-----------
drivers/usb/core/hub.c | 5 ++++-
drivers/usb/core/message.c | 6 ++++++
drivers/usb/core/urb.c | 31 ++++++++++++-------------------
drivers/usb/core/usb.c | 4 ++++
drivers/usb/host/ohci-hcd.c | 6 ------
include/linux/usb.h | 25 +++++++++++--------------
include/linux/usbdevice_fs.h | 2 +-
9 files changed, 72 insertions(+), 67 deletions(-)
------

[email protected], 2002-09-30 16:11:26-07:00, [email protected]
USB: allow /sbin/hotplug to be called for the main USB device.

drivers/usb/core/usb.c | 3 +--
1 files changed, 1 insertion(+), 2 deletions(-)
------

[email protected], 2002-09-30 16:09:50-07:00, [email protected]
USB: Fix the name of usb hubs in driverfs.

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

[email protected], 2002-09-30 16:09:11-07:00, [email protected]
USB: add a lot more driverfs files for all usb devices.

drivers/usb/core/Makefile | 2
drivers/usb/core/driverfs.c | 177 ++++++++++++++++++++++++++++++++++++++++++++
drivers/usb/core/usb.c | 103 -------------------------
drivers/usb/core/usb.h | 5 +
4 files changed, 186 insertions(+), 101 deletions(-)
------

[email protected], 2002-09-30 16:07:29-07:00, [email protected]
driver core: added location of device in driverfs tree to /sbin/hotplug call.

/sbin/hotplug is now called when any device is added or removed from the
system.

drivers/base/hotplug.c | 40 +++++++++++++++++++++++++++++++---------
1 files changed, 31 insertions(+), 9 deletions(-)
------

[email protected], 2002-09-30 16:05:03-07:00, [email protected]
USB: added Palm Zire id to the visor driver, thanks to Martin Brachtl

drivers/usb/serial/visor.c | 6 ++++--
drivers/usb/serial/visor.h | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
------

[email protected], 2002-09-30 15:54:02-07:00, [email protected]
USB: queue_task() fixups

drivers/usb/class/bluetty.c | 4 +---
drivers/usb/class/cdc-acm.c | 3 +--
drivers/usb/serial/cyberjack.c | 14 +++-----------
drivers/usb/serial/empeg.c | 6 +-----
drivers/usb/serial/ftdi_sio.c | 4 +---
drivers/usb/serial/ipaq.c | 6 ++----
drivers/usb/serial/ir-usb.c | 5 +----
drivers/usb/serial/keyspan.c | 6 ++----
drivers/usb/serial/kl5kusb105.c | 5 +----
drivers/usb/serial/mct_u232.c | 3 +--
drivers/usb/serial/omninet.c | 5 +----
drivers/usb/serial/pl2303.c | 5 +----
drivers/usb/serial/usbserial.c | 5 +----
drivers/usb/serial/visor.c | 5 +----
drivers/usb/serial/whiteheat.c | 5 +----
15 files changed, 19 insertions(+), 62 deletions(-)
------


2002-10-01 00:29:41

by Greg KH

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

# 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.660 -> 1.660.1.1
# drivers/usb/serial/keyspan.c 1.32 -> 1.33
# drivers/usb/class/bluetty.c 1.28 -> 1.29
# drivers/usb/serial/ftdi_sio.c 1.35 -> 1.36
# drivers/usb/serial/ipaq.c 1.17 -> 1.18
# drivers/usb/serial/visor.c 1.40 -> 1.41
# drivers/usb/serial/omninet.c 1.23 -> 1.24
# drivers/usb/serial/whiteheat.c 1.24 -> 1.25
# drivers/usb/serial/usbserial.c 1.43 -> 1.44
# drivers/usb/serial/empeg.c 1.30 -> 1.31
# drivers/usb/serial/pl2303.c 1.24 -> 1.25
# drivers/usb/serial/ir-usb.c 1.20 -> 1.21
# drivers/usb/serial/kl5kusb105.c 1.13 -> 1.14
# drivers/usb/class/cdc-acm.c 1.21 -> 1.22
# drivers/usb/serial/mct_u232.c 1.28 -> 1.29
# drivers/usb/serial/cyberjack.c 1.19 -> 1.20
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.1
# USB: queue_task() fixups
# --------------------------------------------
#
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/class/bluetty.c Mon Sep 30 17:26:30 2002
@@ -1006,9 +1006,7 @@
}

/* wake up our little function to let the tty layer know that something happened */
- queue_task(&bluetooth->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- return;
+ schedule_task(&bluetooth->tqueue);
}


diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/class/cdc-acm.c Mon Sep 30 17:26:30 2002
@@ -272,8 +272,7 @@
if (urb->status)
dbg("nonzero write bulk status received: %d", urb->status);

- queue_task(&acm->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ schedule_task(&acm->tqueue);
}

static void acm_softint(void *private)
diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/cyberjack.c Mon Sep 30 17:26:30 2002
@@ -437,9 +437,7 @@
/* Throw away data. No better idea what to do with it. */
priv->wrfilled=0;
priv->wrsent=0;
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- return;
+ goto exit;
}

dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent);
@@ -453,16 +451,10 @@
priv->wrfilled=0;
priv->wrsent=0;
}
-
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- return;
}

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+exit:
+ schedule_task(&port->tqueue);
}

static int __init cyberjack_init (void)
diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
--- a/drivers/usb/serial/empeg.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/empeg.c Mon Sep 30 17:26:30 2002
@@ -362,11 +362,7 @@
return;
}

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
-
+ schedule_task(&port->tqueue);
}


diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/ftdi_sio.c Mon Sep 30 17:26:30 2002
@@ -484,10 +484,8 @@
dbg("nonzero write bulk status received: %d", urb->status);
return;
}
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);

- return;
+ schedule_task(&port->tqueue);
} /* ftdi_sio_write_bulk_callback */


diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/ipaq.c Mon Sep 30 17:26:30 2002
@@ -465,10 +465,8 @@
priv->active = 0;
spin_unlock_irqrestore(&write_list_lock, flags);
}
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+
+ schedule_task(&port->tqueue);
}

static int ipaq_write_room(struct usb_serial_port *port)
diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
--- a/drivers/usb/serial/ir-usb.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/ir-usb.c Mon Sep 30 17:26:30 2002
@@ -426,10 +426,7 @@
urb->actual_length,
urb->transfer_buffer);

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+ schedule_task(&port->tqueue);
}

static void ir_read_bulk_callback (struct urb *urb)
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/keyspan.c Mon Sep 30 17:26:30 2002
@@ -447,10 +447,8 @@
p_priv = (struct keyspan_port_private *)(port->private);
dbg ("%s - urb %d", __FUNCTION__, urb == p_priv->out_urbs[1]);

- if (port->open_count) {
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- }
+ if (port->open_count)
+ schedule_task(&port->tqueue);
}

static void usa26_inack_callback(struct urb *urb)
diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
--- a/drivers/usb/serial/kl5kusb105.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/kl5kusb105.c Mon Sep 30 17:26:30 2002
@@ -577,10 +577,7 @@
}

/* from generic_write_bulk_callback */
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+ schedule_task(&port->tqueue);
} /* klsi_105_write_bulk_completion_callback */


diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/mct_u232.c Mon Sep 30 17:26:30 2002
@@ -507,8 +507,7 @@

} else {
/* from generic_write_bulk_callback */
- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ schedule_task(&port->tqueue);
}

return;
diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
--- a/drivers/usb/serial/omninet.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/omninet.c Mon Sep 30 17:26:30 2002
@@ -359,12 +359,9 @@
return;
}

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ schedule_task(&port->tqueue);

// dbg("omninet_write_bulk_callback, tty %0x\n", tty);
-
- return;
}


diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/pl2303.c Mon Sep 30 17:26:30 2002
@@ -705,10 +705,7 @@
return;
}

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+ schedule_task(&port->tqueue);
}


diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/usbserial.c Mon Sep 30 17:26:30 2002
@@ -1092,10 +1092,7 @@

usb_serial_port_softint((void *)port);

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+ schedule_tasks(&port->tqueue);
}

static void generic_shutdown (struct usb_serial *serial)
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/visor.c Mon Sep 30 17:26:30 2002
@@ -458,10 +458,7 @@
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+ schedule_task(&port->tqueue);
}


diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
--- a/drivers/usb/serial/whiteheat.c Mon Sep 30 17:26:30 2002
+++ b/drivers/usb/serial/whiteheat.c Mon Sep 30 17:26:30 2002
@@ -918,10 +918,7 @@

usb_serial_port_softint((void *)port);

- queue_task(&port->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- return;
+ schedule_task(&port->tqueue);
}


2002-10-01 00:31:02

by Greg KH

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

# 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.660.1.2 -> 1.660.1.3
# drivers/base/hotplug.c 1.1 -> 1.2
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.3
# driver core: added location of device in driverfs tree to /sbin/hotplug call.
#
# /sbin/hotplug is now called when any device is added or removed from the
# system.
# --------------------------------------------
#
diff -Nru a/drivers/base/hotplug.c b/drivers/base/hotplug.c
--- a/drivers/base/hotplug.c Mon Sep 30 17:25:55 2002
+++ b/drivers/base/hotplug.c Mon Sep 30 17:25:55 2002
@@ -18,6 +18,7 @@
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include "base.h"
+#include "fs/fs.h"

/*
* hotplugging invokes what /proc/sys/kernel/hotplug says (normally
@@ -32,14 +33,16 @@
int dev_hotplug (struct device *dev, const char *action)
{
char *argv [3], **envp, *buffer, *scratch;
+ char *dev_path;
int retval;
int i = 0;
+ int dev_length;

pr_debug ("%s\n", __FUNCTION__);
if (!dev)
return -ENODEV;

- if (!dev->bus || !dev->bus->hotplug)
+ if (!dev->bus)
return -ENODEV;

if (!hotplug_path [0])
@@ -66,6 +69,18 @@
return -ENOMEM;
}

+ dev_length = get_devpath_length (dev);
+ dev_length += strlen("root");
+ dev_path = kmalloc (dev_length, GFP_KERNEL);
+ if (!dev_path) {
+ kfree (buffer);
+ kfree (envp);
+ return -ENOMEM;
+ }
+ memset (dev_path, 0x00, dev_length);
+ strcpy (dev_path, "root");
+ fill_devpath (dev, dev_path, dev_length);
+
/* only one standardized param to hotplug command: the bus name */
argv [0] = hotplug_path;
argv [1] = dev->bus->name;
@@ -77,26 +92,33 @@

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;
+ envp [i++] = scratch;
+ scratch += sprintf (scratch, "DEVICE=%s", dev_path) + 1;
+
+ if (dev->bus->hotplug) {
+ /* have the bus specific function add its stuff */
+ 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]);
+ envp[0], envp[1], envp[2], envp[3]);
retval = call_usermodehelper (argv [0], argv, envp);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
__FUNCTION__, retval);

exit:
+ kfree (dev_path);
kfree (buffer);
kfree (envp);
return retval;

2002-10-01 00:33:07

by Greg KH

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

# 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.660.1.4 -> 1.660.1.5
# drivers/usb/core/hub.c 1.35 -> 1.36
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.5
# USB: Fix the name of usb hubs in driverfs.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Mon Sep 30 17:25:28 2002
+++ b/drivers/usb/core/hub.c Mon Sep 30 17:25:28 2002
@@ -537,7 +537,7 @@
dev_set_drvdata (&intf->dev, hub);

if (usb_hub_configure(hub, endpoint) >= 0) {
- strcpy (intf->dev.name, "Hub/Port Status Changes");
+ strcpy (intf->dev.name, "Hub");
return 0;
}

2002-10-01 00:34:11

by Greg KH

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

# 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.660.1.5 -> 1.660.1.6
# drivers/usb/core/usb.c 1.89 -> 1.90
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.6
# USB: allow /sbin/hotplug to be called for the main USB device.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Mon Sep 30 17:25:17 2002
+++ b/drivers/usb/core/usb.c Mon Sep 30 17:25:17 2002
@@ -525,9 +525,8 @@
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;
+ return 0;

intf = to_usb_interface(dev);
if (!intf)

2002-10-01 00:29:57

by Greg KH

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

# 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.660.1.1 -> 1.660.1.2
# drivers/usb/serial/visor.h 1.11 -> 1.12
# drivers/usb/serial/visor.c 1.41 -> 1.42
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.2
# USB: added Palm Zire id to the visor driver, thanks to Martin Brachtl
# --------------------------------------------
#
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c Mon Sep 30 17:26:09 2002
+++ b/drivers/usb/serial/visor.c Mon Sep 30 17:26:09 2002
@@ -182,9 +182,10 @@
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
+ { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
- { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
+ { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
@@ -202,9 +203,10 @@
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
+ { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
- { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
+ { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
--- a/drivers/usb/serial/visor.h Mon Sep 30 17:26:09 2002
+++ b/drivers/usb/serial/visor.h Mon Sep 30 17:26:09 2002
@@ -27,6 +27,7 @@
#define PALM_I705_ID 0x0020
#define PALM_M125_ID 0x0040
#define PALM_M130_ID 0x0050
+#define PALM_ZIRE_ID 0x0070

#define SONY_VENDOR_ID 0x054C
#define SONY_CLIE_3_5_ID 0x0038

2002-10-01 00:32:00

by Greg KH

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

# 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.660.1.3 -> 1.660.1.4
# drivers/usb/core/usb.c 1.88 -> 1.89
# drivers/usb/core/Makefile 1.11 -> 1.12
# (new) -> 1.1 drivers/usb/core/usb.h
# (new) -> 1.1 drivers/usb/core/driverfs.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.4
# USB: add a lot more driverfs files for all usb devices.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
--- a/drivers/usb/core/Makefile Mon Sep 30 17:25:40 2002
+++ b/drivers/usb/core/Makefile Mon Sep 30 17:25:40 2002
@@ -5,7 +5,7 @@
export-objs := usb.o hcd.o hcd-pci.o urb.o message.o file.o buffer.o

usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \
- config.o file.o buffer.o
+ config.o file.o buffer.o driverfs.o

ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
diff -Nru a/drivers/usb/core/driverfs.c b/drivers/usb/core/driverfs.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/core/driverfs.c Mon Sep 30 17:25:40 2002
@@ -0,0 +1,177 @@
+/*
+ * drivers/usb/core/driverfs.c
+ *
+ * (C) Copyright 2002 David Brownell
+ * (C) Copyright 2002 Greg Kroah-Hartman
+ * (C) Copyright 2002 IBM Corp.
+ *
+ * All of the driverfs file attributes for usb devices and interfaces.
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#ifdef CONFIG_USB_DEBUG
+ #define DEBUG
+#else
+ #undef DEBUG
+#endif
+#include <linux/usb.h>
+
+#include "usb.h"
+
+/* Active configuration fields */
+#define usb_actconfig_attr(field, format_string) \
+static ssize_t \
+show_##field (struct device *dev, char *buf, size_t count, loff_t off) \
+{ \
+ struct usb_device *udev; \
+ \
+ if (off) \
+ return 0; \
+ \
+ udev = to_usb_device (dev); \
+ return sprintf (buf, format_string, udev->actconfig->field); \
+} \
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_actconfig_attr (bNumInterfaces, "%2d\n")
+usb_actconfig_attr (bConfigurationValue, "%2d\n")
+usb_actconfig_attr (bmAttributes, "%2x\n")
+usb_actconfig_attr (MaxPower, "%3dmA\n")
+
+/* String fields */
+static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct usb_device *udev;
+ int len;
+
+ if (off)
+ return 0;
+ udev = to_usb_device (dev);
+
+ len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE);
+ if (len < 0)
+ return 0;
+ buf[len] = '\n';
+ buf[len+1] = 0;
+ return len+1;
+}
+static DEVICE_ATTR(product,S_IRUGO,show_product,NULL);
+
+static ssize_t
+show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct usb_device *udev;
+ int len;
+
+ if (off)
+ return 0;
+ udev = to_usb_device (dev);
+
+ len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE);
+ if (len < 0)
+ return 0;
+ buf[len] = '\n';
+ buf[len+1] = 0;
+ return len+1;
+}
+static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL);
+
+static ssize_t
+show_serial (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct usb_device *udev;
+ int len;
+
+ if (off)
+ return 0;
+ udev = to_usb_device (dev);
+
+ len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE);
+ if (len < 0)
+ return 0;
+ buf[len] = '\n';
+ buf[len+1] = 0;
+ return len+1;
+}
+static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
+
+/* Descriptor fields */
+#define usb_descriptor_attr(field, format_string) \
+static ssize_t \
+show_##field (struct device *dev, char *buf, size_t count, loff_t off) \
+{ \
+ struct usb_device *udev; \
+ \
+ if (off) \
+ return 0; \
+ \
+ udev = to_usb_device (dev); \
+ return sprintf (buf, format_string, udev->descriptor.field); \
+} \
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_descriptor_attr (idVendor, "%04x\n")
+usb_descriptor_attr (idProduct, "%04x\n")
+usb_descriptor_attr (bcdDevice, "%04x\n")
+usb_descriptor_attr (bDeviceClass, "%02x\n")
+usb_descriptor_attr (bDeviceSubClass, "%02x\n")
+usb_descriptor_attr (bDeviceProtocol, "%02x\n")
+
+
+void usb_create_driverfs_dev_files (struct usb_device *udev)
+{
+ struct device *dev = &udev->dev;
+
+ device_create_file (dev, &dev_attr_bNumInterfaces);
+ device_create_file (dev, &dev_attr_bConfigurationValue);
+ device_create_file (dev, &dev_attr_bmAttributes);
+ device_create_file (dev, &dev_attr_MaxPower);
+ device_create_file (dev, &dev_attr_idVendor);
+ device_create_file (dev, &dev_attr_idProduct);
+ device_create_file (dev, &dev_attr_bcdDevice);
+ device_create_file (dev, &dev_attr_bDeviceClass);
+ device_create_file (dev, &dev_attr_bDeviceSubClass);
+ device_create_file (dev, &dev_attr_bDeviceProtocol);
+
+ if (udev->descriptor.iManufacturer)
+ device_create_file (dev, &dev_attr_manufacturer);
+ if (udev->descriptor.iProduct)
+ device_create_file (dev, &dev_attr_product);
+ if (udev->descriptor.iSerialNumber)
+ device_create_file (dev, &dev_attr_serial);
+}
+
+/* Interface fields */
+#define usb_intf_attr(field, format_string) \
+static ssize_t \
+show_##field (struct device *dev, char *buf, size_t count, loff_t off) \
+{ \
+ struct usb_interface *intf; \
+ int alt; \
+ \
+ if (off) \
+ return 0; \
+ \
+ intf = to_usb_interface (dev); \
+ alt = intf->act_altsetting; \
+ \
+ return sprintf (buf, format_string, intf->altsetting[alt].field); \
+} \
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_intf_attr (bAlternateSetting, "%2d\n")
+usb_intf_attr (bInterfaceClass, "%02x\n")
+usb_intf_attr (bInterfaceSubClass, "%02x\n")
+usb_intf_attr (bInterfaceProtocol, "%02x\n")
+
+void usb_create_driverfs_intf_files (struct usb_interface *intf)
+{
+ device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
+ device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
+ device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
+ device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
+}
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Mon Sep 30 17:25:40 2002
+++ b/drivers/usb/core/usb.c Mon Sep 30 17:25:40 2002
@@ -42,6 +42,7 @@
#include <linux/usb.h>

#include "hcd.h"
+#include "usb.h"

extern int usb_hub_init(void);
extern void usb_hub_cleanup(void);
@@ -629,98 +630,6 @@

#endif /* CONFIG_HOTPLUG */

-/* driverfs files */
-
-/* devices have one current configuration, with one
- * or more interfaces that are used concurrently
- */
-static ssize_t
-show_config (struct device *dev, char *buf, size_t count, loff_t off)
-{
- struct usb_device *udev;
-
- if (off)
- return 0;
- udev = to_usb_device (dev);
- return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue);
-}
-
-static DEVICE_ATTR(configuration,S_IRUGO,show_config,NULL);
-
-/* interfaces have one current setting; alternates
- * can have different endpoints and class info.
- */
-static ssize_t
-show_altsetting (struct device *dev, char *buf, size_t count, loff_t off)
-{
- struct usb_interface *interface;
-
- if (off)
- return 0;
- interface = to_usb_interface (dev);
- return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting);
-}
-static DEVICE_ATTR(altsetting,S_IRUGO,show_altsetting,NULL);
-
-/* product driverfs file */
-static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off)
-{
- struct usb_device *udev;
- int len;
-
- if (off)
- return 0;
- udev = to_usb_device (dev);
-
- len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE);
- if (len < 0)
- return 0;
- buf[len] = '\n';
- buf[len+1] = 0;
- return len+1;
-}
-static DEVICE_ATTR(product,S_IRUGO,show_product,NULL);
-
-/* manufacturer driverfs file */
-static ssize_t
-show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
-{
- struct usb_device *udev;
- int len;
-
- if (off)
- return 0;
- udev = to_usb_device (dev);
-
- len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE);
- if (len < 0)
- return 0;
- buf[len] = '\n';
- buf[len+1] = 0;
- return len+1;
-}
-static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL);
-
-/* serial number driverfs file */
-static ssize_t
-show_serial (struct device *dev, char *buf, size_t count, loff_t off)
-{
- struct usb_device *udev;
- int len;
-
- if (off)
- return 0;
- udev = to_usb_device (dev);
-
- len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE);
- if (len < 0)
- return 0;
- buf[len] = '\n';
- buf[len+1] = 0;
- return len+1;
-}
-static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
-
/**
* usb_alloc_dev - allocate a usb device structure (usbcore-internal)
* @parent: hub to which device is connected
@@ -1133,13 +1042,7 @@
return err;

/* add the USB device specific driverfs files */
- device_create_file (&dev->dev, &dev_attr_configuration);
- if (dev->descriptor.iManufacturer)
- device_create_file (&dev->dev, &dev_attr_manufacturer);
- if (dev->descriptor.iProduct)
- device_create_file (&dev->dev, &dev_attr_product);
- if (dev->descriptor.iSerialNumber)
- device_create_file (&dev->dev, &dev_attr_serial);
+ usb_create_driverfs_dev_files (dev);

/* Register all of the interfaces for this device with the driver core.
* Remember, interfaces get bound to drivers, not devices. */
@@ -1169,7 +1072,7 @@
}
dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
device_register (&interface->dev);
- device_create_file (&interface->dev, &dev_attr_altsetting);
+ usb_create_driverfs_intf_files (interface);
}

/* add a /proc/bus/usb entry */
diff -Nru a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/core/usb.h Mon Sep 30 17:25:40 2002
@@ -0,0 +1,5 @@
+/* Functions local to drivers/usb/core/ */
+
+extern void usb_create_driverfs_dev_files (struct usb_device *dev);
+extern void usb_create_driverfs_intf_files (struct usb_interface *intf);
+

2002-10-01 00:34:12

by Greg KH

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

# 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.660.1.6 -> 1.660.1.7
# drivers/usb/host/ohci-hcd.c 1.27 -> 1.28
# include/linux/usbdevice_fs.h 1.6 -> 1.7
# drivers/usb/core/message.c 1.7 -> 1.8
# include/linux/usb.h 1.49 -> 1.50
# drivers/usb/core/hub.c 1.36 -> 1.37
# drivers/usb/core/devio.c 1.34 -> 1.35
# drivers/usb/core/usb.c 1.90 -> 1.91
# drivers/usb/core/hcd.c 1.34 -> 1.35
# drivers/usb/core/urb.c 1.6 -> 1.7
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.7
# [PATCH] usbcore misc cleanup
#
# This has minor usbcore cleanups:
#
# DOC:
# - the changes passing a usb_interface to driver probe() and disconnect()
# weren't reflected in their adjacent docs. likewise they still said
# it was possible to get a null usb_device_id (no more).
#
# - the (root) hub API restrictions from rmk's ARM patch weren't
# flagged
#
# - mention the non-dma-coherent cache issue for usb_buffer_alloc()
#
# - mention disconnect() cleanup issue with usb_{control,bulk}_msg()
# [ you can't cancel those urbs from disconnect() ]
#
# CODE
# - make driver ioctl() use 'usb_interface' too ... this update
# also resolves an old 'one instance per device' bad assumption
#
# - module locking on driver->ioctl() was goofy, kept BKL way too
# long and didn't try_inc_mod_count() like the rest of usbcore
#
# - hcd unlink code treated iso inappropriately like interrupt;
# only interrupt still wants that automagic mode
#
# - move iso init out of ohci into shared submit_urb logic
#
# - remove interrupt transfer length restriction; hcds that don't
# handle packetization (just like bulk :) should be updated,
# but device drivers won't care for now.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/core/devio.c Mon Sep 30 17:25:04 2002
@@ -1067,6 +1067,10 @@
/* disconnect kernel driver from interface, leaving it unbound. */
case USBDEVFS_DISCONNECT:
/* this function is voodoo. */
+ /* which function ... usb_device_remove()?
+ * FIXME either the module lock (BKL) should be involved
+ * here too, or the 'default' case below is broken
+ */
driver = ifp->driver;
if (driver) {
dbg ("disconnect '%s' from dev %d interface %d",
@@ -1081,26 +1085,28 @@
retval = usb_device_probe (&ifp->dev);
break;

- /* talk directly to the interface's driver */
- default:
- lock_kernel(); /* against module unload */
- driver = ifp->driver;
- if (driver == 0 || driver->ioctl == 0) {
+ /* talk directly to the interface's driver */
+ default:
+ /* BKL used here to protect against changing the binding
+ * of this driver to this device, as well as unloading its
+ * driver module.
+ */
+ lock_kernel ();
+ driver = ifp->driver;
+ if (driver == 0 || driver->ioctl == 0) {
unlock_kernel();
retval = -ENOSYS;
} else {
- if (ifp->driver->owner) {
- __MOD_INC_USE_COUNT(ifp->driver->owner);
- unlock_kernel();
- }
- /* ifno might usefully be passed ... */
- retval = driver->ioctl (ps->dev, ctrl.ioctl_code, buf);
- /* size = min_t(int, size, retval)? */
- if (ifp->driver->owner) {
- __MOD_DEC_USE_COUNT(ifp->driver->owner);
- } else {
+ if (driver->owner
+ && !try_inc_mod_count (driver->owner)) {
unlock_kernel();
+ retval = -ENOSYS;
+ break;
}
+ unlock_kernel ();
+ retval = driver->ioctl (ifp, ctrl.ioctl_code, buf);
+ if (driver->owner)
+ __MOD_DEC_USE_COUNT (driver->owner);
}

if (retval == -ENOIOCTLCMD)
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/core/hcd.c Mon Sep 30 17:25:04 2002
@@ -1024,6 +1024,11 @@
*/
urb = usb_get_urb (urb);
if (urb->dev == hcd->self.root_hub) {
+ /* NOTE: requirement on hub callers (usbfs and the hub
+ * driver, for now) that URBs' urb->transfer_buffer be
+ * valid and usb_buffer_{sync,unmap}() not be needed, since
+ * they could clobber root hub response data.
+ */
urb->transfer_flags |= URB_NO_DMA_MAP;
return rh_urb_enqueue (hcd, urb);
}
@@ -1132,11 +1137,11 @@
goto done;
}

- /* For non-periodic transfers, any status except -EINPROGRESS means
- * the HCD has already started to unlink this URB from the hardware.
- * In that case, there's no more work to do.
+ /* Except for interrupt transfers, any status except -EINPROGRESS
+ * means the HCD already started to unlink this URB from the hardware.
+ * So there's no more work to do.
*
- * For periodic transfers, this is the only way to trigger unlinking
+ * For interrupt transfers, this is the only way to trigger unlinking
* from the hardware. Since we (currently) overload urb->status to
* tell the driver to unlink, error status might get clobbered ...
* unless that transfer hasn't yet restarted. One such case is when
@@ -1144,13 +1149,10 @@
*
* FIXME use an URB_UNLINKED flag to match URB_TIMEOUT_KILLED
*/
- switch (usb_pipetype (urb->pipe)) {
- case PIPE_CONTROL:
- case PIPE_BULK:
- if (urb->status != -EINPROGRESS) {
- retval = -EINVAL;
- goto done;
- }
+ if (urb->status != -EINPROGRESS
+ && usb_pipetype (urb->pipe) != PIPE_INTERRUPT) {
+ retval = -EINVAL;
+ goto done;
}

/* maybe set up to block on completion notification */
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/core/hub.c Mon Sep 30 17:25:04 2002
@@ -547,8 +547,11 @@
return -ENODEV;
}

-static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
+static int
+hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
{
+ struct usb_device *hub = interface_to_usbdev (intf);
+
/* assert ifno == 0 (part of hub spec) */
switch (code) {
case USBDEVFS_HUB_PORTINFO: {
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/core/message.c Mon Sep 30 17:25:04 2002
@@ -123,6 +123,9 @@
* Don't use this function from within an interrupt context, like a
* bottom half handler. If you need an asynchronous message, or need to send
* a message from within interrupt context, use usb_submit_urb()
+ * If a thread in your driver uses this call, make sure your disconnect()
+ * method can wait for it to complete. Since you don't have a handle on
+ * the URB used, you can't cancel the request.
*/
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
__u16 value, __u16 index, void *data, __u16 size, int timeout)
@@ -170,6 +173,9 @@
* Don't use this function from within an interrupt context, like a
* bottom half handler. If you need an asynchronous message, or need to
* send a message from within interrupt context, use usb_submit_urb()
+ * If a thread in your driver uses this call, make sure your disconnect()
+ * method can wait for it to complete. Since you don't have a handle on
+ * the URB used, you can't cancel the request.
*/
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
--- a/drivers/usb/core/urb.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/core/urb.c Mon Sep 30 17:25:04 2002
@@ -232,22 +232,19 @@
return -EMSGSIZE;
}

- /* "high bandwidth" mode, 1-3 packets/uframe? */
- if (dev->speed == USB_SPEED_HIGH) {
- int mult;
- switch (temp) {
- case PIPE_ISOCHRONOUS:
- case PIPE_INTERRUPT:
- mult = 1 + ((max >> 11) & 0x03);
+ /* periodic transfers limit size per frame/uframe,
+ * but drivers only control those sizes for ISO.
+ * while we're checking, initialize return status.
+ */
+ if (temp == PIPE_ISOCHRONOUS) {
+ int n, len;
+
+ /* "high bandwidth" mode, 1-3 packets/uframe? */
+ if (dev->speed == USB_SPEED_HIGH) {
+ int mult = 1 + ((max >> 11) & 0x03);
max &= 0x03ff;
max *= mult;
}
- }
-
- /* periodic transfers limit size per frame/uframe */
- switch (temp) {
- case PIPE_ISOCHRONOUS: {
- int n, len;

if (urb->number_of_packets <= 0)
return -EINVAL;
@@ -255,13 +252,9 @@
len = urb->iso_frame_desc [n].length;
if (len < 0 || len > max)
return -EMSGSIZE;
+ urb->iso_frame_desc [n].status = -EXDEV;
+ urb->iso_frame_desc [n].actual_length = 0;
}
-
- }
- break;
- case PIPE_INTERRUPT:
- if (urb->transfer_buffer_length > max)
- return -EMSGSIZE;
}

/* the I/O buffer must be mapped/unmapped, except when length=0 */
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/core/usb.c Mon Sep 30 17:25:04 2002
@@ -124,6 +124,8 @@
if (driver->owner) {
m = try_inc_mod_count(driver->owner);
if (m == 0) {
+ // FIXME this happens even when we just rmmod
+ // drivers that aren't in active use...
err("Dieing driver still bound to device.\n");
return -EIO;
}
@@ -1096,6 +1098,8 @@
* avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping
* hardware for long idle periods. The implementation varies between
* platforms, depending on details of how DMA will work to this device.
+ * Using these buffers also helps prevent cacheline sharing problems on
+ * architectures where CPU caches are not DMA-coherent.
*
* When the buffer is no longer used, free it with usb_buffer_free().
*/
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c Mon Sep 30 17:25:04 2002
+++ b/drivers/usb/host/ohci-hcd.c Mon Sep 30 17:25:04 2002
@@ -193,12 +193,6 @@
break;
case PIPE_ISOCHRONOUS: /* number of packets from URB */
size = urb->number_of_packets;
- if (size <= 0)
- return -EINVAL;
- for (i = 0; i < urb->number_of_packets; i++) {
- urb->iso_frame_desc [i].actual_length = 0;
- urb->iso_frame_desc [i].status = -EXDEV;
- }
break;
}

diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h Mon Sep 30 17:25:04 2002
+++ b/include/linux/usb.h Mon Sep 30 17:25:04 2002
@@ -452,9 +452,9 @@
* User mode code can read these tables to choose which modules to load.
* Declare the table as a MODULE_DEVICE_TABLE.
*
- * The third probe() parameter will point to a matching entry from this
- * table. (Null value reserved.) Use the driver_data field for each
- * match to hold information tied to that match: device quirks, etc.
+ * A probe() parameter will point to a matching entry from this table.
+ * Use the driver_info field for each match to hold information tied
+ * to that match: device quirks, etc.
*
* Terminate the driver's table with an all-zeroes entry.
* Use the flag values to control which fields are compared.
@@ -604,17 +604,14 @@
* @name: The driver name should be unique among USB drivers,
* and should normally be the same as the module name.
* @probe: Called to see if the driver is willing to manage a particular
- * interface on a device. The probe routine returns a handle that
- * will later be provided to disconnect(), or a null pointer to
- * indicate that the driver will not handle the interface.
- * The handle is normally a pointer to driver-specific data.
- * If the probe() routine needs to access the interface
- * structure itself, use usb_ifnum_to_if() to make sure it's using
- * the right one.
+ * interface on a device. If it is, probe returns zero and uses
+ * dev_set_drvdata() to associate driver-specific data with the
+ * interface. It may also use usb_set_interface() to specify the
+ * appropriate altsetting. If unwilling to manage the interface,
+ * return a negative errno value.
* @disconnect: Called when the interface is no longer accessible, usually
- * because its device has been (or is being) disconnected. The
- * handle passed is what was returned by probe(), or was provided
- * to usb_driver_claim_interface().
+ * because its device has been (or is being) disconnected or the
+ * driver module is being unloaded.
* @ioctl: Used for drivers that want to talk to userspace through
* the "usbfs" filesystem. This lets devices provide ways to
* expose information to user space regardless of where they
@@ -648,7 +645,7 @@

void (*disconnect) (struct usb_interface *intf);

- int (*ioctl) (struct usb_device *dev, unsigned int code, void *buf);
+ int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf);

const struct usb_device_id *id_table;

diff -Nru a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
--- a/include/linux/usbdevice_fs.h Mon Sep 30 17:25:04 2002
+++ b/include/linux/usbdevice_fs.h Mon Sep 30 17:25:04 2002
@@ -108,7 +108,7 @@
struct usbdevfs_iso_packet_desc iso_frame_desc[0];
};

-/* ioctls for talking to drivers in the usbcore module: */
+/* ioctls for talking directly to drivers */
struct usbdevfs_ioctl {
int ifno; /* interface 0..N ; negative numbers reserved */
int ioctl_code; /* MUST encode size + direction of data so the

2002-10-01 00:36:34

by Greg KH

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

# 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.660.1.7 -> 1.660.1.8
# drivers/usb/serial/usbserial.c 1.44 -> 1.45
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/30 [email protected] 1.660.1.8
# USB: fix typo from previous schedule_task() patch.
# --------------------------------------------
#
diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c Mon Sep 30 17:24:53 2002
+++ b/drivers/usb/serial/usbserial.c Mon Sep 30 17:24:53 2002
@@ -1092,7 +1092,7 @@

usb_serial_port_softint((void *)port);

- schedule_tasks(&port->tqueue);
+ schedule_task(&port->tqueue);
}

static void generic_shutdown (struct usb_serial *serial)