Hi,
Here are a bunch of USB and Driver core patches for 2.6.10 (I had to
merge the trees due to some merge conflicts that came up between them.)
Highlights include:
- delete the tiglusb driver (works just fine from userspace, and
the author asked for it to be done.)
- 2 new usb-serial drivers
- AOE drivers added to the tree
- debugfs added.
- usb host controller driver churn (hopefully this is now
settled down...)
- some new sysfs attributes for pci devices on platforms that
support them
- all usb config fields are now in native (le16) byte order, and
all in-tree USB drivers have been fixed up to properly handle
this.
- lots of bug fixes and other assorted goodness.
Please pull from:
bk://kernel.bkbits.net/gregkh/linux/usb-2.6
Patches will be posted to linux-usb-devel and linux-kernel as a
follow-up thread for those who want to see them.
thanks,
greg k-h
drivers/usb/misc/tiglusb.c | 592 ------
drivers/usb/misc/tiglusb.h | 43
Documentation/Changes | 20
Documentation/DocBook/kernel-api.tmpl | 9
Documentation/aoe/aoe.txt | 75
Documentation/aoe/autoload.sh | 17
Documentation/aoe/mkdevs.sh | 33
Documentation/aoe/mkshelf.sh | 23
Documentation/aoe/status.sh | 15
Documentation/feature-removal-schedule.txt | 26
Documentation/filesystems/sysfs-pci.txt | 90 +
Documentation/stable_api_nonsense.txt | 4
Documentation/usb/sn9c102.txt | 202 +-
MAINTAINERS | 18
arch/ia64/Kconfig | 26
arch/mips/au1000/common/usbdev.c | 6
arch/ppc64/Kconfig | 6
arch/s390/Kconfig | 6
drivers/Makefile | 2
drivers/base/Kconfig | 2
drivers/base/bus.c | 2
drivers/base/class.c | 18
drivers/base/platform.c | 52
drivers/block/Kconfig | 8
drivers/block/aoe/Makefile | 6
drivers/block/aoe/aoe.h | 166 +
drivers/block/aoe/aoeblk.c | 255 ++-
drivers/block/aoe/aoechr.c | 323 +++
drivers/block/aoe/aoecmd.c | 627 +++++++
drivers/block/aoe/aoedev.c | 194 ++
drivers/block/aoe/aoemain.c | 93 +
drivers/block/aoe/aoenet.c | 185 ++
drivers/bluetooth/bfusb.c | 2
drivers/bluetooth/hci_usb.c | 10
drivers/char/misc.c | 14
drivers/char/watchdog/pcwd_usb.c | 8
drivers/isdn/hisax/hfc_usb.c | 15
drivers/isdn/hisax/st5481_b.c | 2
drivers/isdn/hisax/st5481_d.c | 2
drivers/isdn/hisax/st5481_init.c | 3
drivers/isdn/hisax/st5481_usb.c | 4
drivers/media/dvb/b2c2/b2c2-usb-core.c | 2
drivers/media/dvb/dibusb/dvb-dibusb.c | 12
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 6
drivers/media/dvb/ttusb-dec/ttusb_dec.c | 8
drivers/net/irda/irda-usb.c | 6
drivers/net/irda/stir4200.c | 4
drivers/net/pcmcia/Kconfig | 2
drivers/net/tokenring/Kconfig | 2
drivers/net/wireless/Kconfig | 2
drivers/parport/Kconfig | 2
drivers/pci/hotplug/Kconfig | 2
drivers/pci/hotplug/pciehp_core.c | 1
drivers/pci/hotplug/shpchp_core.c | 1
drivers/pci/pci-sysfs.c | 163 +
drivers/pci/probe.c | 83
drivers/pcmcia/Kconfig | 2
drivers/usb/Makefile | 4
drivers/usb/README | 33
drivers/usb/atm/speedtch.c | 31
drivers/usb/atm/usb_atm.c | 34
drivers/usb/atm/usb_atm.h | 19
drivers/usb/class/audio.c | 7
drivers/usb/class/bluetty.c | 6
drivers/usb/class/cdc-acm.c | 21
drivers/usb/class/cdc-acm.h | 3
drivers/usb/class/usb-midi.c | 30
drivers/usb/class/usb-midi.h | 4
drivers/usb/class/usblp.c | 19
drivers/usb/core/config.c | 4
drivers/usb/core/devices.c | 14
drivers/usb/core/devio.c | 65
drivers/usb/core/hcd-pci.c | 23
drivers/usb/core/hcd.c | 234 +-
drivers/usb/core/hcd.h | 47
drivers/usb/core/hub.c | 706 ++++----
drivers/usb/core/hub.h | 2
drivers/usb/core/inode.c | 4
drivers/usb/core/message.c | 54
drivers/usb/core/otg_whitelist.h | 16
drivers/usb/core/sysfs.c | 26
drivers/usb/core/urb.c | 2
drivers/usb/core/usb.c | 84
drivers/usb/core/usb.h | 2
drivers/usb/gadget/Kconfig | 35
drivers/usb/gadget/dummy_hcd.c | 134 -
drivers/usb/gadget/epautoconf.c | 3
drivers/usb/gadget/file_storage.c | 2
drivers/usb/gadget/omap_udc.c | 2
drivers/usb/gadget/serial.c | 2
drivers/usb/host/ehci-dbg.c | 30
drivers/usb/host/ehci-hcd.c | 130 -
drivers/usb/host/ehci-hub.c | 26
drivers/usb/host/ehci-mem.c | 31
drivers/usb/host/ehci-q.c | 68
drivers/usb/host/ehci-sched.c | 424 ++--
drivers/usb/host/ehci.h | 50
drivers/usb/host/hc_crisv10.c | 34
drivers/usb/host/ohci-dbg.c | 22
drivers/usb/host/ohci-hcd.c | 73
drivers/usb/host/ohci-hub.c | 29
drivers/usb/host/ohci-lh7a404.c | 45
drivers/usb/host/ohci-mem.c | 25
drivers/usb/host/ohci-omap.c | 61
drivers/usb/host/ohci-pci.c | 8
drivers/usb/host/ohci-pxa27x.c | 43
drivers/usb/host/ohci-q.c | 82
drivers/usb/host/ohci-sa1111.c | 30
drivers/usb/host/ohci.h | 25
drivers/usb/host/sl811-hcd.c | 347 +---
drivers/usb/host/sl811.h | 18
drivers/usb/host/uhci-debug.c | 36
drivers/usb/host/uhci-hcd.c | 182 --
drivers/usb/host/uhci-hcd.h | 28
drivers/usb/image/mdc800.c | 45
drivers/usb/image/microtek.c | 4
drivers/usb/input/aiptek.c | 6
drivers/usb/input/ati_remote.c | 19
drivers/usb/input/hid-core.c | 16
drivers/usb/input/hid-ff.c | 4
drivers/usb/input/hid-input.c | 469 ++---
drivers/usb/input/hid-lgff.c | 4
drivers/usb/input/hiddev.c | 6
drivers/usb/input/kbtab.c | 6
drivers/usb/input/mtouchusb.c | 6
drivers/usb/input/powermate.c | 13
drivers/usb/input/touchkitusb.c | 6
drivers/usb/input/usbkbd.c | 6
drivers/usb/input/usbmouse.c | 6
drivers/usb/input/wacom.c | 6
drivers/usb/input/xpad.c | 10
drivers/usb/media/Makefile | 2
drivers/usb/media/dabusb.c | 9
drivers/usb/media/ibmcam.c | 25
drivers/usb/media/konicawc.c | 18
drivers/usb/media/ov511.c | 20
drivers/usb/media/se401.c | 22
drivers/usb/media/sn9c102.h | 13
drivers/usb/media/sn9c102_core.c | 119 -
drivers/usb/media/sn9c102_hv7131d.c | 271 +++
drivers/usb/media/sn9c102_mi0343.c | 363 ++++
drivers/usb/media/sn9c102_pas106b.c | 45
drivers/usb/media/sn9c102_pas202bcb.c | 49
drivers/usb/media/sn9c102_sensor.h | 62
drivers/usb/media/sn9c102_tas5110c1b.c | 28
drivers/usb/media/sn9c102_tas5130d1b.c | 26
drivers/usb/media/stv680.c | 3
drivers/usb/media/ultracam.c | 16
drivers/usb/media/vicam.c | 6
drivers/usb/media/w9968cf.c | 8
drivers/usb/misc/Kconfig | 20
drivers/usb/misc/Makefile | 1
drivers/usb/misc/auerswald.c | 21
drivers/usb/misc/emi26.c | 8
drivers/usb/misc/emi62.c | 6
drivers/usb/misc/legousbtower.c | 11
drivers/usb/misc/usblcd.c | 15
drivers/usb/misc/usbtest.c | 25
drivers/usb/misc/uss720.c | 3
drivers/usb/net/catc.c | 5
drivers/usb/net/kaweth.c | 9
drivers/usb/serial/Kconfig | 23
drivers/usb/serial/Makefile | 2
drivers/usb/serial/belkin_sa.c | 4
drivers/usb/serial/ftdi_sio.c | 135 +
drivers/usb/serial/ftdi_sio.h | 51
drivers/usb/serial/garmin_gps.c | 1553 ++++++++++++++++++
drivers/usb/serial/io_edgeport.c | 4
drivers/usb/serial/io_ti.c | 4
drivers/usb/serial/keyspan.c | 24
drivers/usb/serial/keyspan_pda.c | 6
drivers/usb/serial/kobil_sct.c | 2
drivers/usb/serial/mct_u232.c | 157 -
drivers/usb/serial/ti_fw_3410.h | 885 ++++++++++
drivers/usb/serial/ti_fw_5052.h | 885 ++++++++++
drivers/usb/serial/ti_usb_3410_5052.c | 1866 +++++++++++++++++++++-
drivers/usb/serial/ti_usb_3410_5052.h | 224 ++
drivers/usb/serial/usb-serial.c | 29
drivers/usb/serial/usb-serial.h | 4
drivers/usb/serial/visor.c | 8
drivers/usb/serial/visor.h | 6
drivers/usb/storage/scsiglue.c | 2
drivers/usb/storage/transport.c | 16
drivers/usb/storage/unusual_devs.h | 122 -
drivers/usb/storage/usb.c | 20
drivers/usb/storage/usb.h | 1
drivers/usb/usb-skeleton.c | 2
drivers/w1/dscore.c | 2
fs/Makefile | 2
fs/debugfs/Makefile | 4
fs/debugfs/file.c | 262 +++
fs/debugfs/inode.c | 330 +++
fs/sysfs/bin.c | 27
fs/sysfs/dir.c | 2
fs/sysfs/mount.c | 34
fs/sysfs/sysfs.h | 3
include/linux/debugfs.h | 92 +
include/linux/device.h | 7
include/linux/if_ether.h | 3
include/linux/kobject.h | 2
include/linux/miscdevice.h | 7
include/linux/module.h | 19
include/linux/pci.h | 3
include/linux/sysfs.h | 6
include/linux/usb.h | 96 -
include/linux/usb_ch9.h | 27
init/Kconfig | 34
kernel/ksysfs.c | 3
kernel/module.c | 224 +-
kernel/params.c | 384 +---
lib/Kconfig.debug | 10
scripts/ver_linux | 2
sound/usb/usbaudio.c | 124 -
sound/usb/usbmidi.c | 16
sound/usb/usbmixer.c | 12
sound/usb/usx2y/usX2Yhwdep.c | 8
sound/usb/usx2y/usbusx2y.c | 22
sound/usb/usx2y/usbusx2yaudio.c | 24
218 files changed, 12619 insertions(+), 4089 deletions(-)
-----
<eolson:mit.edu>:
o ftdi_sio: Add sysfs attributes for event character and latency
o usb-serial: add tty_hangup on disconnect
<jlamanna:gmail.com>:
o USB: ov511.c - vfree() checking cleanups
Adrian Bunk:
o select HOTPLUG
Al Borchers:
o USB: serial driver for TI USB 3410/5052 chips (2/3)
o USB: serial driver for TI USB 3410/5052 chips (1/3)
o USB: serial driver for TI USB 3410/5052 chips (3/3)
Alan Stern:
o USB: Another hub driver cleanup [13/13]
o USB: Hub driver cleanups [12/13]
o USB: Hub driver: several bug fixes and simplifications [11/13]
o USB: Create usb_hcd structures within usbcore [6/13]
o USB: Create usb_hcd structures within usbcore [5/13]
o USB: Create usb_hcd structures within usbcore [4/13]
o USB: Create usb_hcd structures within usbcore [3/13]
o USB: Create usb_hcd structures within usbcore [2/13]
o USB: Create usb_hcd structures within usbcore [1/13]
o USB: dummy_hcd: update to match the new endpoint changes
Andrew Morton:
o debugfs-typo-fix
Chris Wright:
o sysfs: Allocate sysfs_dirent structures from their own slab
Dave Jones:
o driver core: Fix up vesafb failure probing
David Brownell:
o USB: ehci "hc died" on startup (chip bug workaround)
o USB: ohci diagnostic tweak
o USB: usb makefile tweaks
o USB: definitions for USB2 debug device, debug port
o USB: minor usb doc/comment fixes
o Driver Core: handle bridged platform bus segments
o USB: fix serial gadget oops during enumeration
o USB: fix Scheduling while atomic warning when resuming
o USB: ohci build tweaks
o USB: Hub driver: improve error checking and retries [10/13]
o USB: gadget kconfig doc updates
o USB: EHCI periodic schedule tree
o USB: EHCI "park" mode disabled
o USB: HCDs and per-device state (16/15)
o USB: better messages for "no-IRQ" cases (15/15)
o USB: UHCI and HCD API change (14/15)
o USB: OHCI and HCD API changes (13/15)
o USB: EHCI and HCD API updates (12/15)
o USB: maintain usb_host_endpoint.urb_list (11/15)
o USB: remove some now-unused HCD infrastructure (10/15)
o USB: HCD/usb_bus interface cleanup (9/15)
o USB: usbtest and usb_dev->epmaxpacket (8/15)
o USB: EHCI HCD and usb_dev->epmaxpacket (7/15)
o USB: CRIS HCD and usb_dev->epmaxpacket (6/15)
o USB: auerswald and usb_dev->ep[] (5/15)
o USB: ALSA and usb_dev->ep[] (4/15)
o USB: usbfs changes for usb_dev->ep[] (3/15)
o USB: usbcore changes for usb_dev->ep[](2/15)
o USB: usb_dev->ep[] not usb_dev->epmaxpacket (1/15)
o USB: update drivers/usb/README
Duncan Sands:
o usb atm: macro consolidation, fixes debugging problem
Ed L. Cashin:
o rename ETH_P_AOE
o add ATA over Ethernet driver
Greg Kroah-Hartman:
o add feature-removal-schedule.txt documentation
o Fix up udev url in Documentation/Changes file
o debugfs: add /sys/kernel/debug mount point for people to mount debugfs on
o sysfs: export the /sys/kernel subsystem for people to use
o USB: explicitly mark the endianness of some visor data fields
o USB Gadget: fix up simple sparse warnings (NULL stuff) in dummy_hcd.c driver
o USB: change wMaxPacketSize field in struct usb_config_descriptor to be __le16
o USB: change wTotalLength field in struct usb_config_descriptor to be __le16
o USB: convert the idVendor, idProduct, bcdDevice and bcdUSB fields to __le16
o USB: change warning level in ftdi_sio driver of a debug message
o USB: fix up some sparse warnings in the new garmin_gps driver
o AOE: fix up sparse warnings and get rid of a kmalloc in the aoe driver
o USB: convert uhci-hcd driver to use debugfs
o debugfs: add debugfs
o USB: delete the tiglusb driver as it's not needed
o USB: fix sparse and compiler warnings in ti_usb_3410_5052.c
o misc: remove miscdevice.h from pci hotplug drivers as they do not need it
o Documentation: fix some grammer in the stable_api_nonsense.txt file
o misc: remove device.h #include from miscdevice.h
Hermann Kneissel:
o Re: garmin gps driver patch 0.23
Jesper Juhl:
o add printing of udev version to scripts/ver_linux
Jesse Barnes:
o fix oops when reading resourceN files in sysfs
o PCI: add legacy resources to sysfs for pci busses
o driver core: allow struct bin_attributes in class devices
o PCI: export PCI resources in sysfs
o sysfs: add mmap support to struct bin_attribute files
Kumar Gala:
o Driver Core: Add platform_get_resource_byname & platform_get_resource_byirq
Luca Risolia:
o USB: SN9C10x driver updates
Matthew Dharm:
o USB Storage: Increase Genesys delay
o USB Storage: support 'bulk32' devices
Oliver Neukum:
o USB: another workaround for cdc-acm
o USB: additional device id for kaweth driver
Pete Zaitcev:
o Clean mct_u232 in 2.6.10-rc2
Phil Dibowitz:
o USB Storage: unusual_devs: prolific atapi controler
o USB Storage: unusual_devs: prolific atapi controler
o USB Storage: Remove old XLATE-only entries from unusual_devs.h
o USB Storage: Remove MODE_XLATE flag from unusual_devs.h
Randy Dunlap:
o add cpufreq info to Documentation/feature-removal-schedule.txt
Robert Love:
o add class_device to miscdevice
Tejun Heo:
o module sysfs: module parameters reimplemented using attr group
o module sysfs: sections attr reimplemented using attr group
o module sysfs: expand module_attribute methods
o module sysfs: make module.mkobj inline
ChangeSet 1.2251, 2005/01/07 15:19:51-08:00, [email protected]
Fix up udev url in Documentation/Changes file
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/Changes | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes 2005-01-07 15:33:42 -08:00
+++ b/Documentation/Changes 2005-01-07 15:33:42 -08:00
@@ -223,10 +223,10 @@
version v0.99.0 or higher. Running old versions may cause problems
with programs using shared memory.
-Udev
+udev
----
-Udev is a userspace application for populating /dev dynamically with
-only entries for devices actually present. Udev replaces devfs.
+udev is a userspace application for populating /dev dynamically with
+only entries for devices actually present. udev replaces devfs.
Networking
==========
@@ -373,9 +373,9 @@
----------
o <http://powertweak.sourceforge.net/>
-Udev
+udev
----
-o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>
+o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
Networking
**********
ChangeSet 1.1938.446.44, 2004/12/20 14:20:07-08:00, [email protected]
[PATCH] USB: Create usb_hcd structures within usbcore [5/13]
This patch alters the non-PCI OHCI drivers, removing the routines that
allocate the hcd structures and introducing inline functions to convert
safely between the public and private hcd structures.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ohci-lh7a404.c | 43 +++-----
drivers/usb/host/ohci-omap.c | 60 +++++-------
drivers/usb/host/ohci-pxa27x.c | 41 +++-----
drivers/usb/host/ohci-sa1111.c | 28 ++---
drivers/usb/host/sl811-hcd.c | 198 +++++++++++++++++++++-------------------
drivers/usb/host/sl811.h | 8 +
6 files changed, 184 insertions(+), 194 deletions(-)
diff -Nru a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
--- a/drivers/usb/host/ohci-lh7a404.c 2005-01-07 15:43:22 -08:00
+++ b/drivers/usb/host/ohci-lh7a404.c 2005-01-07 15:43:22 -08:00
@@ -106,23 +106,22 @@
retval = -ENOMEM;
goto err1;
}
-
- hcd = driver->hcd_alloc ();
- if (hcd == NULL){
- pr_debug ("hcd_alloc failed");
+ if(dev->resource[1].flags != IORESOURCE_IRQ){
+ pr_debug ("resource[1] is not IORESOURCE_IRQ");
retval = -ENOMEM;
goto err1;
}
+
- if(dev->resource[1].flags != IORESOURCE_IRQ){
- pr_debug ("resource[1] is not IORESOURCE_IRQ");
+ hcd = usb_create_hcd (driver);
+ if (hcd == NULL){
+ pr_debug ("hcd_alloc failed");
retval = -ENOMEM;
goto err1;
}
+ ohci_hcd_init(hcd_to_ohci(hcd));
- hcd->driver = (struct hc_driver *) driver;
- hcd->description = driver->description;
hcd->irq = dev->resource[1].start;
hcd->regs = addr;
hcd->self.controller = &dev->dev;
@@ -130,27 +129,21 @@
retval = hcd_buffer_create (hcd);
if (retval != 0) {
pr_debug ("pool alloc fail");
- goto err1;
+ goto err2;
}
retval = request_irq (hcd->irq, usb_hcd_lh7a404_hcim_irq, SA_INTERRUPT,
- hcd->description, hcd);
+ hcd->driver->description, hcd);
if (retval != 0) {
pr_debug("request_irq failed");
retval = -EBUSY;
- goto err2;
+ goto err3;
}
pr_debug ("%s (LH7A404) at 0x%p, irq %d",
- hcd->description, hcd->regs, hcd->irq);
+ hcd->driver->description, hcd->regs, hcd->irq);
- usb_bus_init (&hcd->self);
- hcd->self.op = &usb_hcd_operations;
- hcd->self.release = &usb_hcd_release;
- hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = "lh7a404";
- hcd->product_desc = "LH7A404 OHCI";
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
@@ -162,10 +155,11 @@
*hcd_out = hcd;
return 0;
- err2:
+ err3:
hcd_buffer_destroy (hcd);
+ err2:
+ usb_put_hcd(hcd);
err1:
- kfree(hcd);
lh7a404_stop_hc(dev);
release_mem_region(dev->resource[0].start,
dev->resource[0].end
@@ -226,7 +220,7 @@
return ret;
if ((ret = ohci_run (ohci)) < 0) {
- err ("can't start %s", ohci->hcd.self.bus_name);
+ err ("can't start %s", hcd->self.bus_name);
ohci_stop (hcd);
return ret;
}
@@ -237,6 +231,8 @@
static const struct hc_driver ohci_lh7a404_hc_driver = {
.description = hcd_name,
+ .product_desc = "LH7A404 OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
/*
* generic hardware linkage
@@ -253,11 +249,6 @@
/* resume: ohci_lh7a404_resume, -- tbd */
#endif /*CONFIG_PM*/
.stop = ohci_stop,
-
- /*
- * memory lifecycle (except per-request)
- */
- .hcd_alloc = ohci_hcd_alloc,
/*
* managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
--- a/drivers/usb/host/ohci-omap.c 2005-01-07 15:43:22 -08:00
+++ b/drivers/usb/host/ohci-omap.c 2005-01-07 15:43:22 -08:00
@@ -157,7 +157,7 @@
static void start_hnp(struct ohci_hcd *ohci)
{
- const unsigned port = ohci->hcd.self.otg_port - 1;
+ const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1;
unsigned long flags;
otg_start_hnp(ohci->transceiver);
@@ -181,7 +181,7 @@
dev_dbg(&pdev->dev, "starting USB Controller\n");
if (config->otg) {
- ohci->hcd.self.otg_port = config->otg;
+ ohci_to_hcd(ohci)->self.otg_port = config->otg;
/* default/minimum OTG power budget: 8 mA */
ohci->power_budget = 8;
}
@@ -198,7 +198,7 @@
ohci->transceiver = otg_get_transceiver();
if (ohci->transceiver) {
int status = otg_set_host(ohci->transceiver,
- &ohci->hcd.self);
+ &ohci_to_hcd(ohci)->self);
dev_dbg(&pdev->dev, "init %s transceiver, status %d\n",
ohci->transceiver->label, status);
if (status) {
@@ -293,7 +293,7 @@
return -EBUSY;
}
- hcd = driver->hcd_alloc ();
+ hcd = usb_create_hcd (driver);
if (hcd == NULL){
dev_dbg(&pdev->dev, "hcd_alloc failed\n");
retval = -ENOMEM;
@@ -301,40 +301,33 @@
}
dev_set_drvdata(&pdev->dev, hcd);
ohci = hcd_to_ohci(hcd);
+ ohci_hcd_init(ohci);
- hcd->driver = (struct hc_driver *) driver;
- hcd->description = driver->description;
hcd->irq = pdev->resource[1].start;
hcd->regs = (void *)pdev->resource[0].start;
hcd->self.controller = &pdev->dev;
retval = omap_start_hc(ohci, pdev);
if (retval < 0)
- goto err1;
+ goto err2;
retval = hcd_buffer_create (hcd);
if (retval != 0) {
dev_dbg(&pdev->dev, "pool alloc fail\n");
- goto err1;
+ goto err2;
}
retval = request_irq (hcd->irq, usb_hcd_irq,
- SA_INTERRUPT, hcd->description, hcd);
+ SA_INTERRUPT, hcd->driver->description, hcd);
if (retval != 0) {
dev_dbg(&pdev->dev, "request_irq failed\n");
retval = -EBUSY;
- goto err2;
+ goto err3;
}
dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
- usb_bus_init (&hcd->self);
- hcd->self.op = &usb_hcd_operations;
- hcd->self.release = &usb_hcd_release;
- hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = pdev->dev.bus_id;
- hcd->product_desc = "OMAP OHCI";
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
@@ -345,16 +338,17 @@
return 0;
- err2:
+ err3:
hcd_buffer_destroy (hcd);
+ err2:
+ dev_set_drvdata(&pdev->dev, NULL);
+ usb_put_hcd(hcd);
err1:
- kfree(hcd);
omap_stop_hc(pdev);
release_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1);
- dev_set_drvdata(&pdev->dev, 0);
return retval;
}
@@ -418,7 +412,7 @@
writel(OHCI_CTRL_RWC, &ohci->regs->control);
if ((ret = ohci_run (ohci)) < 0) {
- err ("can't start %s", ohci->hcd.self.bus_name);
+ err ("can't start %s", hcd->self.bus_name);
ohci_stop (hcd);
return ret;
}
@@ -429,6 +423,8 @@
static const struct hc_driver ohci_omap_hc_driver = {
.description = hcd_name,
+ .product_desc = "OMAP OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
/*
* generic hardware linkage
@@ -443,11 +439,6 @@
.stop = ohci_stop,
/*
- * memory lifecycle (except per-request)
- */
- .hcd_alloc = ohci_hcd_alloc,
-
- /*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ohci_urb_enqueue,
@@ -512,19 +503,20 @@
return 0;
dev_dbg(dev, "suspend to %d\n", state);
- down(&ohci->hcd.self.root_hub->serialize);
- status = ohci_hub_suspend(&ohci->hcd);
+ down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+ status = ohci_hub_suspend(ohci_to_hcd(ohci));
if (status == 0) {
if (state >= 4) {
/* power off + reset */
OTG_SYSCON_2_REG &= ~UHOST_EN;
- ohci->hcd.self.root_hub->state = USB_STATE_SUSPENDED;
+ ohci_to_hcd(ohci)->self.root_hub->state =
+ USB_STATE_SUSPENDED;
state = 4;
}
- ohci->hcd.state = HCD_STATE_SUSPENDED;
+ ohci_to_hcd(ohci)->state = HCD_STATE_SUSPENDED;
dev->power.power_state = state;
}
- up(&ohci->hcd.self.root_hub->serialize);
+ up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
return status;
}
@@ -546,11 +538,11 @@
dev_dbg(dev, "resume from %d\n", dev->power.power_state);
#ifdef CONFIG_USB_SUSPEND
/* get extra cleanup even if remote wakeup isn't in use */
- status = usb_resume_device(ohci->hcd.self.root_hub);
+ status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
#else
- down(&ohci->hcd.self.root_hub->serialize);
- status = ohci_hub_resume(&ohci->hcd);
- up(&ohci->hcd.self.root_hub->serialize);
+ down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+ status = ohci_hub_resume(ohci_to_hcd(ohci));
+ up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
#endif
if (status == 0)
dev->power.power_state = 0;
diff -Nru a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
--- a/drivers/usb/host/ohci-pxa27x.c 2005-01-07 15:43:22 -08:00
+++ b/drivers/usb/host/ohci-pxa27x.c 2005-01-07 15:43:22 -08:00
@@ -206,21 +206,20 @@
goto err1;
}
- hcd = driver->hcd_alloc ();
- if (hcd == NULL){
- pr_debug ("hcd_alloc failed");
+ if(dev->resource[1].flags != IORESOURCE_IRQ){
+ pr_debug ("resource[1] is not IORESOURCE_IRQ");
retval = -ENOMEM;
goto err1;
}
- if(dev->resource[1].flags != IORESOURCE_IRQ){
- pr_debug ("resource[1] is not IORESOURCE_IRQ");
+ hcd = usb_create_hcd (driver);
+ if (hcd == NULL){
+ pr_debug ("hcd_alloc failed");
retval = -ENOMEM;
goto err1;
}
+ ohci_hcd_init(hcd_to_ohci(hcd));
- hcd->driver = (struct hc_driver *) driver;
- hcd->description = driver->description;
hcd->irq = dev->resource[1].start;
hcd->regs = addr;
hcd->self.controller = &dev->dev;
@@ -228,27 +227,21 @@
retval = hcd_buffer_create (hcd);
if (retval != 0) {
pr_debug ("pool alloc fail");
- goto err1;
+ goto err2;
}
retval = request_irq (hcd->irq, usb_hcd_irq, SA_INTERRUPT,
- hcd->description, hcd);
+ hcd->driver->description, hcd);
if (retval != 0) {
pr_debug("request_irq(%d) failed with retval %d\n",hcd->irq,retval);
retval = -EBUSY;
- goto err2;
+ goto err3;
}
pr_debug ("%s (pxa27x) at 0x%p, irq %d",
- hcd->description, hcd->regs, hcd->irq);
+ hcd->driver->description, hcd->regs, hcd->irq);
- usb_bus_init (&hcd->self);
- hcd->self.op = &usb_hcd_operations;
- hcd->self.release = &usb_hcd_release;
- hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = "pxa27x";
- hcd->product_desc = "PXA27x OHCI";
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0) {
@@ -259,10 +252,11 @@
*hcd_out = hcd;
return 0;
- err2:
+ err3:
hcd_buffer_destroy (hcd);
+ err2:
+ usb_put_hcd(hcd);
err1:
- kfree(hcd);
pxa27x_stop_hc(dev);
release_mem_region(dev->resource[0].start,
dev->resource[0].end
@@ -323,7 +317,7 @@
return ret;
if ((ret = ohci_run (ohci)) < 0) {
- err ("can't start %s", ohci->hcd.self.bus_name);
+ err ("can't start %s", hcd->self.bus_name);
ohci_stop (hcd);
return ret;
}
@@ -335,6 +329,8 @@
static const struct hc_driver ohci_pxa27x_hc_driver = {
.description = hcd_name,
+ .product_desc = "PXA27x OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
/*
* generic hardware linkage
@@ -347,11 +343,6 @@
*/
.start = ohci_pxa27x_start,
.stop = ohci_stop,
-
- /*
- * memory lifecycle (except per-request)
- */
- .hcd_alloc = ohci_hcd_alloc,
/*
* managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
--- a/drivers/usb/host/ohci-sa1111.c 2005-01-07 15:43:22 -08:00
+++ b/drivers/usb/host/ohci-sa1111.c 2005-01-07 15:43:22 -08:00
@@ -162,15 +162,14 @@
sa1111_start_hc(dev);
- hcd = driver->hcd_alloc ();
+ hcd = usb_create_hcd (driver);
if (hcd == NULL){
dbg ("hcd_alloc failed");
retval = -ENOMEM;
goto err1;
}
+ ohci_hcd_init(hcd_to_ohci(hcd));
- hcd->driver = (struct hc_driver *) driver;
- hcd->description = driver->description;
hcd->irq = dev->irq[1];
hcd->regs = dev->mapbase;
hcd->self.controller = &dev->dev;
@@ -178,27 +177,21 @@
retval = hcd_buffer_create (hcd);
if (retval != 0) {
dbg ("pool alloc fail");
- goto err1;
+ goto err2;
}
retval = request_irq (hcd->irq, usb_hcd_sa1111_hcim_irq, SA_INTERRUPT,
- hcd->description, hcd);
+ hcd->driver->description, hcd);
if (retval != 0) {
dbg("request_irq failed");
retval = -EBUSY;
- goto err2;
+ goto err3;
}
info ("%s (SA-1111) at 0x%p, irq %d\n",
- hcd->description, hcd->regs, hcd->irq);
+ hcd->driver->description, hcd->regs, hcd->irq);
- usb_bus_init (&hcd->self);
- hcd->self.op = &usb_hcd_operations;
- hcd->self.release = &usb_hcd_release;
- hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = "sa1111";
- hcd->product_desc = "SA-1111 OHCI";
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
@@ -210,10 +203,11 @@
*hcd_out = hcd;
return 0;
- err2:
+ err3:
hcd_buffer_destroy (hcd);
+ err2:
+ usb_put_hcd(hcd);
err1:
- kfree(hcd);
sa1111_stop_hc(dev);
release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
return retval;
@@ -269,7 +263,7 @@
return ret;
if ((ret = ohci_run (ohci)) < 0) {
- err ("can't start %s", ohci->hcd.self.bus_name);
+ err ("can't start %s", hcd->self.bus_name);
ohci_stop (hcd);
return ret;
}
@@ -280,6 +274,8 @@
static const struct hc_driver ohci_sa1111_hc_driver = {
.description = hcd_name,
+ .product_desc = "SA-1111 OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
/*
* generic hardware linkage
diff -Nru a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
--- a/drivers/usb/host/sl811-hcd.c 2005-01-07 15:43:22 -08:00
+++ b/drivers/usb/host/sl811-hcd.c 2005-01-07 15:43:22 -08:00
@@ -90,10 +90,12 @@
/*-------------------------------------------------------------------------*/
-static irqreturn_t sl811h_irq(int irq, void *_sl811, struct pt_regs *regs);
+static irqreturn_t sl811h_irq(int irq, void *_hcd, struct pt_regs *regs);
static void port_power(struct sl811 *sl811, int is_on)
{
+ struct usb_hcd *hcd = sl811_to_hcd(sl811);
+
/* hub is inactive unless the port is powered */
if (is_on) {
if (sl811->port1 & (1 << USB_PORT_FEAT_POWER))
@@ -101,12 +103,12 @@
sl811->port1 = (1 << USB_PORT_FEAT_POWER);
sl811->irq_enable = SL11H_INTMASK_INSRMV;
- sl811->hcd.self.controller->power.power_state = PM_SUSPEND_ON;
+ hcd->self.controller->power.power_state = PM_SUSPEND_ON;
} else {
sl811->port1 = 0;
sl811->irq_enable = 0;
- sl811->hcd.state = USB_STATE_HALT;
- sl811->hcd.self.controller->power.power_state = PM_SUSPEND_DISK;
+ hcd->state = USB_STATE_HALT;
+ hcd->self.controller->power.power_state = PM_SUSPEND_DISK;
}
sl811->ctrl1 = 0;
sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
@@ -115,12 +117,12 @@
if (sl811->board && sl811->board->port_power) {
/* switch VBUS, at 500mA unless hub power budget gets set */
DBG("power %s\n", is_on ? "on" : "off");
- sl811->board->port_power(sl811->hcd.self.controller, is_on);
+ sl811->board->port_power(hcd->self.controller, is_on);
}
/* reset as thoroughly as we can */
if (sl811->board && sl811->board->reset)
- sl811->board->reset(sl811->hcd.self.controller);
+ sl811->board->reset(hcd->self.controller);
sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1);
@@ -446,7 +448,7 @@
spin_unlock(&urb->lock);
spin_unlock(&sl811->lock);
- usb_hcd_giveback_urb(&sl811->hcd, urb, regs);
+ usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, regs);
spin_lock(&sl811->lock);
/* leave active endpoints in the schedule */
@@ -475,7 +477,7 @@
}
ep->branch = PERIODIC_SIZE;
sl811->periodic_count--;
- hcd_to_bus(&sl811->hcd)->bandwidth_allocated
+ sl811_to_hcd(sl811)->self.bandwidth_allocated
-= ep->load / ep->period;
if (ep == sl811->next_periodic)
sl811->next_periodic = ep->next;
@@ -643,9 +645,10 @@
return irqstat;
}
-static irqreturn_t sl811h_irq(int irq, void *_sl811, struct pt_regs *regs)
+static irqreturn_t sl811h_irq(int irq, void *_hcd, struct pt_regs *regs)
{
- struct sl811 *sl811 = _sl811;
+ struct usb_hcd *hcd = _hcd;
+ struct sl811 *sl811 = hcd_to_sl811(hcd);
u8 irqstat;
irqreturn_t ret = IRQ_NONE;
unsigned retries = 5;
@@ -757,7 +760,7 @@
if (sl811->port1 & (1 << USB_PORT_FEAT_ENABLE))
start_transfer(sl811);
ret = IRQ_HANDLED;
- sl811->hcd.saw_irq = 1;
+ hcd->saw_irq = 1;
if (retries--)
goto retry;
}
@@ -835,7 +838,7 @@
/* don't submit to a dead or disabled port */
if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE))
- || !HCD_IS_RUNNING(sl811->hcd.state)) {
+ || !HCD_IS_RUNNING(hcd->state)) {
retval = -ENODEV;
goto fail;
}
@@ -937,8 +940,7 @@
sl811->load[i] += ep->load;
}
sl811->periodic_count++;
- hcd_to_bus(&sl811->hcd)->bandwidth_allocated
- += ep->load / ep->period;
+ hcd->self.bandwidth_allocated += ep->load / ep->period;
sofirq_on(sl811);
}
@@ -1396,7 +1398,7 @@
unsigned i;
seq_printf(s, "%s\n%s version %s\nportstatus[1] = %08x\n",
- sl811->hcd.product_desc,
+ sl811_to_hcd(sl811)->product_desc,
hcd_name, DRIVER_VERSION,
sl811->port1);
@@ -1544,7 +1546,7 @@
struct sl811 *sl811 = hcd_to_sl811(hcd);
unsigned long flags;
- del_timer_sync(&sl811->hcd.rh_timer);
+ del_timer_sync(&hcd->rh_timer);
spin_lock_irqsave(&sl811->lock, flags);
port_power(sl811, 0);
@@ -1559,7 +1561,7 @@
/* chip has been reset, VBUS power is off */
- udev = usb_alloc_dev(NULL, &sl811->hcd.self, 0);
+ udev = usb_alloc_dev(NULL, &hcd->self, 0);
if (!udev)
return -ENOMEM;
@@ -1567,9 +1569,9 @@
hcd->state = USB_STATE_RUNNING;
if (sl811->board)
- sl811->hcd.can_wakeup = sl811->board->can_wakeup;
+ hcd->can_wakeup = sl811->board->can_wakeup;
- if (hcd_register_root(udev, &sl811->hcd) != 0) {
+ if (hcd_register_root(udev, hcd) != 0) {
usb_put_dev(udev);
sl811h_stop(hcd);
return -ENODEV;
@@ -1585,6 +1587,7 @@
static struct hc_driver sl811h_hc_driver = {
.description = hcd_name,
+ .hcd_priv_size = sizeof(struct sl811),
/*
* generic hardware linkage
@@ -1618,35 +1621,32 @@
sl811h_remove(struct device *dev)
{
struct sl811 *sl811 = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = sl811_to_hcd(sl811);
struct platform_device *pdev;
struct resource *res;
pdev = container_of(dev, struct platform_device, dev);
- if (HCD_IS_RUNNING(sl811->hcd.state))
- sl811->hcd.state = USB_STATE_QUIESCING;
+ if (HCD_IS_RUNNING(hcd->state))
+ hcd->state = USB_STATE_QUIESCING;
- usb_disconnect(&sl811->hcd.self.root_hub);
+ usb_disconnect(&hcd->self.root_hub);
remove_debug_file(sl811);
- sl811h_stop(&sl811->hcd);
+ sl811h_stop(hcd);
- if (!list_empty(&sl811->hcd.self.bus_list))
- usb_deregister_bus(&sl811->hcd.self);
+ usb_deregister_bus(&hcd->self);
- if (sl811->hcd.irq >= 0)
- free_irq(sl811->hcd.irq, sl811);
+ free_irq(hcd->irq, hcd);
- if (sl811->data_reg)
- iounmap(sl811->data_reg);
+ iounmap(sl811->data_reg);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
release_mem_region(res->start, 1);
- if (sl811->addr_reg)
- iounmap(sl811->addr_reg);
+ iounmap(sl811->addr_reg);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, 1);
- kfree(sl811);
+ usb_put_hcd(hcd);
return 0;
}
@@ -1655,13 +1655,15 @@
static int __init
sl811h_probe(struct device *dev)
{
+ struct usb_hcd *hcd;
struct sl811 *sl811;
struct platform_device *pdev;
struct resource *addr, *data;
int irq;
- int status;
+ void __iomem *addr_reg;
+ void __iomem *data_reg;
+ int retval;
u8 tmp;
- unsigned long flags;
/* basic sanity checks first. board-specific init logic should
* have initialized these three resources and probably board
@@ -1684,32 +1686,39 @@
return -EINVAL;
}
- if (!request_mem_region(addr->start, 1, hcd_name))
- return -EBUSY;
+ if (!request_mem_region(addr->start, 1, hcd_name)) {
+ retval = -EBUSY;
+ goto err1;
+ }
+ addr_reg = ioremap(addr->start, resource_len(addr));
+ if (addr_reg == NULL) {
+ retval = -ENOMEM;
+ goto err2;
+ }
+
if (!request_mem_region(data->start, 1, hcd_name)) {
- release_mem_region(addr->start, 1);
- return -EBUSY;
+ retval = -EBUSY;
+ goto err3;
+ }
+ data_reg = ioremap(data->start, resource_len(addr));
+ if (data_reg == NULL) {
+ retval = -ENOMEM;
+ goto err4;
}
/* allocate and initialize hcd */
- sl811 = kcalloc(1, sizeof *sl811, GFP_KERNEL);
- if (!sl811)
- return 0;
+ hcd = usb_create_hcd(&sl811h_hc_driver);
+ if (!hcd) {
+ retval = 0;
+ goto err5;
+ }
+ sl811 = hcd_to_sl811(hcd);
dev_set_drvdata(dev, sl811);
- usb_bus_init(&sl811->hcd.self);
- sl811->hcd.self.controller = dev;
- sl811->hcd.self.bus_name = dev->bus_id;
- sl811->hcd.self.op = &usb_hcd_operations;
- sl811->hcd.self.hcpriv = sl811;
-
- sl811->hcd.self.release = &usb_hcd_release;
-
- sl811->hcd.description = sl811h_hc_driver.description;
- init_timer(&sl811->hcd.rh_timer);
- sl811->hcd.driver = &sl811h_hc_driver;
- sl811->hcd.irq = -1;
- sl811->hcd.state = USB_STATE_HALT;
+ hcd->self.controller = dev;
+ hcd->self.bus_name = dev->bus_id;
+ hcd->irq = irq;
+ hcd->regs = addr_reg;
spin_lock_init(&sl811->lock);
INIT_LIST_HEAD(&sl811->async);
@@ -1717,36 +1726,27 @@
init_timer(&sl811->timer);
sl811->timer.function = sl811h_timer;
sl811->timer.data = (unsigned long) sl811;
+ sl811->addr_reg = addr_reg;
+ sl811->data_reg = data_reg;
- sl811->addr_reg = ioremap(addr->start, resource_len(addr));
- if (sl811->addr_reg == NULL) {
- status = -ENOMEM;
- goto fail;
- }
- sl811->data_reg = ioremap(data->start, resource_len(addr));
- if (sl811->data_reg == NULL) {
- status = -ENOMEM;
- goto fail;
- }
-
- spin_lock_irqsave(&sl811->lock, flags);
+ spin_lock_irq(&sl811->lock);
port_power(sl811, 0);
- spin_unlock_irqrestore(&sl811->lock, flags);
+ spin_unlock_irq(&sl811->lock);
msleep(200);
tmp = sl811_read(sl811, SL11H_HWREVREG);
switch (tmp >> 4) {
case 1:
- sl811->hcd.product_desc = "SL811HS v1.2";
+ hcd->product_desc = "SL811HS v1.2";
break;
case 2:
- sl811->hcd.product_desc = "SL811HS v1.5";
+ hcd->product_desc = "SL811HS v1.5";
break;
default:
/* reject case 0, SL11S is less functional */
DBG("chiprev %02x\n", tmp);
- status = -ENXIO;
- goto fail;
+ retval = -ENXIO;
+ goto err6;
}
/* sl811s would need a different handler for this irq */
@@ -1754,25 +1754,41 @@
/* Cypress docs say the IRQ is IRQT_HIGH ... */
set_irq_type(irq, IRQT_RISING);
#endif
- status = request_irq(irq, sl811h_irq, SA_INTERRUPT, hcd_name, sl811);
- if (status < 0)
- goto fail;
- sl811->hcd.irq = irq;
+ retval = request_irq(irq, sl811h_irq, SA_INTERRUPT,
+ hcd->driver->description, hcd);
+ if (retval != 0)
+ goto err6;
+
+ INFO("%s, irq %d\n", hcd->product_desc, irq);
+
+ retval = usb_register_bus(&hcd->self);
+ if (retval < 0)
+ goto err7;
+
+ retval = sl811h_start(hcd);
+ if (retval < 0)
+ goto err8;
- INFO("%s, irq %d\n", sl811->hcd.product_desc, irq);
+ create_debug_file(sl811);
+ return 0;
- status = usb_register_bus(&sl811->hcd.self);
- if (status < 0)
- goto fail;
- status = sl811h_start(&sl811->hcd);
- if (status == 0) {
- create_debug_file(sl811);
- return 0;
- }
-fail:
- sl811h_remove(dev);
- DBG("init error, %d\n", status);
- return status;
+ err8:
+ usb_deregister_bus(&hcd->self);
+ err7:
+ free_irq(hcd->irq, hcd);
+ err6:
+ usb_put_hcd(hcd);
+ err5:
+ iounmap(data_reg);
+ err4:
+ release_mem_region(data->start, 1);
+ err3:
+ iounmap(addr_reg);
+ err2:
+ release_mem_region(addr->start, 1);
+ err1:
+ DBG("init error, %d\n", retval);
+ return retval;
}
#ifdef CONFIG_PM
@@ -1792,7 +1808,7 @@
return retval;
if (state <= PM_SUSPEND_MEM)
- retval = sl811h_hub_suspend(&sl811->hcd);
+ retval = sl811h_hub_suspend(sl811_to_hcd(sl811));
else
port_power(sl811, 0);
if (retval == 0)
@@ -1812,14 +1828,14 @@
* let's assume it'd only be powered to enable remote wakeup.
*/
if (dev->power.power_state > PM_SUSPEND_MEM
- || !sl811->hcd.can_wakeup) {
+ || !sl811_to_hcd(sl811)->can_wakeup) {
sl811->port1 = 0;
port_power(sl811, 1);
return 0;
}
dev->power.power_state = PM_SUSPEND_ON;
- return sl811h_hub_resume(&sl811->hcd);
+ return sl811h_hub_resume(sl811_to_hcd(sl811));
}
#else
diff -Nru a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h
--- a/drivers/usb/host/sl811.h 2005-01-07 15:43:22 -08:00
+++ b/drivers/usb/host/sl811.h 2005-01-07 15:43:22 -08:00
@@ -118,7 +118,6 @@
#define PERIODIC_SIZE (1 << LOG2_PERIODIC_SIZE)
struct sl811 {
- struct usb_hcd hcd;
spinlock_t lock;
void __iomem *addr_reg;
void __iomem *data_reg;
@@ -158,7 +157,12 @@
static inline struct sl811 *hcd_to_sl811(struct usb_hcd *hcd)
{
- return container_of(hcd, struct sl811, hcd);
+ return (struct sl811 *) (hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *sl811_to_hcd(struct sl811 *sl811)
+{
+ return container_of((void *) sl811, struct usb_hcd, hcd_priv);
}
struct sl811h_ep {
ChangeSet 1.1938.446.49, 2004/12/20 15:01:26-08:00, [email protected]
[PATCH] USB: Another hub driver cleanup [13/13]
This patch does some more cleaning up of the hub driver. The idea is to
use 1-based port numbers everywhere, in accordance with the usage of the
USB spec, the values stored in USB messages, and the values printed in the
system log. The downside is that we have to subtract 1 to index the
children[] array, but that's a lot better than all the additions of 1 that
were there before. To emphasize the nature of this change, I renamed the
"port" local variable to "port1" every place it is used.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hub.c | 280 ++++++++++++++++++++++++-------------------------
drivers/usb/core/usb.c | 8 -
2 files changed, 146 insertions(+), 142 deletions(-)
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:42:44 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:42:44 -08:00
@@ -128,19 +128,21 @@
/*
* USB 2.0 spec Section 11.24.2.2
*/
-static int clear_port_feature(struct usb_device *hdev, int port, int feature)
+static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
{
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
+ USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
+ NULL, 0, HZ);
}
/*
* USB 2.0 spec Section 11.24.2.13
*/
-static int set_port_feature(struct usb_device *hdev, int port, int feature)
+static int set_port_feature(struct usb_device *hdev, int port1, int feature)
{
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
- USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
+ USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1,
+ NULL, 0, HZ);
}
/*
@@ -149,16 +151,16 @@
*/
static void set_port_led(
struct usb_hub *hub,
- int port,
+ int port1,
int selector
)
{
- int status = set_port_feature(hub->hdev, (selector << 8) | port,
+ int status = set_port_feature(hub->hdev, (selector << 8) | port1,
USB_PORT_FEAT_INDICATOR);
if (status < 0)
dev_dbg (hub->intfdev,
"port %d indicator %s status %d\n",
- port,
+ port1,
({ char *s; switch (selector) {
case HUB_LED_AMBER: s = "amber"; break;
case HUB_LED_GREEN: s = "green"; break;
@@ -263,14 +265,14 @@
/*
* USB 2.0 spec Section 11.24.2.7
*/
-static int get_port_status(struct usb_device *hdev, int port,
+static int get_port_status(struct usb_device *hdev, int port1,
struct usb_port_status *data)
{
int i, status = -ETIMEDOUT;
for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
- USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
data, sizeof(*data), HZ * USB_STS_TIMEOUT);
}
return status;
@@ -428,13 +430,13 @@
static void hub_power_on(struct usb_hub *hub)
{
- int i;
+ int port1;
/* if hub supports power switching, enable power on each port */
if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
dev_dbg(hub->intfdev, "enabling power on all ports\n");
- for (i = 0; i < hub->descriptor->bNbrPorts; i++)
- set_port_feature(hub->hdev, i + 1,
+ for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
+ set_port_feature(hub->hdev, port1,
USB_PORT_FEAT_POWER);
}
@@ -688,7 +690,7 @@
hub->indicator [0] = INDICATOR_CYCLE;
hub_power_on(hub);
- hub->change_bits[0] = (1UL << (hub->descriptor->bNbrPorts)) - 1;
+ hub->change_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 2;
hub_activate(hub);
return 0;
@@ -899,7 +901,7 @@
*/
down(&udev->serialize);
up(&hdev->serialize);
- return t;
+ return t + 1;
}
}
usb_unlock_device(hdev);
@@ -1190,22 +1192,22 @@
udev->config[0].desc.wTotalLength,
USB_DT_OTG, (void **) &desc) == 0) {
if (desc->bmAttributes & USB_OTG_HNP) {
- unsigned port;
+ unsigned port1;
struct usb_device *root = udev->parent;
- for (port = 0; port < root->maxchild; port++) {
- if (root->children[port] == udev)
+ for (port1 = 1; port1 <= root->maxchild;
+ port1++) {
+ if (root->children[port1-1] == udev)
break;
}
- port++;
dev_info(&udev->dev,
"Dual-Role OTG device on %sHNP port\n",
- (port == bus->otg_port)
+ (port1 == bus->otg_port)
? "" : "non-");
/* enable HNP before suspend, it's simpler */
- if (port == bus->otg_port)
+ if (port1 == bus->otg_port)
bus->b_hnp_enable = 1;
err = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
@@ -1234,9 +1236,9 @@
*/
if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
static int __usb_suspend_device (struct usb_device *,
- int port, u32 state);
+ int port1, u32 state);
err = __usb_suspend_device(udev,
- udev->bus->otg_port - 1,
+ udev->bus->otg_port,
PM_SUSPEND_MEM);
if (err < 0)
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
@@ -1284,12 +1286,12 @@
}
-static int hub_port_status(struct usb_hub *hub, int port,
+static int hub_port_status(struct usb_hub *hub, int port1,
u16 *status, u16 *change)
{
int ret;
- ret = get_port_status(hub->hdev, port + 1, &hub->status->port);
+ ret = get_port_status(hub->hdev, port1, &hub->status->port);
if (ret < 0)
dev_err (hub->intfdev,
"%s failed (err = %d)\n", __FUNCTION__, ret);
@@ -1312,7 +1314,7 @@
#define HUB_LONG_RESET_TIME 200
#define HUB_RESET_TIMEOUT 500
-static int hub_port_wait_reset(struct usb_hub *hub, int port,
+static int hub_port_wait_reset(struct usb_hub *hub, int port1,
struct usb_device *udev, unsigned int delay)
{
int delay_time, ret;
@@ -1326,7 +1328,7 @@
msleep(delay);
/* read and decode port status */
- ret = hub_port_status(hub, port, &portstatus, &portchange);
+ ret = hub_port_status(hub, port1, &portstatus, &portchange);
if (ret < 0)
return ret;
@@ -1356,13 +1358,13 @@
dev_dbg (hub->intfdev,
"port %d not reset yet, waiting %dms\n",
- port + 1, delay);
+ port1, delay);
}
return -EBUSY;
}
-static int hub_port_reset(struct usb_hub *hub, int port,
+static int hub_port_reset(struct usb_hub *hub, int port1,
struct usb_device *udev, unsigned int delay)
{
int i, status;
@@ -1370,13 +1372,13 @@
/* Reset the port */
for (i = 0; i < PORT_RESET_TRIES; i++) {
status = set_port_feature(hub->hdev,
- port + 1, USB_PORT_FEAT_RESET);
+ port1, USB_PORT_FEAT_RESET);
if (status)
dev_err(hub->intfdev,
"cannot reset port %d (err = %d)\n",
- port + 1, status);
+ port1, status);
else
- status = hub_port_wait_reset(hub, port, udev, delay);
+ status = hub_port_wait_reset(hub, port1, udev, delay);
/* return on disconnect or reset */
switch (status) {
@@ -1384,7 +1386,7 @@
case -ENOTCONN:
case -ENODEV:
clear_port_feature(hub->hdev,
- port + 1, USB_PORT_FEAT_C_RESET);
+ port1, USB_PORT_FEAT_C_RESET);
/* FIXME need disconnect() for NOTATTACHED device */
usb_set_device_state(udev, status
? USB_STATE_NOTATTACHED
@@ -1394,30 +1396,30 @@
dev_dbg (hub->intfdev,
"port %d not enabled, trying reset again...\n",
- port + 1);
+ port1);
delay = HUB_LONG_RESET_TIME;
}
dev_err (hub->intfdev,
"Cannot enable port %i. Maybe the USB cable is bad?\n",
- port + 1);
+ port1);
return status;
}
-static int hub_port_disable(struct usb_hub *hub, int port, int set_state)
+static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
{
struct usb_device *hdev = hub->hdev;
int ret;
- if (hdev->children[port] && set_state) {
- usb_set_device_state(hdev->children[port],
+ if (hdev->children[port1-1] && set_state) {
+ usb_set_device_state(hdev->children[port1-1],
USB_STATE_NOTATTACHED);
}
- ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE);
+ ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
if (ret)
dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
- port + 1, ret);
+ port1, ret);
return ret;
}
@@ -1427,10 +1429,10 @@
* time later khubd will disconnect() any existing usb_device on the port
* and will re-enumerate if there actually is a device attached.
*/
-static void hub_port_logical_disconnect(struct usb_hub *hub, int port)
+static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
{
- dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port + 1);
- hub_port_disable(hub, port, 1);
+ dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1);
+ hub_port_disable(hub, port1, 1);
/* FIXME let caller ask to power down the port:
* - some devices won't enumerate without a VBUS power cycle
@@ -1441,7 +1443,7 @@
* Powerdown must be optional, because of reset/DFU.
*/
- set_bit(port, hub->change_bits);
+ set_bit(port1, hub->change_bits);
kick_khubd(hub);
}
@@ -1458,12 +1460,12 @@
* tree above them to deliver data, such as a keypress or packet. In
* some cases, this wakes the USB host.
*/
-static int hub_port_suspend(struct usb_hub *hub, int port,
+static int hub_port_suspend(struct usb_hub *hub, int port1,
struct usb_device *udev)
{
int status;
- // dev_dbg(hub->intfdev, "suspend port %d\n", port + 1);
+ // dev_dbg(hub->intfdev, "suspend port %d\n", port1);
/* enable remote wakeup when appropriate; this lets the device
* wake up the upstream hub (including maybe the root hub).
@@ -1488,11 +1490,11 @@
}
/* see 7.1.7.6 */
- status = set_port_feature(hub->hdev, port + 1, USB_PORT_FEAT_SUSPEND);
+ status = set_port_feature(hub->hdev, port1, USB_PORT_FEAT_SUSPEND);
if (status) {
dev_dbg(hub->intfdev,
"can't suspend port %d, status %d\n",
- port + 1, status);
+ port1, status);
/* paranoia: "should not happen" */
(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
@@ -1522,13 +1524,13 @@
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd
* timer, no SRP, no requests through sysfs.
*/
-int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
+int __usb_suspend_device (struct usb_device *udev, int port1, u32 state)
{
int status;
/* caller owns the udev device lock */
- if (port < 0)
- return port;
+ if (port1 < 0)
+ return port1;
if (udev->state == USB_STATE_SUSPENDED
|| udev->state == USB_STATE_NOTATTACHED) {
@@ -1609,7 +1611,7 @@
} else
status = -EOPNOTSUPP;
} else
- status = hub_port_suspend(hdev_to_hub(udev->parent), port,
+ status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
udev);
if (status == 0)
@@ -1638,13 +1640,13 @@
*/
int usb_suspend_device(struct usb_device *udev, u32 state)
{
- int port, status;
+ int port1, status;
- port = locktree(udev);
- if (port < 0)
- return port;
+ port1 = locktree(udev);
+ if (port1 < 0)
+ return port1;
- status = __usb_suspend_device(udev, port, state);
+ status = __usb_suspend_device(udev, port1, state);
usb_unlock_device(udev);
return status;
}
@@ -1738,19 +1740,19 @@
}
static int
-hub_port_resume(struct usb_hub *hub, int port, struct usb_device *udev)
+hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
{
int status;
- // dev_dbg(hub->intfdev, "resume port %d\n", port + 1);
+ // dev_dbg(hub->intfdev, "resume port %d\n", port1);
/* see 7.1.7.7; affects power usage, but not budgeting */
status = clear_port_feature(hub->hdev,
- port + 1, USB_PORT_FEAT_SUSPEND);
+ port1, USB_PORT_FEAT_SUSPEND);
if (status) {
dev_dbg(hub->intfdev,
"can't resume port %d, status %d\n",
- port + 1, status);
+ port1, status);
} else {
u16 devstatus;
u16 portchange;
@@ -1769,7 +1771,7 @@
* sequence.
*/
devstatus = portchange = 0;
- status = hub_port_status(hub, port,
+ status = hub_port_status(hub, port1,
&devstatus, &portchange);
if (status < 0
|| (devstatus & LIVE_FLAGS) != LIVE_FLAGS
@@ -1777,7 +1779,7 @@
) {
dev_dbg(hub->intfdev,
"port %d status %04x.%04x after resume, %d\n",
- port + 1, portchange, devstatus, status);
+ port1, portchange, devstatus, status);
} else {
/* TRSMRCY = 10 msec */
msleep(10);
@@ -1786,7 +1788,7 @@
}
}
if (status < 0)
- hub_port_logical_disconnect(hub, port);
+ hub_port_logical_disconnect(hub, port1);
return status;
}
@@ -1808,11 +1810,11 @@
*/
int usb_resume_device(struct usb_device *udev)
{
- int port, status;
+ int port1, status;
- port = locktree(udev);
- if (port < 0)
- return port;
+ port1 = locktree(udev);
+ if (port1 < 0)
+ return port1;
/* "global resume" of the HC-to-USB interface (root hub), or
* selective resume of one hub-to-device port
@@ -1833,7 +1835,7 @@
} else if (udev->state == USB_STATE_SUSPENDED) {
// NOTE this fails if parent is also suspended...
status = hub_port_resume(hdev_to_hub(udev->parent),
- port, udev);
+ port1, udev);
} else {
status = 0;
}
@@ -1875,25 +1877,25 @@
{
struct usb_hub *hub = usb_get_intfdata (intf);
struct usb_device *hdev = hub->hdev;
- unsigned port;
+ unsigned port1;
int status;
/* stop khubd and related activity */
hub_quiesce(hub);
/* then suspend every port */
- for (port = 0; port < hdev->maxchild; port++) {
+ for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
- udev = hdev->children [port];
+ udev = hdev->children [port1-1];
if (!udev)
continue;
down(&udev->serialize);
- status = __usb_suspend_device(udev, port, state);
+ status = __usb_suspend_device(udev, port1, state);
up(&udev->serialize);
if (status < 0)
dev_dbg(&intf->dev, "suspend port %d --> %d\n",
- port, status);
+ port1, status);
}
intf->dev.power.power_state = state;
@@ -1904,21 +1906,21 @@
{
struct usb_device *hdev = interface_to_usbdev(intf);
struct usb_hub *hub = usb_get_intfdata (intf);
- unsigned port;
+ unsigned port1;
int status;
if (intf->dev.power.power_state == PM_SUSPEND_ON)
return 0;
- for (port = 0; port < hdev->maxchild; port++) {
+ for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
u16 portstat, portchange;
- udev = hdev->children [port];
- status = hub_port_status(hub, port, &portstat, &portchange);
+ udev = hdev->children [port1-1];
+ status = hub_port_status(hub, port1, &portstat, &portchange);
if (status == 0) {
if (portchange & USB_PORT_STAT_C_SUSPEND) {
- clear_port_feature(hdev, port + 1,
+ clear_port_feature(hdev, port1,
USB_PORT_FEAT_C_SUSPEND);
portchange &= ~USB_PORT_STAT_C_SUSPEND;
}
@@ -1932,13 +1934,13 @@
continue;
down (&udev->serialize);
if (portstat & USB_PORT_STAT_SUSPEND)
- status = hub_port_resume(hub, port, udev);
+ status = hub_port_resume(hub, port1, udev);
else {
status = finish_port_resume(udev);
if (status < 0) {
dev_dbg(&intf->dev, "resume port %d --> %d\n",
- port + 1, status);
- hub_port_logical_disconnect(hub, port);
+ port1, status);
+ hub_port_logical_disconnect(hub, port1);
}
}
up(&udev->serialize);
@@ -1992,7 +1994,7 @@
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 100
-static int hub_port_debounce(struct usb_hub *hub, int port)
+static int hub_port_debounce(struct usb_hub *hub, int port1)
{
int ret;
int total_time, stable_time = 0;
@@ -2000,7 +2002,7 @@
unsigned connection = 0xffff;
for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
- ret = hub_port_status(hub, port, &portstatus, &portchange);
+ ret = hub_port_status(hub, port1, &portstatus, &portchange);
if (ret < 0)
return ret;
@@ -2015,7 +2017,7 @@
}
if (portchange & USB_PORT_STAT_C_CONNECTION) {
- clear_port_feature(hub->hdev, port+1,
+ clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
}
@@ -2026,7 +2028,7 @@
dev_dbg (hub->intfdev,
"debounce: port %d: total %dms stable %dms status 0x%x\n",
- port + 1, total_time, stable_time, portstatus);
+ port1, total_time, stable_time, portstatus);
if (stable_time < HUB_DEBOUNCE_STABLE)
return -ETIMEDOUT;
@@ -2073,7 +2075,7 @@
* pointers, it's not necessary to lock the device.
*/
static int
-hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port,
+hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
int retry_counter)
{
static DECLARE_MUTEX(usb_address0_sem);
@@ -2088,7 +2090,7 @@
*/
if (!hdev->parent) {
delay = HUB_ROOT_RESET_TIME;
- if (port + 1 == hdev->bus->otg_port)
+ if (port1 == hdev->bus->otg_port)
hdev->bus->b_hnp_enable = 0;
}
@@ -2100,7 +2102,7 @@
down(&usb_address0_sem);
/* Reset the device; full speed may morph to high speed */
- retval = hub_port_reset(hub, port, udev, delay);
+ retval = hub_port_reset(hub, port1, udev, delay);
if (retval < 0) /* error or disconnect */
goto fail;
/* success, speed is known */
@@ -2152,7 +2154,7 @@
} else if (udev->speed != USB_SPEED_HIGH
&& hdev->speed == USB_SPEED_HIGH) {
udev->tt = &hub->tt;
- udev->ttport = port + 1;
+ udev->ttport = port1;
}
/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
@@ -2202,7 +2204,7 @@
buf->bMaxPacketSize0;
kfree(buf);
- retval = hub_port_reset(hub, port, udev, delay);
+ retval = hub_port_reset(hub, port1, udev, delay);
if (retval < 0) /* error or disconnect */
goto fail;
if (oldspeed != udev->speed) {
@@ -2286,13 +2288,13 @@
fail:
if (retval)
- hub_port_disable(hub, port, 0);
+ hub_port_disable(hub, port1, 0);
up(&usb_address0_sem);
return retval;
}
static void
-check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port)
+check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
{
struct usb_qualifier_descriptor *qual;
int status;
@@ -2308,7 +2310,7 @@
"connect to a high speed hub\n");
/* hub LEDs are probably harder to miss than syslog */
if (hub->has_indicators) {
- hub->indicator[port] = INDICATOR_GREEN_BLINK;
+ hub->indicator[port1-1] = INDICATOR_GREEN_BLINK;
schedule_work (&hub->leds);
}
}
@@ -2366,7 +2368,7 @@
* a firmware download)
* caller already locked the hub
*/
-static void hub_port_connect_change(struct usb_hub *hub, int port,
+static void hub_port_connect_change(struct usb_hub *hub, int port1,
u16 portstatus, u16 portchange)
{
struct usb_device *hdev = hub->hdev;
@@ -2375,17 +2377,17 @@
dev_dbg (hub_dev,
"port %d, status %04x, change %04x, %s\n",
- port + 1, portstatus, portchange, portspeed (portstatus));
+ port1, portstatus, portchange, portspeed (portstatus));
if (hub->has_indicators) {
- set_port_led(hub, port + 1, HUB_LED_AUTO);
- hub->indicator[port] = INDICATOR_AUTO;
+ set_port_led(hub, port1, HUB_LED_AUTO);
+ hub->indicator[port1-1] = INDICATOR_AUTO;
}
/* Disconnect any existing devices under this port */
- if (hdev->children[port])
- usb_disconnect(&hdev->children[port]);
- clear_bit(port, hub->change_bits);
+ if (hdev->children[port1-1])
+ usb_disconnect(&hdev->children[port1-1]);
+ clear_bit(port1, hub->change_bits);
#ifdef CONFIG_USB_OTG
/* during HNP, don't repeat the debounce */
@@ -2394,11 +2396,11 @@
#endif
if (portchange & USB_PORT_STAT_C_CONNECTION) {
- status = hub_port_debounce(hub, port);
+ status = hub_port_debounce(hub, port1);
if (status < 0) {
dev_err (hub_dev,
"connect-debounce failed, port %d disabled\n",
- port+1);
+ port1);
goto done;
}
portstatus = status;
@@ -2411,7 +2413,7 @@
if ((hub->descriptor->wHubCharacteristics
& HUB_CHAR_LPSM) < 2
&& !(portstatus & (1 << USB_PORT_FEAT_POWER)))
- set_port_feature(hdev, port + 1, USB_PORT_FEAT_POWER);
+ set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
if (portstatus & USB_PORT_STAT_ENABLE)
goto done;
@@ -2421,11 +2423,11 @@
#ifdef CONFIG_USB_SUSPEND
/* If something is connected, but the port is suspended, wake it up. */
if (portstatus & USB_PORT_STAT_SUSPEND) {
- status = hub_port_resume(hub, port, NULL);
+ status = hub_port_resume(hub, port1, NULL);
if (status < 0) {
dev_dbg(hub_dev,
"can't clear suspend on port %d; %d\n",
- port+1, status);
+ port1, status);
goto done;
}
}
@@ -2437,10 +2439,11 @@
/* reallocate for each attempt, since references
* to the previous one can escape in various ways
*/
- udev = usb_alloc_dev(hdev, hdev->bus, port);
+ udev = usb_alloc_dev(hdev, hdev->bus, port1);
if (!udev) {
dev_err (hub_dev,
- "couldn't allocate port %d usb_device\n", port+1);
+ "couldn't allocate port %d usb_device\n",
+ port1);
goto done;
}
@@ -2455,7 +2458,7 @@
}
/* reset and get descriptor */
- status = hub_port_init(hub, udev, port, i);
+ status = hub_port_init(hub, udev, port1, i);
if (status < 0)
goto loop;
@@ -2481,7 +2484,7 @@
"can't connect bus-powered hub "
"to this port\n");
if (hub->has_indicators) {
- hub->indicator[port] =
+ hub->indicator[port1-1] =
INDICATOR_AMBER_BLINK;
schedule_work (&hub->leds);
}
@@ -2494,7 +2497,7 @@
if (udev->descriptor.bcdUSB >= 0x0200
&& udev->speed == USB_SPEED_FULL
&& highspeed_hubs != 0)
- check_highspeed (hub, udev, port);
+ check_highspeed (hub, udev, port1);
/* Store the parent's children[] pointer. At this point
* udev becomes globally accessible, although presumably
@@ -2511,7 +2514,7 @@
if (hdev->state == USB_STATE_NOTATTACHED)
status = -ENOTCONN;
else
- hdev->children[port] = udev;
+ hdev->children[port1-1] = udev;
spin_unlock_irq(&device_state_lock);
/* Run it through the hoops (find a driver, etc) */
@@ -2519,7 +2522,7 @@
status = usb_new_device(udev);
if (status) {
spin_lock_irq(&device_state_lock);
- hdev->children[port] = NULL;
+ hdev->children[port1-1] = NULL;
spin_unlock_irq(&device_state_lock);
}
}
@@ -2537,7 +2540,7 @@
return;
loop_disable:
- hub_port_disable(hub, port, 1);
+ hub_port_disable(hub, port1, 1);
loop:
ep0_reinit(udev);
release_address(udev);
@@ -2547,7 +2550,7 @@
}
done:
- hub_port_disable(hub, port, 1);
+ hub_port_disable(hub, port1, 1);
}
static void hub_events(void)
@@ -2623,9 +2626,9 @@
}
/* deal with port status changes */
- for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
+ for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
connect_change = test_bit(i, hub->change_bits);
- if (!test_and_clear_bit(i+1, hub->event_bits) &&
+ if (!test_and_clear_bit(i, hub->event_bits) &&
!connect_change)
continue;
@@ -2635,8 +2638,8 @@
continue;
if (portchange & USB_PORT_STAT_C_CONNECTION) {
- clear_port_feature(hdev,
- i + 1, USB_PORT_FEAT_C_CONNECTION);
+ clear_port_feature(hdev, i,
+ USB_PORT_FEAT_C_CONNECTION);
connect_change = 1;
}
@@ -2645,9 +2648,9 @@
dev_dbg (hub_dev,
"port %d enable change, "
"status %08x\n",
- i + 1, portstatus);
- clear_port_feature(hdev,
- i + 1, USB_PORT_FEAT_C_ENABLE);
+ i, portstatus);
+ clear_port_feature(hdev, i,
+ USB_PORT_FEAT_C_ENABLE);
/*
* EM interference sometimes causes badly
@@ -2657,21 +2660,22 @@
*/
if (!(portstatus & USB_PORT_STAT_ENABLE)
&& !connect_change
- && hdev->children[i]) {
+ && hdev->children[i-1]) {
dev_err (hub_dev,
"port %i "
"disabled by hub (EMI?), "
"re-enabling...\n",
- i + 1);
+ i);
connect_change = 1;
}
}
if (portchange & USB_PORT_STAT_C_SUSPEND) {
- clear_port_feature(hdev, i + 1,
+ clear_port_feature(hdev, i,
USB_PORT_FEAT_C_SUSPEND);
- if (hdev->children[i]) {
- ret = remote_wakeup(hdev->children[i]);
+ if (hdev->children[i-1]) {
+ ret = remote_wakeup(hdev->
+ children[i-1]);
if (ret < 0)
connect_change = 1;
} else {
@@ -2680,24 +2684,24 @@
}
dev_dbg (hub_dev,
"resume on port %d, status %d\n",
- i + 1, ret);
+ i, ret);
}
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
dev_err (hub_dev,
"over-current change on port %d\n",
- i + 1);
- clear_port_feature(hdev,
- i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
+ i);
+ clear_port_feature(hdev, i,
+ USB_PORT_FEAT_C_OVER_CURRENT);
hub_power_on(hub);
}
if (portchange & USB_PORT_STAT_C_RESET) {
dev_dbg (hub_dev,
"reset change on port %d\n",
- i + 1);
- clear_port_feature(hdev,
- i + 1, USB_PORT_FEAT_C_RESET);
+ i);
+ clear_port_feature(hdev, i,
+ USB_PORT_FEAT_C_RESET);
}
if (connect_change)
@@ -2886,7 +2890,7 @@
struct usb_hub *parent_hub;
struct usb_device_descriptor descriptor = udev->descriptor;
struct usb_hub *hub = NULL;
- int i, ret = 0, port = -1;
+ int i, ret = 0, port1 = -1;
if (udev->state == USB_STATE_NOTATTACHED ||
udev->state == USB_STATE_SUSPENDED) {
@@ -2903,11 +2907,11 @@
for (i = 0; i < parent_hdev->maxchild; i++)
if (parent_hdev->children[i] == udev) {
- port = i;
+ port1 = i + 1;
break;
}
- if (port < 0) {
+ if (port1 < 0) {
/* If this ever happens, it's very bad */
dev_err(&udev->dev, "Can't locate device's port!\n");
return -ENOENT;
@@ -2927,7 +2931,7 @@
/* ep0 maxpacket size may change; let the HCD know about it.
* Other endpoints will be handled by re-enumeration. */
ep0_reinit(udev);
- ret = hub_port_init(parent_hub, udev, port, i);
+ ret = hub_port_init(parent_hub, udev, port1, i);
if (ret >= 0)
break;
}
@@ -2983,6 +2987,6 @@
return 0;
re_enumerate:
- hub_port_logical_disconnect(parent_hub, port);
+ hub_port_logical_disconnect(parent_hub, port1);
return -ENODEV;
}
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c 2005-01-07 15:42:44 -08:00
+++ b/drivers/usb/core/usb.c 2005-01-07 15:42:44 -08:00
@@ -655,7 +655,7 @@
* usb_alloc_dev - usb device constructor (usbcore-internal)
* @parent: hub to which device is connected; null to allocate a root hub
* @bus: bus used to access the device
- * @port: zero based index of port; ignored for root hubs
+ * @port1: one-based index of port; ignored for root hubs
* Context: !in_interrupt ()
*
* Only hub drivers (including virtual root hub drivers for host
@@ -664,7 +664,7 @@
* This call may not be used in a non-sleeping context.
*/
struct usb_device *
-usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port)
+usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;
@@ -711,10 +711,10 @@
/* match any labeling on the hubs; it's one-based */
if (parent->devpath [0] == '0')
snprintf (dev->devpath, sizeof dev->devpath,
- "%d", port + 1);
+ "%d", port1);
else
snprintf (dev->devpath, sizeof dev->devpath,
- "%s.%d", parent->devpath, port + 1);
+ "%s.%d", parent->devpath, port1);
dev->dev.parent = &parent->dev;
sprintf (&dev->dev.bus_id[0], "%d-%s",
ChangeSet 1.1938.446.48, 2004/12/20 15:01:03-08:00, [email protected]
[PATCH] USB: Hub driver cleanups [12/13]
This patch does a little cleanup of the hub driver, nothing dramatic
(although it is long because it touches a lot of code). The main feature
is that the private hub structure is passed as an argument to internal
routines rather than the hub device structure. This simplifies
conversions, because it's easier to go from the private structure to the
device structure than vice versa. The other change is to store a pointer
to the interface's embedded struct device rather than the interface
itself. This helps because that pointer is mainly used for dev_xxx log
messages.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hub.c | 202 +++++++++++++++++++++++--------------------------
drivers/usb/core/hub.h | 2
2 files changed, 99 insertions(+), 105 deletions(-)
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:42:51 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:42:51 -08:00
@@ -94,10 +94,10 @@
}
#endif
-/* for dev_info, dev_dbg, etc */
-static inline struct device *hubdev (struct usb_device *hdev)
+/* Note that hdev or one of its children must be locked! */
+static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev)
{
- return &hdev->actconfig->interface[0]->dev;
+ return usb_get_intfdata(hdev->actconfig->interface[0]);
}
/* USB 2.0 spec Section 11.24.4.5 */
@@ -148,15 +148,15 @@
* for info about using port indicators
*/
static void set_port_led(
- struct usb_device *hdev,
+ struct usb_hub *hub,
int port,
int selector
)
{
- int status = set_port_feature(hdev, (selector << 8) | port,
+ int status = set_port_feature(hub->hdev, (selector << 8) | port,
USB_PORT_FEAT_INDICATOR);
if (status < 0)
- dev_dbg (hubdev (hdev),
+ dev_dbg (hub->intfdev,
"port %d indicator %s status %d\n",
port,
({ char *s; switch (selector) {
@@ -226,13 +226,13 @@
}
if (selector != HUB_LED_AUTO)
changed = 1;
- set_port_led(hdev, i + 1, selector);
+ set_port_led(hub, i + 1, selector);
hub->indicator[i] = mode;
}
if (!changed && blinkenlights) {
cursor++;
cursor %= hub->descriptor->bNbrPorts;
- set_port_led(hdev, cursor + 1, HUB_LED_GREEN);
+ set_port_led(hub, cursor + 1, HUB_LED_GREEN);
hub->indicator[cursor] = INDICATOR_CYCLE;
changed++;
}
@@ -305,7 +305,7 @@
default: /* presumably an error */
/* Cause a hub reset after 10 consecutive errors */
- dev_dbg (&hub->intf->dev, "transfer --> %d\n", urb->status);
+ dev_dbg (hub->intfdev, "transfer --> %d\n", urb->status);
if ((++hub->nerrors < 10) || hub->error)
goto resubmit;
hub->error = urb->status;
@@ -332,7 +332,7 @@
if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
&& status != -ENODEV && status != -EPERM)
- dev_err (&hub->intf->dev, "resubmit --> %d\n", status);
+ dev_err (hub->intfdev, "resubmit --> %d\n", status);
}
/* USB 2.0 spec Section 11.24.2.3 */
@@ -432,7 +432,7 @@
/* if hub supports power switching, enable power on each port */
if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
- dev_dbg(&hub->intf->dev, "enabling power on all ports\n");
+ dev_dbg(hub->intfdev, "enabling power on all ports\n");
for (i = 0; i < hub->descriptor->bNbrPorts; i++)
set_port_feature(hub->hdev, i + 1,
USB_PORT_FEAT_POWER);
@@ -460,7 +460,7 @@
hub->quiescing = 0;
status = usb_submit_urb(hub->urb, GFP_NOIO);
if (status < 0)
- dev_err(&hub->intf->dev, "activate --> %d\n", status);
+ dev_err(hub->intfdev, "activate --> %d\n", status);
if (hub->has_indicators && blinkenlights)
schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
@@ -476,7 +476,7 @@
ret = get_hub_status(hub->hdev, &hub->status->hub);
if (ret < 0)
- dev_err (&hub->intf->dev,
+ dev_err (hub->intfdev,
"%s failed (err = %d)\n", __FUNCTION__, ret);
else {
*status = le16_to_cpu(hub->status->hub.wHubStatus);
@@ -490,7 +490,7 @@
struct usb_endpoint_descriptor *endpoint)
{
struct usb_device *hdev = hub->hdev;
- struct device *hub_dev = &hub->intf->dev;
+ struct device *hub_dev = hub->intfdev;
u16 hubstatus, hubchange;
unsigned int pipe;
int maxp, ret;
@@ -749,18 +749,16 @@
struct usb_endpoint_descriptor *endpoint;
struct usb_device *hdev;
struct usb_hub *hub;
- struct device *hub_dev;
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);
- hub_dev = &intf->dev;
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
if ((desc->desc.bInterfaceSubClass != 0) &&
(desc->desc.bInterfaceSubClass != 1)) {
descriptor_error:
- dev_err (hub_dev, "bad descriptor, ignoring hub\n");
+ dev_err (&intf->dev, "bad descriptor, ignoring hub\n");
return -EIO;
}
@@ -780,18 +778,18 @@
goto descriptor_error;
/* We found a hub */
- dev_info (hub_dev, "USB hub found\n");
+ dev_info (&intf->dev, "USB hub found\n");
hub = kmalloc(sizeof(*hub), GFP_KERNEL);
if (!hub) {
- dev_dbg (hub_dev, "couldn't kmalloc hub struct\n");
+ dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n");
return -ENOMEM;
}
memset(hub, 0, sizeof(*hub));
INIT_LIST_HEAD(&hub->event_list);
- hub->intf = intf;
+ hub->intfdev = &intf->dev;
hub->hdev = hdev;
INIT_WORK(&hub->leds, led_work, hub);
@@ -842,9 +840,9 @@
}
/* caller has locked the hub device */
-static void hub_pre_reset(struct usb_device *hdev)
+static void hub_pre_reset(struct usb_hub *hub)
{
- struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
+ struct usb_device *hdev = hub->hdev;
int i;
for (i = 0; i < hdev->maxchild; ++i) {
@@ -855,10 +853,8 @@
}
/* caller has locked the hub device */
-static void hub_post_reset(struct usb_device *hdev)
+static void hub_post_reset(struct usb_hub *hub)
{
- struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
-
hub_activate(hub);
hub_power_on(hub);
}
@@ -1288,18 +1284,14 @@
}
-static int hub_port_status(struct usb_device *hdev, int port,
+static int hub_port_status(struct usb_hub *hub, int port,
u16 *status, u16 *change)
{
- struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
int ret;
- if (!hub)
- return -ENODEV;
-
- ret = get_port_status(hdev, port + 1, &hub->status->port);
+ ret = get_port_status(hub->hdev, port + 1, &hub->status->port);
if (ret < 0)
- dev_err (&hub->intf->dev,
+ dev_err (hub->intfdev,
"%s failed (err = %d)\n", __FUNCTION__, ret);
else {
*status = le16_to_cpu(hub->status->port.wPortStatus);
@@ -1320,7 +1312,7 @@
#define HUB_LONG_RESET_TIME 200
#define HUB_RESET_TIMEOUT 500
-static int hub_port_wait_reset(struct usb_device *hdev, int port,
+static int hub_port_wait_reset(struct usb_hub *hub, int port,
struct usb_device *udev, unsigned int delay)
{
int delay_time, ret;
@@ -1334,7 +1326,7 @@
msleep(delay);
/* read and decode port status */
- ret = hub_port_status(hdev, port, &portstatus, &portchange);
+ ret = hub_port_status(hub, port, &portstatus, &portchange);
if (ret < 0)
return ret;
@@ -1362,7 +1354,7 @@
if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
delay = HUB_LONG_RESET_TIME;
- dev_dbg (hubdev (hdev),
+ dev_dbg (hub->intfdev,
"port %d not reset yet, waiting %dms\n",
port + 1, delay);
}
@@ -1370,27 +1362,28 @@
return -EBUSY;
}
-static int hub_port_reset(struct usb_device *hdev, int port,
+static int hub_port_reset(struct usb_hub *hub, int port,
struct usb_device *udev, unsigned int delay)
{
int i, status;
- struct device *hub_dev = hubdev (hdev);
/* Reset the port */
for (i = 0; i < PORT_RESET_TRIES; i++) {
- status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
+ status = set_port_feature(hub->hdev,
+ port + 1, USB_PORT_FEAT_RESET);
if (status)
- dev_err(hub_dev, "cannot reset port %d (err = %d)\n",
+ dev_err(hub->intfdev,
+ "cannot reset port %d (err = %d)\n",
port + 1, status);
else
- status = hub_port_wait_reset(hdev, port, udev, delay);
+ status = hub_port_wait_reset(hub, port, udev, delay);
/* return on disconnect or reset */
switch (status) {
case 0:
case -ENOTCONN:
case -ENODEV:
- clear_port_feature(hdev,
+ clear_port_feature(hub->hdev,
port + 1, USB_PORT_FEAT_C_RESET);
/* FIXME need disconnect() for NOTATTACHED device */
usb_set_device_state(udev, status
@@ -1399,21 +1392,22 @@
return status;
}
- dev_dbg (hub_dev,
+ dev_dbg (hub->intfdev,
"port %d not enabled, trying reset again...\n",
port + 1);
delay = HUB_LONG_RESET_TIME;
}
- dev_err (hub_dev,
+ dev_err (hub->intfdev,
"Cannot enable port %i. Maybe the USB cable is bad?\n",
port + 1);
return status;
}
-static int hub_port_disable(struct usb_device *hdev, int port, int set_state)
+static int hub_port_disable(struct usb_hub *hub, int port, int set_state)
{
+ struct usb_device *hdev = hub->hdev;
int ret;
if (hdev->children[port] && set_state) {
@@ -1422,7 +1416,7 @@
}
ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE);
if (ret)
- dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n",
+ dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
port + 1, ret);
return ret;
@@ -1433,12 +1427,10 @@
* time later khubd will disconnect() any existing usb_device on the port
* and will re-enumerate if there actually is a device attached.
*/
-static void hub_port_logical_disconnect(struct usb_device *hdev, int port)
+static void hub_port_logical_disconnect(struct usb_hub *hub, int port)
{
- struct usb_hub *hub;
-
- dev_dbg(hubdev(hdev), "logical disconnect on port %d\n", port + 1);
- hub_port_disable(hdev, port, 1);
+ dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port + 1);
+ hub_port_disable(hub, port, 1);
/* FIXME let caller ask to power down the port:
* - some devices won't enumerate without a VBUS power cycle
@@ -1449,7 +1441,6 @@
* Powerdown must be optional, because of reset/DFU.
*/
- hub = usb_get_intfdata(hdev->actconfig->interface[0]);
set_bit(port, hub->change_bits);
kick_khubd(hub);
}
@@ -1467,12 +1458,12 @@
* tree above them to deliver data, such as a keypress or packet. In
* some cases, this wakes the USB host.
*/
-static int hub_port_suspend(struct usb_device *hdev, int port,
+static int hub_port_suspend(struct usb_hub *hub, int port,
struct usb_device *udev)
{
int status;
- // dev_dbg(hubdev(hdev), "suspend port %d\n", port + 1);
+ // dev_dbg(hub->intfdev, "suspend port %d\n", port + 1);
/* enable remote wakeup when appropriate; this lets the device
* wake up the upstream hub (including maybe the root hub).
@@ -1497,9 +1488,9 @@
}
/* see 7.1.7.6 */
- status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND);
+ status = set_port_feature(hub->hdev, port + 1, USB_PORT_FEAT_SUSPEND);
if (status) {
- dev_dbg(hubdev(hdev),
+ dev_dbg(hub->intfdev,
"can't suspend port %d, status %d\n",
port + 1, status);
/* paranoia: "should not happen" */
@@ -1618,7 +1609,8 @@
} else
status = -EOPNOTSUPP;
} else
- status = hub_port_suspend(udev->parent, port, udev);
+ status = hub_port_suspend(hdev_to_hub(udev->parent), port,
+ udev);
if (status == 0)
udev->dev.power.power_state = state;
@@ -1746,16 +1738,17 @@
}
static int
-hub_port_resume(struct usb_device *hdev, int port, struct usb_device *udev)
+hub_port_resume(struct usb_hub *hub, int port, struct usb_device *udev)
{
int status;
- // dev_dbg(hubdev(hdev), "resume port %d\n", port + 1);
+ // dev_dbg(hub->intfdev, "resume port %d\n", port + 1);
/* see 7.1.7.7; affects power usage, but not budgeting */
- status = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND);
+ status = clear_port_feature(hub->hdev,
+ port + 1, USB_PORT_FEAT_SUSPEND);
if (status) {
- dev_dbg(&hdev->actconfig->interface[0]->dev,
+ dev_dbg(hub->intfdev,
"can't resume port %d, status %d\n",
port + 1, status);
} else {
@@ -1776,13 +1769,13 @@
* sequence.
*/
devstatus = portchange = 0;
- status = hub_port_status(hdev, port,
+ status = hub_port_status(hub, port,
&devstatus, &portchange);
if (status < 0
|| (devstatus & LIVE_FLAGS) != LIVE_FLAGS
|| (devstatus & USB_PORT_STAT_SUSPEND) != 0
) {
- dev_dbg(&hdev->actconfig->interface[0]->dev,
+ dev_dbg(hub->intfdev,
"port %d status %04x.%04x after resume, %d\n",
port + 1, portchange, devstatus, status);
} else {
@@ -1793,7 +1786,7 @@
}
}
if (status < 0)
- hub_port_logical_disconnect(hdev, port);
+ hub_port_logical_disconnect(hub, port);
return status;
}
@@ -1815,7 +1808,7 @@
*/
int usb_resume_device(struct usb_device *udev)
{
- int port, status;
+ int port, status;
port = locktree(udev);
if (port < 0)
@@ -1839,7 +1832,8 @@
}
} else if (udev->state == USB_STATE_SUSPENDED) {
// NOTE this fails if parent is also suspended...
- status = hub_port_resume(udev->parent, port, udev);
+ status = hub_port_resume(hdev_to_hub(udev->parent),
+ port, udev);
} else {
status = 0;
}
@@ -1921,7 +1915,7 @@
u16 portstat, portchange;
udev = hdev->children [port];
- status = hub_port_status(hdev, port, &portstat, &portchange);
+ status = hub_port_status(hub, port, &portstat, &portchange);
if (status == 0) {
if (portchange & USB_PORT_STAT_C_SUSPEND) {
clear_port_feature(hdev, port + 1,
@@ -1938,13 +1932,13 @@
continue;
down (&udev->serialize);
if (portstat & USB_PORT_STAT_SUSPEND)
- status = hub_port_resume(hdev, port, udev);
+ status = hub_port_resume(hub, port, udev);
else {
status = finish_port_resume(udev);
if (status < 0) {
dev_dbg(&intf->dev, "resume port %d --> %d\n",
port + 1, status);
- hub_port_logical_disconnect(hdev, port);
+ hub_port_logical_disconnect(hub, port);
}
}
up(&udev->serialize);
@@ -1998,7 +1992,7 @@
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 100
-static int hub_port_debounce(struct usb_device *hdev, int port)
+static int hub_port_debounce(struct usb_hub *hub, int port)
{
int ret;
int total_time, stable_time = 0;
@@ -2006,7 +2000,7 @@
unsigned connection = 0xffff;
for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
- ret = hub_port_status(hdev, port, &portstatus, &portchange);
+ ret = hub_port_status(hub, port, &portstatus, &portchange);
if (ret < 0)
return ret;
@@ -2021,7 +2015,7 @@
}
if (portchange & USB_PORT_STAT_C_CONNECTION) {
- clear_port_feature(hdev, port+1,
+ clear_port_feature(hub->hdev, port+1,
USB_PORT_FEAT_C_CONNECTION);
}
@@ -2030,7 +2024,7 @@
msleep(HUB_DEBOUNCE_STEP);
}
- dev_dbg (hubdev (hdev),
+ dev_dbg (hub->intfdev,
"debounce: port %d: total %dms stable %dms status 0x%x\n",
port + 1, total_time, stable_time, portstatus);
@@ -2079,11 +2073,12 @@
* pointers, it's not necessary to lock the device.
*/
static int
-hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port,
+hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port,
int retry_counter)
{
static DECLARE_MUTEX(usb_address0_sem);
+ struct usb_device *hdev = hub->hdev;
int i, j, retval;
unsigned delay = HUB_SHORT_RESET_TIME;
enum usb_device_speed oldspeed = udev->speed;
@@ -2105,7 +2100,7 @@
down(&usb_address0_sem);
/* Reset the device; full speed may morph to high speed */
- retval = hub_port_reset(hdev, port, udev, delay);
+ retval = hub_port_reset(hub, port, udev, delay);
if (retval < 0) /* error or disconnect */
goto fail;
/* success, speed is known */
@@ -2156,9 +2151,6 @@
udev->ttport = hdev->ttport;
} else if (udev->speed != USB_SPEED_HIGH
&& hdev->speed == USB_SPEED_HIGH) {
- struct usb_hub *hub;
-
- hub = usb_get_intfdata(hdev->actconfig->interface[0]);
udev->tt = &hub->tt;
udev->ttport = port + 1;
}
@@ -2210,7 +2202,7 @@
buf->bMaxPacketSize0;
kfree(buf);
- retval = hub_port_reset(hdev, port, udev, delay);
+ retval = hub_port_reset(hub, port, udev, delay);
if (retval < 0) /* error or disconnect */
goto fail;
if (oldspeed != udev->speed) {
@@ -2294,7 +2286,7 @@
fail:
if (retval)
- hub_port_disable(hdev, port, 0);
+ hub_port_disable(hub, port, 0);
up(&usb_address0_sem);
return retval;
}
@@ -2358,7 +2350,7 @@
remaining -= delta;
}
if (remaining < 0) {
- dev_warn(&hub->intf->dev,
+ dev_warn(hub->intfdev,
"%dmA over power budget!\n",
-2 * remaining);
remaining = 0;
@@ -2378,7 +2370,7 @@
u16 portstatus, u16 portchange)
{
struct usb_device *hdev = hub->hdev;
- struct device *hub_dev = &hub->intf->dev;
+ struct device *hub_dev = hub->intfdev;
int status, i;
dev_dbg (hub_dev,
@@ -2386,7 +2378,7 @@
port + 1, portstatus, portchange, portspeed (portstatus));
if (hub->has_indicators) {
- set_port_led(hdev, port + 1, HUB_LED_AUTO);
+ set_port_led(hub, port + 1, HUB_LED_AUTO);
hub->indicator[port] = INDICATOR_AUTO;
}
@@ -2402,7 +2394,7 @@
#endif
if (portchange & USB_PORT_STAT_C_CONNECTION) {
- status = hub_port_debounce(hdev, port);
+ status = hub_port_debounce(hub, port);
if (status < 0) {
dev_err (hub_dev,
"connect-debounce failed, port %d disabled\n",
@@ -2429,7 +2421,7 @@
#ifdef CONFIG_USB_SUSPEND
/* If something is connected, but the port is suspended, wake it up. */
if (portstatus & USB_PORT_STAT_SUSPEND) {
- status = hub_port_resume(hdev, port, NULL);
+ status = hub_port_resume(hub, port, NULL);
if (status < 0) {
dev_dbg(hub_dev,
"can't clear suspend on port %d; %d\n",
@@ -2463,7 +2455,7 @@
}
/* reset and get descriptor */
- status = hub_port_init(hdev, udev, port, i);
+ status = hub_port_init(hub, udev, port, i);
if (status < 0)
goto loop;
@@ -2545,7 +2537,7 @@
return;
loop_disable:
- hub_port_disable(hdev, port, 1);
+ hub_port_disable(hub, port, 1);
loop:
ep0_reinit(udev);
release_address(udev);
@@ -2555,7 +2547,7 @@
}
done:
- hub_port_disable(hdev, port, 1);
+ hub_port_disable(hub, port, 1);
}
static void hub_events(void)
@@ -2592,7 +2584,7 @@
hub = list_entry(tmp, struct usb_hub, event_list);
hdev = hub->hdev;
- intf = hub->intf;
+ intf = to_usb_interface(hub->intfdev);
hub_dev = &intf->dev;
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
@@ -2637,7 +2629,7 @@
!connect_change)
continue;
- ret = hub_port_status(hdev, i,
+ ret = hub_port_status(hub, i,
&portstatus, &portchange);
if (ret < 0)
continue;
@@ -2684,7 +2676,7 @@
connect_change = 1;
} else {
ret = -ENODEV;
- hub_port_disable(hdev, i, 1);
+ hub_port_disable(hub, i, 1);
}
dev_dbg (hub_dev,
"resume on port %d, status %d\n",
@@ -2890,10 +2882,11 @@
*/
int usb_reset_device(struct usb_device *udev)
{
- struct usb_device *parent = udev->parent;
- struct usb_device_descriptor descriptor = udev->descriptor;
- int i, ret = 0, port = -1;
- int udev_is_a_hub = 0;
+ struct usb_device *parent_hdev = udev->parent;
+ struct usb_hub *parent_hub;
+ struct usb_device_descriptor descriptor = udev->descriptor;
+ struct usb_hub *hub = NULL;
+ int i, ret = 0, port = -1;
if (udev->state == USB_STATE_NOTATTACHED ||
udev->state == USB_STATE_SUSPENDED) {
@@ -2902,14 +2895,14 @@
return -EINVAL;
}
- if (!parent) {
+ if (!parent_hdev) {
/* this requires hcd-specific logic; see OHCI hc_restart() */
dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
return -EISDIR;
}
- for (i = 0; i < parent->maxchild; i++)
- if (parent->children[i] == udev) {
+ for (i = 0; i < parent_hdev->maxchild; i++)
+ if (parent_hdev->children[i] == udev) {
port = i;
break;
}
@@ -2919,13 +2912,14 @@
dev_err(&udev->dev, "Can't locate device's port!\n");
return -ENOENT;
}
+ parent_hub = hdev_to_hub(parent_hdev);
/* If we're resetting an active hub, take some special actions */
if (udev->actconfig &&
udev->actconfig->interface[0]->dev.driver ==
- &hub_driver.driver) {
- udev_is_a_hub = 1;
- hub_pre_reset(udev);
+ &hub_driver.driver &&
+ (hub = hdev_to_hub(udev)) != NULL) {
+ hub_pre_reset(hub);
}
for (i = 0; i < SET_CONFIG_TRIES; ++i) {
@@ -2933,7 +2927,7 @@
/* ep0 maxpacket size may change; let the HCD know about it.
* Other endpoints will be handled by re-enumeration. */
ep0_reinit(udev);
- ret = hub_port_init(parent, udev, port, i);
+ ret = hub_port_init(parent_hub, udev, port, i);
if (ret >= 0)
break;
}
@@ -2984,11 +2978,11 @@
}
done:
- if (udev_is_a_hub)
- hub_post_reset(udev);
+ if (hub)
+ hub_post_reset(hub);
return 0;
re_enumerate:
- hub_port_logical_disconnect(parent, port);
+ hub_port_logical_disconnect(parent_hub, port);
return -ENODEV;
}
diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h 2005-01-07 15:42:51 -08:00
+++ b/drivers/usb/core/hub.h 2005-01-07 15:42:51 -08:00
@@ -186,7 +186,7 @@
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
- struct usb_interface *intf; /* the "real" device */
+ struct device *intfdev; /* the "interface" device */
struct usb_device *hdev;
struct urb *urb; /* for interrupt polling pipe */
ChangeSet 1.1938.446.43, 2004/12/20 14:19:38-08:00, [email protected]
[PATCH] USB: Create usb_hcd structures within usbcore [4/13]
This patch alters the UHCI driver, removing the routine that allocates the
hcd structure and introducing inline functions to convert safely between
the public and private hcd structures.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/uhci-hcd.c | 23 +++++------------------
drivers/usb/host/uhci-hcd.h | 16 ++++++++++++----
2 files changed, 17 insertions(+), 22 deletions(-)
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c 2005-01-07 15:43:29 -08:00
+++ b/drivers/usb/host/uhci-hcd.c 2005-01-07 15:43:29 -08:00
@@ -1891,7 +1891,7 @@
uhci->state_end = jiffies + HZ;
outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
- uhci->hcd.state = USB_STATE_RUNNING;
+ uhci_to_hcd(uhci)->state = USB_STATE_RUNNING;
return 0;
}
@@ -2151,7 +2151,7 @@
udev->speed = USB_SPEED_FULL;
- if (hcd_register_root(udev, &uhci->hcd) != 0) {
+ if (hcd_register_root(udev, hcd) != 0) {
dev_err(uhci_dev(uhci), "unable to start root hub\n");
retval = -ENOMEM;
goto err_start_root_hub;
@@ -2277,24 +2277,11 @@
if ((rc = start_hc(uhci)) != 0)
return rc;
}
- uhci->hcd.state = USB_STATE_RUNNING;
+ hcd->state = USB_STATE_RUNNING;
return 0;
}
#endif
-static struct usb_hcd *uhci_hcd_alloc(void)
-{
- struct uhci_hcd *uhci;
-
- uhci = (struct uhci_hcd *)kmalloc(sizeof(*uhci), GFP_KERNEL);
- if (!uhci)
- return NULL;
-
- memset(uhci, 0, sizeof(*uhci));
- uhci->hcd.product_desc = "UHCI Host Controller";
- return &uhci->hcd;
-}
-
/* Wait until all the URBs for a particular device/endpoint are gone */
static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
struct usb_host_endpoint *ep)
@@ -2313,6 +2300,8 @@
static const struct hc_driver uhci_driver = {
.description = hcd_name,
+ .product_desc = "UHCI Host Controller",
+ .hcd_priv_size = sizeof(struct uhci_hcd),
/* Generic hardware linkage */
.irq = uhci_irq,
@@ -2326,8 +2315,6 @@
.resume = uhci_resume,
#endif
.stop = uhci_stop,
-
- .hcd_alloc = uhci_hcd_alloc,
.urb_enqueue = uhci_urb_enqueue,
.urb_dequeue = uhci_urb_dequeue,
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h 2005-01-07 15:43:29 -08:00
+++ b/drivers/usb/host/uhci-hcd.h 2005-01-07 15:43:29 -08:00
@@ -314,9 +314,6 @@
UHCI_RESUMING_2
};
-#define hcd_to_uhci(hcd_ptr) container_of(hcd_ptr, struct uhci_hcd, hcd)
-#define uhci_dev(u) ((u)->hcd.self.controller)
-
/*
* This describes the full uhci information.
*
@@ -324,7 +321,6 @@
* a subset of what the full implementation needs.
*/
struct uhci_hcd {
- struct usb_hcd hcd; /* must come first! */
#ifdef CONFIG_PROC_FS
/* procfs */
@@ -382,6 +378,18 @@
wait_queue_head_t waitqh; /* endpoint_disable waiters */
};
+
+/* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
+static inline struct uhci_hcd *hcd_to_uhci(struct usb_hcd *hcd)
+{
+ return (struct uhci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
+{
+ return container_of((void *) uhci, struct usb_hcd, hcd_priv);
+}
+
+#define uhci_dev(u) (uhci_to_hcd(u)->self.controller)
struct urb_priv {
struct list_head urb_list;
ChangeSet 1.1938.446.35, 2004/12/17 15:39:44-08:00, [email protected]
[PATCH] USB: dummy_hcd: update to match the new endpoint changes
Here's the patch to make dummy_hcd build properly once again. I did some
quick light testing to make sure that it still works too. The patch takes
the easy way out by allocating a new private data structure for each URB,
just to keep a single united list of all the outstanding URBs. More
extensive changes would be needed to make effective use of the
per-endpoint queues now available, and it's probably not worth the effort.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/dummy_hcd.c | 60 +++++++++++++++++++++++------------------
1 files changed, 35 insertions(+), 25 deletions(-)
diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:45:03 -08:00
+++ b/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:45:03 -08:00
@@ -65,7 +65,7 @@
#define DRIVER_DESC "USB Host+Gadget Emulator"
-#define DRIVER_VERSION "29 Oct 2004"
+#define DRIVER_VERSION "17 Dec 2004"
static const char driver_name [] = "dummy_hcd";
static const char driver_desc [] = "USB Host+Gadget Emulator";
@@ -143,6 +143,11 @@
#define FIFO_SIZE 64
+struct urbp {
+ struct urb *urb;
+ struct list_head urbp_list;
+};
+
struct dummy {
struct usb_hcd hcd; /* must come first! */
spinlock_t lock;
@@ -168,6 +173,7 @@
unsigned long re_timeout;
struct usb_device *udev;
+ struct list_head urbp_list;
};
static inline struct dummy *hcd_to_dummy (struct usb_hcd *hcd)
@@ -830,16 +836,23 @@
*/
static int dummy_urb_enqueue (
- struct usb_hcd *hcd,
- struct urb *urb,
- int mem_flags
+ struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep,
+ struct urb *urb,
+ int mem_flags
) {
struct dummy *dum;
+ struct urbp *urbp;
unsigned long flags;
if (!urb->transfer_buffer && urb->transfer_buffer_length)
return -EINVAL;
+ urbp = kmalloc (sizeof *urbp, mem_flags);
+ if (!urbp)
+ return -ENOMEM;
+ urbp->urb = urb;
+
dum = hcd_to_dummy (hcd);
spin_lock_irqsave (&dum->lock, flags);
@@ -849,7 +862,8 @@
} else if (unlikely (dum->udev != urb->dev))
dev_err (dummy_dev(dum), "usb_device address has changed!\n");
- urb->hcpriv = dum;
+ list_add_tail (&urbp->urbp_list, &dum->urbp_list);
+ urb->hcpriv = urbp;
if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
urb->error_count = 1; /* mark as a new urb */
@@ -1055,8 +1069,7 @@
static void dummy_timer (unsigned long _dum)
{
struct dummy *dum = (struct dummy *) _dum;
- struct hcd_dev *hdev;
- struct list_head *entry, *tmp;
+ struct urbp *urbp, *tmp;
unsigned long flags;
int limit, total;
int i;
@@ -1088,7 +1101,6 @@
spin_unlock_irqrestore (&dum->lock, flags);
return;
}
- hdev = dum->udev->hcpriv;
for (i = 0; i < DUMMY_ENDPOINTS; i++) {
if (!ep_name [i])
@@ -1097,14 +1109,14 @@
}
restart:
- list_for_each_safe (entry, tmp, &hdev->urb_list) {
+ list_for_each_entry_safe (urbp, tmp, &dum->urbp_list, urbp_list) {
struct urb *urb;
struct dummy_request *req;
u8 address;
struct dummy_ep *ep = 0;
int type;
- urb = list_entry (entry, struct urb, urb_list);
+ urb = urbp->urb;
if (urb->status != -EINPROGRESS) {
/* likely it was just unlinked */
goto return_urb;
@@ -1349,7 +1361,9 @@
continue;
return_urb:
- urb->hcpriv = 0;
+ urb->hcpriv = NULL;
+ list_del (&urbp->urbp_list);
+ kfree (urbp);
if (ep)
ep->already_seen = ep->setup_stage = 0;
@@ -1361,7 +1375,7 @@
}
/* want a 1 msec delay here */
- if (!list_empty (&hdev->urb_list))
+ if (!list_empty (&dum->urbp_list))
mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
else {
usb_put_dev (dum->udev);
@@ -1601,21 +1615,17 @@
{
struct usb_hcd *hcd = dev_get_drvdata (dev);
struct dummy *dum = hcd_to_dummy (hcd);
- struct urb *urb;
+ struct urbp *urbp;
size_t size = 0;
unsigned long flags;
- struct hcd_dev *hdev;
spin_lock_irqsave (&dum->lock, flags);
- if (dum->udev) {
- hdev = dum->udev->hcpriv;
- list_for_each_entry (urb, &hdev->urb_list, urb_list) {
- size_t temp;
-
- temp = show_urb (buf, PAGE_SIZE - size, urb);
- buf += temp;
- size += temp;
- }
+ list_for_each_entry (urbp, &dum->urbp_list, urbp_list) {
+ size_t temp;
+
+ temp = show_urb (buf, PAGE_SIZE - size, urbp->urb);
+ buf += temp;
+ size += temp;
}
spin_unlock_irqrestore (&dum->lock, flags);
@@ -1642,6 +1652,8 @@
dum->timer.function = dummy_timer;
dum->timer.data = (unsigned long) dum;
+ INIT_LIST_HEAD (&dum->urbp_list);
+
root = usb_alloc_dev (0, &hcd->self, 0);
if (!root)
return -ENOMEM;
@@ -1754,8 +1766,6 @@
hcd->self.hcpriv = hcd;
hcd->self.bus_name = dev->bus_id;
hcd->product_desc = "Dummy host controller";
-
- INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (&hcd->self);
ChangeSet 1.1938.446.39, 2004/12/20 10:37:42-08:00, [email protected]
USB: change warning level in ftdi_sio driver of a debug message.
This keeps users happy as it really isn't an error.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/ftdi_sio.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c 2005-01-07 15:44:16 -08:00
+++ b/drivers/usb/serial/ftdi_sio.c 2005-01-07 15:44:16 -08:00
@@ -1651,7 +1651,7 @@
dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
if (count == 0) {
- err("write request of 0 bytes");
+ dbg("write request of 0 bytes");
return 0;
}
ChangeSet 1.1938.446.42, 2004/12/20 14:19:05-08:00, [email protected]
[PATCH] USB: Create usb_hcd structures within usbcore [3/13]
This patch alters the OHCI driver, removing the routine that allocates the
hcd structure and introducing inline functions to convert safely between
the public and private hcd structures. It also moves the code to
initialize the private structure into the reset routine, since the
allocation routine is now gone. That particular aspect should be reviewed
by David, but for now it seems to work.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ohci-dbg.c | 22 +++++++++++++---------
drivers/usb/host/ohci-hcd.c | 34 +++++++++++++++++-----------------
drivers/usb/host/ohci-hub.c | 27 +++++++++++++--------------
drivers/usb/host/ohci-mem.c | 25 +++++++++----------------
drivers/usb/host/ohci-pci.c | 8 +++-----
drivers/usb/host/ohci-q.c | 32 ++++++++++++++++----------------
drivers/usb/host/ohci.h | 25 ++++++++++++++-----------
7 files changed, 85 insertions(+), 88 deletions(-)
diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
--- a/drivers/usb/host/ohci-dbg.c 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci-dbg.c 2005-01-07 15:43:40 -08:00
@@ -676,19 +676,23 @@
static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
-static inline void create_debug_files (struct ohci_hcd *bus)
+static inline void create_debug_files (struct ohci_hcd *ohci)
{
- class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_async);
- class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
- class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
- ohci_dbg (bus, "created debug files\n");
+ struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev;
+
+ class_device_create_file(cldev, &class_device_attr_async);
+ class_device_create_file(cldev, &class_device_attr_periodic);
+ class_device_create_file(cldev, &class_device_attr_registers);
+ ohci_dbg (ohci, "created debug files\n");
}
-static inline void remove_debug_files (struct ohci_hcd *bus)
+static inline void remove_debug_files (struct ohci_hcd *ohci)
{
- class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_async);
- class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
- class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
+ struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev;
+
+ class_device_remove_file(cldev, &class_device_attr_async);
+ class_device_remove_file(cldev, &class_device_attr_periodic);
+ class_device_remove_file(cldev, &class_device_attr_registers);
}
#endif
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci-hcd.c 2005-01-07 15:43:40 -08:00
@@ -240,7 +240,7 @@
spin_lock_irqsave (&ohci->lock, flags);
/* don't submit to a dead HC */
- if (!HCD_IS_RUNNING(ohci->hcd.state)) {
+ if (!HCD_IS_RUNNING(hcd->state)) {
retval = -ENODEV;
goto fail;
}
@@ -308,7 +308,7 @@
#endif
spin_lock_irqsave (&ohci->lock, flags);
- if (HCD_IS_RUNNING(ohci->hcd.state)) {
+ if (HCD_IS_RUNNING(hcd->state)) {
urb_priv_t *urb_priv;
/* Unless an IRQ completed the unlink while it was being
@@ -355,7 +355,7 @@
rescan:
spin_lock_irqsave (&ohci->lock, flags);
- if (!HCD_IS_RUNNING (ohci->hcd.state)) {
+ if (!HCD_IS_RUNNING (hcd->state)) {
sanitize:
ed->state = ED_IDLE;
finish_unlinks (ohci, 0, NULL);
@@ -420,7 +420,7 @@
int ret;
disable (ohci);
- ohci->regs = ohci->hcd.regs;
+ ohci->regs = ohci_to_hcd(ohci)->regs;
ohci->next_statechange = jiffies;
#ifndef IR_DISABLE
@@ -456,13 +456,13 @@
if (ohci->hcca)
return 0;
- ohci->hcca = dma_alloc_coherent (ohci->hcd.self.controller,
+ ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller,
sizeof *ohci->hcca, &ohci->hcca_dma, 0);
if (!ohci->hcca)
return -ENOMEM;
if ((ret = ohci_mem_init (ohci)) < 0)
- ohci_stop (&ohci->hcd);
+ ohci_stop (ohci_to_hcd(ohci));
return ret;
@@ -507,7 +507,7 @@
if (ohci->hc_control & OHCI_CTRL_RWC
&& !(ohci->flags & OHCI_QUIRK_AMD756))
- ohci->hcd.can_wakeup = 1;
+ ohci_to_hcd(ohci)->can_wakeup = 1;
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
@@ -605,7 +605,7 @@
ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
- ohci->hcd.state = USB_STATE_RUNNING;
+ ohci_to_hcd(ohci)->state = USB_STATE_RUNNING;
/* wake on ConnectStatusChange, matching external hubs */
ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
@@ -645,12 +645,12 @@
// POTPGT delay is bits 24-31, in 2 ms units.
mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
- bus = hcd_to_bus (&ohci->hcd);
- ohci->hcd.state = USB_STATE_RUNNING;
+ bus = &ohci_to_hcd(ohci)->self;
+ ohci_to_hcd(ohci)->state = USB_STATE_RUNNING;
ohci_dump (ohci, 1);
- udev = hcd_to_bus (&ohci->hcd)->root_hub;
+ udev = bus->root_hub;
if (udev) {
return 0;
}
@@ -665,7 +665,7 @@
}
udev->speed = USB_SPEED_FULL;
- if (hcd_register_root (udev, &ohci->hcd) != 0) {
+ if (hcd_register_root (udev, ohci_to_hcd(ohci)) != 0) {
usb_put_dev (udev);
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
@@ -740,11 +740,11 @@
if (ohci->ed_rm_list)
finish_unlinks (ohci, ohci_frame_no(ohci), ptregs);
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
- && HCD_IS_RUNNING(ohci->hcd.state))
+ && HCD_IS_RUNNING(hcd->state))
ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable);
spin_unlock (&ohci->lock);
- if (HCD_IS_RUNNING(ohci->hcd.state)) {
+ if (HCD_IS_RUNNING(hcd->state)) {
ohci_writel (ohci, ints, ®s->intrstatus);
ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable);
// flush those writes
@@ -762,7 +762,7 @@
ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
- ohci->hcd.state);
+ hcd->state);
ohci_dump (ohci, 1);
flush_scheduled_work();
@@ -773,7 +773,7 @@
remove_debug_files (ohci);
ohci_mem_cleanup (ohci);
if (ohci->hcca) {
- dma_free_coherent (ohci->hcd.self.controller,
+ dma_free_coherent (hcd->self.controller,
sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
ohci->hcca = NULL;
@@ -792,7 +792,7 @@
int temp;
int i;
struct urb_priv *priv;
- struct usb_device *root = ohci->hcd.self.root_hub;
+ struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub;
/* mark any devices gone, so they do nothing till khubd disconnects.
* recycle any "live" eds/tds (and urbs) right away.
diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci-hub.c 2005-01-07 15:43:40 -08:00
@@ -73,7 +73,7 @@
ohci_dbg (ohci, "suspend root hub\n");
/* First stop any processing */
- ohci->hcd.state = USB_STATE_QUIESCING;
+ hcd->state = USB_STATE_QUIESCING;
if (ohci->hc_control & OHCI_SCHED_ENABLES) {
int limit;
@@ -103,7 +103,7 @@
&ohci->regs->intrstatus);
/* maybe resume can wake root hub */
- if (ohci->hcd.remote_wakeup)
+ if (hcd->remote_wakeup)
ohci->hc_control |= OHCI_CTRL_RWE;
else
ohci->hc_control &= ~OHCI_CTRL_RWE;
@@ -119,7 +119,7 @@
done:
if (status == 0)
- ohci->hcd.state = HCD_STATE_SUSPENDED;
+ hcd->state = HCD_STATE_SUSPENDED;
spin_unlock_irqrestore (&ohci->lock, flags);
return status;
}
@@ -198,7 +198,7 @@
}
/* Some controllers (lucent) need extra-long delays */
- ohci->hcd.state = USB_STATE_RESUMING;
+ hcd->state = USB_STATE_RESUMING;
mdelay (20 /* usb 11.5.1.10 */ + 15);
temp = ohci_readl (ohci, &ohci->regs->control);
@@ -231,7 +231,7 @@
msleep (3);
temp = OHCI_CONTROL_INIT | OHCI_USB_OPER;
- if (ohci->hcd.can_wakeup)
+ if (hcd->can_wakeup)
temp |= OHCI_CTRL_RWC;
ohci->hc_control = temp;
ohci_writel (ohci, temp, &ohci->regs->control);
@@ -261,8 +261,7 @@
temp |= OHCI_BLF;
}
}
- if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs
- || hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs)
+ if (hcd->self.bandwidth_isoc_reqs || hcd->self.bandwidth_int_reqs)
enables |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
if (enables) {
ohci_dbg (ohci, "restarting schedules ... %08x\n", enables);
@@ -273,7 +272,7 @@
(void) ohci_readl (ohci, &ohci->regs->control);
}
- ohci->hcd.state = USB_STATE_RUNNING;
+ hcd->state = USB_STATE_RUNNING;
return 0;
}
@@ -314,7 +313,7 @@
* letting khubd or root hub timer see state changes.
*/
if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
- || !HCD_IS_RUNNING(ohci->hcd.state)) {
+ || !HCD_IS_RUNNING(hcd->state)) {
can_suspend = 0;
goto done;
}
@@ -356,7 +355,7 @@
*/
if (!(status & RH_PS_CCS))
continue;
- if ((status & RH_PS_PSS) && ohci->hcd.remote_wakeup)
+ if ((status & RH_PS_PSS) && hcd->remote_wakeup)
continue;
can_suspend = 0;
}
@@ -378,8 +377,8 @@
&& usb_trylock_device (hcd->self.root_hub)
) {
ohci_vdbg (ohci, "autosuspend\n");
- (void) ohci_hub_suspend (&ohci->hcd);
- ohci->hcd.state = USB_STATE_RUNNING;
+ (void) ohci_hub_suspend (hcd);
+ hcd->state = USB_STATE_RUNNING;
usb_unlock_device (hcd->self.root_hub);
}
#endif
@@ -613,8 +612,8 @@
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
#ifdef CONFIG_USB_OTG
- if (ohci->hcd.self.otg_port == (wIndex + 1)
- && ohci->hcd.self.b_hnp_enable)
+ if (hcd->self.otg_port == (wIndex + 1)
+ && hcd->self.b_hnp_enable)
start_hnp(ohci);
else
#endif
diff -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
--- a/drivers/usb/host/ohci-mem.c 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci-mem.c 2005-01-07 15:43:40 -08:00
@@ -23,34 +23,27 @@
/*-------------------------------------------------------------------------*/
-static struct usb_hcd *ohci_hcd_alloc (void)
+static void ohci_hcd_init (struct ohci_hcd *ohci)
{
- struct ohci_hcd *ohci;
-
- ohci = (struct ohci_hcd *) kmalloc (sizeof *ohci, GFP_KERNEL);
- if (ohci != 0) {
- memset (ohci, 0, sizeof (struct ohci_hcd));
- ohci->hcd.product_desc = "OHCI Host Controller";
- ohci->next_statechange = jiffies;
- spin_lock_init (&ohci->lock);
- INIT_LIST_HEAD (&ohci->pending);
- INIT_WORK (&ohci->rh_resume, ohci_rh_resume, &ohci->hcd);
- return &ohci->hcd;
- }
- return NULL;
+ ohci->next_statechange = jiffies;
+ spin_lock_init (&ohci->lock);
+ INIT_LIST_HEAD (&ohci->pending);
+ INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
}
/*-------------------------------------------------------------------------*/
static int ohci_mem_init (struct ohci_hcd *ohci)
{
- ohci->td_cache = dma_pool_create ("ohci_td", ohci->hcd.self.controller,
+ ohci->td_cache = dma_pool_create ("ohci_td",
+ ohci_to_hcd(ohci)->self.controller,
sizeof (struct td),
32 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->td_cache)
return -ENOMEM;
- ohci->ed_cache = dma_pool_create ("ohci_ed", ohci->hcd.self.controller,
+ ohci->ed_cache = dma_pool_create ("ohci_ed",
+ ohci_to_hcd(ohci)->self.controller,
sizeof (struct ed),
16 /* byte alignment */,
0 /* no page-crossing issues */);
diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- a/drivers/usb/host/ohci-pci.c 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci-pci.c 2005-01-07 15:43:40 -08:00
@@ -35,6 +35,7 @@
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ ohci_hcd_init (ohci);
return ohci_init (ohci);
}
@@ -172,6 +173,8 @@
static const struct hc_driver ohci_pci_hc_driver = {
.description = hcd_name,
+ .product_desc = "OHCI Host Controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
/*
* generic hardware linkage
@@ -189,11 +192,6 @@
.resume = ohci_pci_resume,
#endif
.stop = ohci_stop,
-
- /*
- * memory lifecycle (except per-request)
- */
- .hcd_alloc = ohci_hcd_alloc,
/*
* managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci-q.c 2005-01-07 15:43:40 -08:00
@@ -60,10 +60,10 @@
switch (usb_pipetype (urb->pipe)) {
case PIPE_ISOCHRONOUS:
- hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs--;
+ ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
break;
case PIPE_INTERRUPT:
- hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs--;
+ ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
break;
}
@@ -73,12 +73,12 @@
/* urb->complete() can reenter this HCD */
spin_unlock (&ohci->lock);
- usb_hcd_giveback_urb (&ohci->hcd, urb, regs);
+ usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb, regs);
spin_lock (&ohci->lock);
/* stop periodic dma if it's not needed */
- if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0
- && hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0) {
+ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
+ && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0) {
ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE);
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
}
@@ -163,7 +163,7 @@
}
ohci->load [i] += ed->load;
}
- hcd_to_bus (&ohci->hcd)->bandwidth_allocated += ed->load / ed->interval;
+ ohci_to_hcd(ohci)->self.bandwidth_allocated += ed->load / ed->interval;
}
/* link an ed into one of the HC chains */
@@ -172,7 +172,7 @@
{
int branch;
- if (ohci->hcd.state == USB_STATE_QUIESCING)
+ if (ohci_to_hcd(ohci)->state == USB_STATE_QUIESCING)
return -EAGAIN;
ed->state = ED_OPER;
@@ -276,7 +276,7 @@
}
ohci->load [i] -= ed->load;
}
- hcd_to_bus (&ohci->hcd)->bandwidth_allocated -= ed->load / ed->interval;
+ ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval;
ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
@@ -619,8 +619,8 @@
*/
case PIPE_INTERRUPT:
/* ... and periodic urbs have extra accounting */
- periodic = hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs++ == 0
- && hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0;
+ periodic = ohci_to_hcd(ohci)->self.bandwidth_int_reqs++ == 0
+ && ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0;
/* FALLTHROUGH */
case PIPE_BULK:
info = is_out
@@ -688,8 +688,8 @@
data + urb->iso_frame_desc [cnt].offset,
urb->iso_frame_desc [cnt].length, urb, cnt);
}
- periodic = hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs++ == 0
- && hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0;
+ periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
+ && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
break;
}
@@ -920,7 +920,7 @@
/* only take off EDs that the HC isn't using, accounting for
* frame counter wraps and EDs with partially retired TDs
*/
- if (likely (regs && HCD_IS_RUNNING(ohci->hcd.state))) {
+ if (likely (regs && HCD_IS_RUNNING(ohci_to_hcd(ohci)->state))) {
if (tick_before (tick, ed->tick)) {
skip_ed:
last = &ed->ed_next;
@@ -1002,7 +1002,7 @@
/* but if there's work queued, reschedule */
if (!list_empty (&ed->td_list)) {
- if (HCD_IS_RUNNING(ohci->hcd.state))
+ if (HCD_IS_RUNNING(ohci_to_hcd(ohci)->state))
ed_schedule (ohci, ed);
}
@@ -1011,8 +1011,8 @@
}
/* maybe reenable control and bulk lists */
- if (HCD_IS_RUNNING(ohci->hcd.state)
- && ohci->hcd.state != USB_STATE_QUIESCING
+ if (HCD_IS_RUNNING(ohci_to_hcd(ohci)->state)
+ && ohci_to_hcd(ohci)->state != USB_STATE_QUIESCING
&& !ohci->ed_rm_list) {
u32 command = 0, control = 0;
diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h 2005-01-07 15:43:40 -08:00
+++ b/drivers/usb/host/ohci.h 2005-01-07 15:43:40 -08:00
@@ -345,11 +345,6 @@
*/
struct ohci_hcd {
- /*
- * framework state
- */
- struct usb_hcd hcd; /* must come first! */
-
spinlock_t lock;
/*
@@ -405,7 +400,15 @@
};
-#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
+/* convert between an hcd pointer and the corresponding ohci_hcd */
+static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd)
+{
+ return (struct ohci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)
+{
+ return container_of ((void *) ohci, struct usb_hcd, hcd_priv);
+}
/*-------------------------------------------------------------------------*/
@@ -414,13 +417,13 @@
#endif /* DEBUG */
#define ohci_dbg(ohci, fmt, args...) \
- dev_dbg ((ohci)->hcd.self.controller , fmt , ## args )
+ dev_dbg (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
#define ohci_err(ohci, fmt, args...) \
- dev_err ((ohci)->hcd.self.controller , fmt , ## args )
+ dev_err (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
#define ohci_info(ohci, fmt, args...) \
- dev_info ((ohci)->hcd.self.controller , fmt , ## args )
+ dev_info (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
#define ohci_warn(ohci, fmt, args...) \
- dev_warn ((ohci)->hcd.self.controller , fmt , ## args )
+ dev_warn (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
#ifdef OHCI_VERBOSE_DEBUG
# define ohci_vdbg ohci_dbg
@@ -553,7 +556,7 @@
static inline void disable (struct ohci_hcd *ohci)
{
- ohci->hcd.state = USB_STATE_HALT;
+ ohci_to_hcd(ohci)->state = USB_STATE_HALT;
}
#define FI 0x2edf /* 12000 bits per frame (-1) */
ChangeSet 1.1938.444.1, 2004/12/15 10:48:19-08:00, [email protected]
[PATCH] add class_device to miscdevice
Currently misc_register() throws away the return from
class_simple_device_add(). This makes it impossible to get to the
class_device of the directories in /sys/class/misc and, for example,
thus impossible to add attributes to those directories.
Attached patch adds a class_device structure to the miscdevice structure
and assigns to it the value returned from class_simple_device_add() in
misc_register(), thus caching the value and allowing us to f.e. later
call class_device_create_file().
We need this for inotify, but I can see plenty of other misc. devices
wanting this and consider it missing but required functionality.
Add the class_device structure to miscdevice so that we can add sysfs
attributes to /sys/class/misc/foo
Signed-Off-By: Robert Love <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/char/misc.c | 14 ++++++--------
include/linux/miscdevice.h | 5 +++--
2 files changed, 9 insertions(+), 10 deletions(-)
diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c
--- a/drivers/char/misc.c 2005-01-07 15:52:07 -08:00
+++ b/drivers/char/misc.c 2005-01-07 15:52:07 -08:00
@@ -207,10 +207,9 @@
int misc_register(struct miscdevice * misc)
{
struct miscdevice *c;
- struct class_device *class;
dev_t dev;
int err;
-
+
down(&misc_sem);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
@@ -224,8 +223,7 @@
while (--i >= 0)
if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
break;
- if (i<0)
- {
+ if (i<0) {
up(&misc_sem);
return -EBUSY;
}
@@ -240,10 +238,10 @@
}
dev = MKDEV(MISC_MAJOR, misc->minor);
- class = class_simple_device_add(misc_class, dev,
- misc->dev, misc->name);
- if (IS_ERR(class)) {
- err = PTR_ERR(class);
+ misc->class = class_simple_device_add(misc_class, dev,
+ misc->dev, misc->name);
+ if (IS_ERR(misc->class)) {
+ err = PTR_ERR(misc->class);
goto out;
}
diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
--- a/include/linux/miscdevice.h 2005-01-07 15:52:07 -08:00
+++ b/include/linux/miscdevice.h 2005-01-07 15:52:07 -08:00
@@ -2,6 +2,7 @@
#define _LINUX_MISCDEVICE_H
#include <linux/module.h>
#include <linux/major.h>
+#include <linux/device.h>
#define PSMOUSE_MINOR 1
#define MS_BUSMOUSE_MINOR 2
@@ -32,13 +33,13 @@
struct device;
-struct miscdevice
-{
+struct miscdevice {
int minor;
const char *name;
struct file_operations *fops;
struct list_head list;
struct device *dev;
+ struct class_device *class;
char devfs_name[64];
};
ChangeSet 1.1938.446.38, 2004/12/17 16:11:38-08:00, [email protected]
[PATCH] Clean mct_u232 in 2.6.10-rc2
I would like to clean up mct_u232 a little bit, although primarily to make
my fixes to 2.4 branch look better. The attached patch does this:
- zeroes whole private structure
- zaps dangling pointer (or why do we check it then)
- removes unused code for FIX_WRITE_RETURN_CODE_PROBLEM
- changes version
- makes the diagnostic name not quite as pompous
- makes debugging printouts a little more informative
From: Pete Zaitcev <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/mct_u232.c | 148 +++---------------------------------------
1 files changed, 12 insertions(+), 136 deletions(-)
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c 2005-01-07 15:44:27 -08:00
+++ b/drivers/usb/serial/mct_u232.c 2005-01-07 15:44:27 -08:00
@@ -82,21 +82,10 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.2"
+#define DRIVER_VERSION "z2.0" /* Linux in-kernel version */
#define DRIVER_AUTHOR "Wolfgang Grandegger <[email protected]>"
#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
-/*
- * Some not properly written applications do not handle the return code of
- * write() correctly. This can result in character losses. A work-a-round
- * can be compiled in with the following definition. This work-a-round
- * should _NOT_ be part of an 'official' kernel release, of course!
- */
-#undef FIX_WRITE_RETURN_CODE_PROBLEM
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int write_blocking; /* disabled by default */
-#endif
-
static int debug;
/*
@@ -108,12 +97,6 @@
struct file *filp);
static void mct_u232_close (struct usb_serial_port *port,
struct file *filp);
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int mct_u232_write (struct usb_serial_port *port,
- const unsigned char *buf,
- int count);
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-#endif
static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs);
static void mct_u232_set_termios (struct usb_serial_port *port,
struct termios * old);
@@ -151,7 +134,7 @@
static struct usb_serial_device_type mct_u232_device = {
.owner = THIS_MODULE,
- .name = "Magic Control Technology USB-RS232",
+ .name = "MCT U232",
.short_name = "mct_u232",
.id_table = id_table_combined,
.num_interrupt_in = 2,
@@ -160,10 +143,6 @@
.num_ports = 1,
.open = mct_u232_open,
.close = mct_u232_close,
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
- .write = mct_u232_write,
- .write_bulk_callback = mct_u232_write_bulk_callback,
-#endif
.read_int_callback = mct_u232_read_int_callback,
.ioctl = mct_u232_ioctl,
.set_termios = mct_u232_set_termios,
@@ -366,15 +345,11 @@
struct mct_u232_private *priv;
struct usb_serial_port *port, *rport;
- /* allocate the private data structure */
priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- /* set initial values for control structures */
+ memset(priv, 0, sizeof(struct mct_u232_private));
spin_lock_init(&priv->lock);
- priv->control_state = 0;
- priv->last_lsr = 0;
- priv->last_msr = 0;
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
@@ -404,8 +379,10 @@
for (i=0; i < serial->num_ports; ++i) {
/* My special items, the standard routines free my urbs */
priv = usb_get_serial_port_data(serial->port[i]);
- if (priv)
+ if (priv) {
+ usb_set_serial_port_data(serial->port[i], NULL);
kfree(priv);
+ }
}
} /* mct_u232_shutdown */
@@ -459,14 +436,16 @@
port->read_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (retval) {
- err("usb_submit_urb(read bulk) failed");
+ err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
+ port->read_urb->pipe, retval);
goto exit;
}
port->interrupt_in_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval)
- err(" usb_submit_urb(read int) failed");
+ err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
+ port->interrupt_in_urb->pipe, retval);
exit:
return 0;
@@ -486,101 +465,6 @@
} /* mct_u232_close */
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-/* The generic routines work fine otherwise */
-
-static int mct_u232_write (struct usb_serial_port *port,
- const unsigned char *buf, int count)
-{
- struct usb_serial *serial = port->serial;
- int result, bytes_sent, size;
-
- dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (count == 0) {
- dbg("%s - write request of 0 bytes", __FUNCTION__);
- return (0);
- }
-
- /* only do something if we have a bulk out endpoint */
- if (!serial->num_bulk_out)
- return(0);
-
- /* another write is still pending? */
- if (port->write_urb->status == -EINPROGRESS) {
- dbg("%s - already writing", __FUNCTION__);
- return (0);
- }
-
- bytes_sent = 0;
- while (count > 0) {
- size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-
- usb_serial_debug_data(debug, &port->dev, __FUNCTION__, size, buf);
-
- memcpy (port->write_urb->transfer_buffer, buf, size);
-
- /* set up our urb */
- usb_fill_bulk_urb(port->write_urb, serial->dev,
- usb_sndbulkpipe(serial->dev,
- port->bulk_out_endpointAddress),
- port->write_urb->transfer_buffer, size,
- ((serial->type->write_bulk_callback) ?
- serial->type->write_bulk_callback :
- mct_u232_write_bulk_callback),
- port);
-
- /* send the data out the bulk port */
- result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
- if (result) {
- err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
- return result;
- }
-
- bytes_sent += size;
- if (write_blocking)
- interruptible_sleep_on(&port->write_wait);
- else
- break;
-
- buf += size;
- count -= size;
- }
-
- return bytes_sent;
-} /* mct_u232_write */
-
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
- struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- struct usb_serial *serial = port->serial;
- struct tty_struct *tty = port->tty;
-
- dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (!serial) {
- dbg("%s - bad serial pointer, exiting", __FUNCTION__);
- return;
- }
-
- if (urb->status) {
- dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
- urb->status);
- return;
- }
-
- if (write_blocking) {
- wake_up_interruptible(&port->write_wait);
- tty_wakeup(tty);
- } else {
- /* from generic_write_bulk_callback */
- schedule_work(&port->work);
- }
-
- return;
-} /* mct_u232_write_bulk_callback */
-#endif
-
static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -591,8 +475,6 @@
int status;
unsigned long flags;
- dbg("%s - port %d", __FUNCTION__, port->number);
-
switch (urb->status) {
case 0:
/* success */
@@ -612,7 +494,8 @@
dbg("%s - bad serial pointer, exiting", __FUNCTION__);
return;
}
-
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
/*
@@ -893,12 +776,5 @@
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-module_param(write_blocking, int, 0);
-MODULE_PARM_DESC(write_blocking,
- "The write function will block to write out all data");
-#endif
-
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-
ChangeSet 1.1938.446.40, 2004/12/20 14:17:44-08:00, [email protected]
[PATCH] USB: Create usb_hcd structures within usbcore [1/13]
This patch changes the usbcore routines, making them fully responsible for
the entire lifecycle of each usb_hcd. It also splits up registration of
the USB host class_device into an _init and an _add phase, to match the
initialization and registration of the USB bus belonging to the host.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hcd-pci.c | 21 +++-------------
drivers/usb/core/hcd.c | 59 ++++++++++++++++++++++++++++++++++++---------
drivers/usb/core/hcd.h | 27 +++++++++-----------
3 files changed, 66 insertions(+), 41 deletions(-)
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c 2005-01-07 15:44:04 -08:00
+++ b/drivers/usb/core/hcd-pci.c 2005-01-07 15:44:04 -08:00
@@ -124,7 +124,7 @@
// driver->reset(), later on, will transfer device from
// control by SMM/BIOS to control by Linux (if needed)
- hcd = driver->hcd_alloc ();
+ hcd = usb_create_hcd (driver);
if (hcd == NULL){
dev_dbg (&dev->dev, "hcd alloc fail\n");
retval = -ENOMEM;
@@ -144,20 +144,16 @@
hcd->region = region;
pci_set_drvdata (dev, hcd);
- hcd->driver = driver;
- hcd->description = driver->description;
hcd->self.bus_name = pci_name(dev);
#ifdef CONFIG_PCI_NAMES
hcd->product_desc = dev->pretty_name;
-#else
- if (hcd->product_desc == NULL)
- hcd->product_desc = "USB Host Controller";
#endif
hcd->self.controller = &dev->dev;
if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
- kfree (hcd);
+ pci_set_drvdata (dev, NULL);
+ usb_put_hcd (hcd);
goto clean_2;
}
@@ -168,7 +164,6 @@
dev_err (hcd->self.controller, "can't reset\n");
goto clean_3;
}
- hcd->state = USB_STATE_HALT;
pci_set_master (dev);
#ifndef __sparc__
@@ -177,7 +172,7 @@
bufp = __irq_itoa(dev->irq);
#endif
retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
- hcd->description, hcd);
+ hcd->driver->description, hcd);
if (retval != 0) {
dev_err (hcd->self.controller,
"request interrupt %s failed\n", bufp);
@@ -189,12 +184,6 @@
(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
resource);
- usb_bus_init (&hcd->self);
- hcd->self.op = &usb_hcd_operations;
- hcd->self.release = &usb_hcd_release;
- hcd->self.hcpriv = (void *) hcd;
- init_timer (&hcd->rh_timer);
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0) {
@@ -409,7 +398,7 @@
pci_set_power_state (dev, 0);
dev->dev.power.power_state = 0;
retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
- hcd->description, hcd);
+ hcd->driver->description, hcd);
if (retval < 0) {
dev_err (hcd->self.controller,
"can't restore IRQ after resume!\n");
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:44:04 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:44:04 -08:00
@@ -312,7 +312,7 @@
// id 3 == vendor description
} else if (id == 3) {
sprintf (buf, "%s %s %s", UTS_SYSNAME, UTS_RELEASE,
- hcd->description);
+ hcd->driver->description);
// unsupported IDs --> "protocol stall"
} else
@@ -676,6 +676,8 @@
bus->bandwidth_isoc_reqs = 0;
INIT_LIST_HEAD (&bus->bus_list);
+
+ class_device_initialize(&bus->class_dev);
}
EXPORT_SYMBOL (usb_bus_init);
@@ -734,7 +736,7 @@
snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
bus->class_dev.class = &usb_host_class;
bus->class_dev.dev = bus->controller;
- retval = class_device_register(&bus->class_dev);
+ retval = class_device_add(&bus->class_dev);
if (retval) {
clear_bit(busnum, busmap.busmap);
up(&usb_bus_list_lock);
@@ -1430,12 +1432,8 @@
/*
* usb_hcd_operations - adapts usb_bus framework to HCD framework (bus glue)
- *
- * When registering a USB bus through the HCD framework code, use this
- * usb_operations vector. The PCI glue layer does so automatically; only
- * bus glue for non-PCI system busses will need to use this.
*/
-struct usb_operations usb_hcd_operations = {
+static struct usb_operations usb_hcd_operations = {
.get_frame_number = hcd_get_frame_number,
.submit_urb = hcd_submit_urb,
.unlink_urb = hcd_unlink_urb,
@@ -1447,7 +1445,6 @@
.hub_resume = hcd_hub_resume,
#endif
};
-EXPORT_SYMBOL (usb_hcd_operations);
/*-------------------------------------------------------------------------*/
@@ -1549,11 +1546,51 @@
/*-------------------------------------------------------------------------*/
-void usb_hcd_release(struct usb_bus *bus)
+static void hcd_release (struct usb_bus *bus)
{
struct usb_hcd *hcd;
- hcd = container_of (bus, struct usb_hcd, self);
+ hcd = container_of(bus, struct usb_hcd, self);
kfree(hcd);
}
-EXPORT_SYMBOL (usb_hcd_release);
+
+/**
+ * usb_create_hcd - create and initialize an HCD structure
+ * @driver: HC driver that will use this hcd
+ * Context: !in_interrupt()
+ *
+ * Allocate a struct usb_hcd, with extra space at the end for the
+ * HC driver's private data. Initialize the generic members of the
+ * hcd structure.
+ *
+ * If memory is unavailable, returns NULL.
+ */
+struct usb_hcd *usb_create_hcd (const struct hc_driver *driver)
+{
+ struct usb_hcd *hcd;
+
+ hcd = kcalloc(1, sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
+ if (!hcd)
+ return NULL;
+
+ usb_bus_init(&hcd->self);
+ hcd->self.op = &usb_hcd_operations;
+ hcd->self.hcpriv = hcd;
+ hcd->self.release = &hcd_release;
+
+ init_timer(&hcd->rh_timer);
+
+ hcd->driver = driver;
+ hcd->product_desc = (driver->product_desc) ? driver->product_desc :
+ "USB Host Controller";
+ hcd->state = USB_STATE_HALT;
+
+ return hcd;
+}
+EXPORT_SYMBOL (usb_create_hcd);
+
+void usb_put_hcd (struct usb_hcd *hcd)
+{
+ usb_bus_put(&hcd->self);
+}
+EXPORT_SYMBOL (usb_put_hcd);
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h 2005-01-07 15:44:04 -08:00
+++ b/drivers/usb/core/hcd.h 2005-01-07 15:44:04 -08:00
@@ -63,14 +63,13 @@
struct usb_bus self; /* hcd is-a bus */
const char *product_desc; /* product/vendor string */
- const char *description; /* "ehci-hcd" etc */
struct timer_list rh_timer; /* drives root hub */
/*
* hardware info/state
*/
- struct hc_driver *driver; /* hw-specific hooks */
+ const struct hc_driver *driver; /* hw-specific hooks */
unsigned saw_irq : 1;
unsigned can_wakeup:1; /* hw supports wakeup? */
unsigned remote_wakeup:1;/* sw should use wakeup? */
@@ -103,6 +102,12 @@
* input size of periodic table to an interrupt scheduler.
* (ohci 32, uhci 1024, ehci 256/512/1024).
*/
+
+ /* The HC driver's private data is stored at the end of
+ * this structure.
+ */
+ unsigned long hcd_priv[0]
+ __attribute__ ((aligned (sizeof(unsigned long))));
};
/* 2.4 does this a bit differently ... */
@@ -152,6 +157,8 @@
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
+ const char *product_desc; /* product/vendor string */
+ size_t hcd_priv_size; /* size of private data */
/* irq handler */
irqreturn_t (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
@@ -180,15 +187,6 @@
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
- /* memory lifecycle */
- /* Note: The absence of hcd_free reflects a temporary situation;
- * in the near future hcd_alloc will disappear as well and all
- * allocations/deallocations will be handled by usbcore. For the
- * moment, drivers are required to return a pointer that the core
- * can pass to kfree, i.e., the struct usb_hcd must be the _first_
- * member of a larger driver-specific structure. */
- struct usb_hcd *(*hcd_alloc) (void);
-
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
@@ -213,6 +211,10 @@
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
extern void usb_bus_init (struct usb_bus *bus);
+extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver);
+extern void usb_put_hcd (struct usb_hcd *hcd);
+
+
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
@@ -237,7 +239,6 @@
void *addr, dma_addr_t dma);
/* generic bus glue, needed for host controllers that don't use PCI */
-extern struct usb_operations usb_hcd_operations;
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void usb_hc_died (struct usb_hcd *hcd);
@@ -356,8 +357,6 @@
return usb_register_root_hub (usb_dev, hcd->self.controller);
}
-
-extern void usb_hcd_release (struct usb_bus *);
extern void usb_set_device_state(struct usb_device *udev,
enum usb_device_state new_state);
ChangeSet 1.1938.446.36, 2004/12/17 15:40:33-08:00, [email protected]
[PATCH] Re: garmin gps driver patch 0.23
From: Hermann Kneissel <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/Kconfig | 13
drivers/usb/serial/Makefile | 1
drivers/usb/serial/garmin_gps.c | 1542 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 1556 insertions(+)
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig 2005-01-07 15:44:51 -08:00
+++ b/drivers/usb/serial/Kconfig 2005-01-07 15:44:51 -08:00
@@ -202,6 +202,19 @@
To compile this driver as a module, choose M here: the
module will be called io_ti.
+config USB_SERIAL_GARMIN
+ tristate "Garmin GPS driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to connect to your Garmin GPS.
+ Should work with most Garmin GPS devices which have a native USB port.
+
+ See <http://sourceforge.net/projects/garmin-gps> for the latest
+ version of the driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called garmin_gps.
+
config USB_SERIAL_IPW
tristate "USB IPWireless (3G UMTS TDD) Driver (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
diff -Nru a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
--- a/drivers/usb/serial/Makefile 2005-01-07 15:44:51 -08:00
+++ b/drivers/usb/serial/Makefile 2005-01-07 15:44:51 -08:00
@@ -19,6 +19,7 @@
obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o
obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o
obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o
+obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o
obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o
obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o
obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o
diff -Nru a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/garmin_gps.c 2005-01-07 15:44:51 -08:00
@@ -0,0 +1,1542 @@
+/*
+ * Garmin GPS driver
+ *
+ * Copyright (C) 2004 Hermann Kneissel [email protected]
+ *
+ * The latest version of the driver can be found at
+ * http://sourceforge.net/projects/garmin-gps/
+ *
+ * This driver has been derived from v2.1 of the visor driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+
+/* the mode to be set when the port ist opened */
+static int initial_mode = 1;
+
+/* debug flag */
+static int debug = 0;
+
+#include "usb-serial.h"
+
+#define GARMIN_VENDOR_ID 0x091E
+
+/*
+ * Version Information
+ */
+
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 23
+
+#define _STR(s) #s
+#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
+#define DRIVER_VERSION _DRIVER_VERSION(VERSION_MAJOR, VERSION_MINOR)
+#define DRIVER_AUTHOR "hermann kneissel"
+#define DRIVER_DESC "garmin gps driver"
+
+/* error codes returned by the driver */
+#define EINVPKT 1000 /* invalid packet structure */
+
+
+// size of the header of a packet using the usb protocol
+#define GARMIN_PKTHDR_LENGTH 12
+
+// max. possible size of a packet using the serial protocol
+#define MAX_SERIAL_PKT_SIZ (3+255+3)
+
+// max. possible size of a packet with worst case stuffing
+#define MAX_SERIAL_PKT_SIZ_STUFFED MAX_SERIAL_PKT_SIZ+256
+
+// size of a buffer able to hold a complete (no stuffing) packet
+// (the document protocol does not contain packets with a larger
+// size, but in theory a packet may be 64k+12 bytes - if in
+// later protocol versions larger packet sizes occur, this value
+// should be increased accordingly, so the input buffer is always
+// large enough the store a complete packet inclusive header)
+#define GPS_IN_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ)
+
+// size of a buffer able to hold a complete (incl. stuffing) packet
+#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED)
+
+// where to place the packet id of a serial packet, so we can
+// prepend the usb-packet header without the need to move the
+// packets data
+#define GSP_INITIAL_OFFSET (GARMIN_PKTHDR_LENGTH-2)
+
+// max. size of incoming private packets (header+1 param)
+#define PRIVPKTSIZ (GARMIN_PKTHDR_LENGTH+4)
+
+#define GARMIN_LAYERID_TRANSPORT 0
+#define GARMIN_LAYERID_APPL 20
+// our own layer-id to use for some control mechanisms
+#define GARMIN_LAYERID_PRIVATE 0x01106E4B
+
+#define GARMIN_PKTID_PVT_DATA 51
+#define GARMIN_PKTID_L001_COMMAND_DATA 10
+
+#define CMND_ABORT_TRANSFER 0
+
+// packet ids used in private layer
+#define PRIV_PKTID_SET_DEBUG 1
+#define PRIV_PKTID_SET_MODE 2
+#define PRIV_PKTID_INFO_REQ 3
+#define PRIV_PKTID_INFO_RESP 4
+#define PRIV_PKTID_RESET_REQ 5
+#define PRIV_PKTID_SET_DEF_MODE 6
+
+
+#define ETX 0x03
+#define DLE 0x10
+#define ACK 0x06
+#define NAK 0x15
+
+/* structure used to queue incoming packets */
+struct garmin_packet {
+ struct list_head list;
+ int seq;
+ int size; // the real size of the data array, always > 0
+ __u8 data[1];
+};
+
+/* structure used to keep the current state of the driver */
+struct garmin_data {
+ __u8 state;
+ __u16 flags;
+ __u8 mode;
+ __u8 ignorePkts;
+ __u8 count;
+ __u8 pkt_id;
+ __u32 serial_num;
+ struct timer_list timer;
+ struct usb_serial_port *port;
+ int seq_counter;
+ int insize;
+ int outsize;
+ __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */
+ __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
+ __u8 privpkt[4*6];
+ spinlock_t lock;
+ struct list_head pktlist;
+};
+
+
+#define STATE_NEW 0
+#define STATE_INITIAL_DELAY 1
+#define STATE_TIMEOUT 2
+#define STATE_SESSION_REQ1 3
+#define STATE_SESSION_REQ2 4
+#define STATE_ACTIVE 5
+
+#define STATE_RESET 8
+#define STATE_DISCONNECTED 9
+#define STATE_WAIT_TTY_ACK 10
+#define STATE_GSP_WAIT_DATA 11
+
+#define MODE_NATIVE 0
+#define MODE_GARMIN_SERIAL 1
+
+// Flags used in garmin_data.flags:
+#define FLAGS_SESSION_REPLY_MASK 0x00C0
+#define FLAGS_SESSION_REPLY1_SEEN 0x0080
+#define FLAGS_SESSION_REPLY2_SEEN 0x0040
+#define FLAGS_BULK_IN_ACTIVE 0x0020
+#define FLAGS_THROTTLED 0x0010
+#define CLEAR_HALT_REQUIRED 0x0001
+
+#define FLAGS_QUEUING 0x0100
+#define FLAGS_APP_RESP_SEEN 0x0200
+#define FLAGS_APP_REQ_SEEN 0x0400
+#define FLAGS_DROP_DATA 0x0800
+
+#define FLAGS_GSP_SKIP 0x1000
+#define FLAGS_GSP_DLESEEN 0x2000
+
+
+
+
+
+
+/* function prototypes */
+static void gsp_next_packet(struct garmin_data * garmin_data_p);
+static int garmin_write_bulk(struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+
+/* some special packets to be send or received */
+static unsigned char const GARMIN_START_SESSION_REQ[]
+ = { 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_START_SESSION_REQ2[]
+ = { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_START_SESSION_REPLY[]
+ = { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 };
+static unsigned char const GARMIN_SESSION_ACTIVE_REPLY[]
+ = { 0, 0, 0, 0, 17, 0, 0, 0, 4, 0, 0, 0, 0, 16, 0, 0 };
+static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[]
+ = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_APP_LAYER_REPLY[]
+ = { 0x14, 0, 0, 0 };
+static unsigned char const GARMIN_START_PVT_REQ[]
+ = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0 };
+static unsigned char const GARMIN_STOP_PVT_REQ[]
+ = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0 };
+static unsigned char const GARMIN_STOP_TRANSFER_REQ[]
+ = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[]
+ = { 20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0 };
+static unsigned char const PRIVATE_REQ[]
+ = { 0x4B, 0x6E, 0x10, 0x01, 0xFF, 0, 0, 0, 0xFF, 0, 0, 0 };
+
+
+
+static struct usb_device_id id_table [] = {
+ /* the same device id seems to be used by all usb enabled gps devices */
+ { USB_DEVICE(GARMIN_VENDOR_ID, 3 ) },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+static struct usb_driver garmin_driver = {
+ .owner = THIS_MODULE,
+ .name = "garmin_gps",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+
+static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
+{
+ return ((garmin_data_p->flags
+ & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
+ == FLAGS_APP_REQ_SEEN);
+}
+
+
+static inline int getLayerId(const __u8 *usbPacket)
+{
+ return __le32_to_cpup((__le32 *)(usbPacket));
+}
+
+static inline int getPacketId(const __u8 *usbPacket)
+{
+ return __le32_to_cpup((__le32 *)(usbPacket+4));
+}
+
+static inline int getDataLength(const __u8 *usbPacket)
+{
+ return __le32_to_cpup((__le32 *)(usbPacket+8));
+}
+
+
+/*
+ * check if the usb-packet in buf contains an abort-transfer command.
+ * (if yes, all queued data will be dropped)
+ */
+static inline int isAbortTrfCmnd(const unsigned char *buf)
+{
+ if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ,
+ sizeof(GARMIN_STOP_TRANSFER_REQ)) ||
+ 0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2,
+ sizeof(GARMIN_STOP_TRANSFER_REQ_V2)))
+ return 1;
+ else
+ return 0;
+}
+
+
+
+static void send_to_tty(struct usb_serial_port *port,
+ char *data, unsigned int actual_length)
+{
+ struct tty_struct *tty = port->tty;
+ int i;
+
+ if (tty && actual_length) {
+
+ usb_serial_debug_data(debug, &port->dev,
+ __FUNCTION__, actual_length, data);
+
+ for (i = 0; i < actual_length ; ++i) {
+ /* if we insert more than TTY_FLIPBUF_SIZE characters,
+ we drop them. */
+ if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ tty_flip_buffer_push(tty);
+ }
+ /* this doesn't actually push the data through unless
+ tty->low_latency is set */
+ tty_insert_flip_char(tty, data[i], 0);
+ }
+ tty_flip_buffer_push(tty);
+ }
+}
+
+
+/******************************************************************************
+ * packet queue handling
+ ******************************************************************************/
+
+/*
+ * queue a received (usb-)packet for later processing
+ */
+static int pkt_add(struct garmin_data * garmin_data_p,
+ unsigned char *data, unsigned int data_length)
+{
+ int result = 0;
+ unsigned long flags;
+ struct garmin_packet *pkt;
+
+ /* process only packets containg data ... */
+ if (data_length) {
+ garmin_data_p->flags |= FLAGS_QUEUING;
+ pkt = kmalloc(sizeof(struct garmin_packet)+data_length,
+ GFP_ATOMIC);
+ if (pkt == 0) {
+ dev_err(&garmin_data_p->port->dev, "out of memory\n");
+ return 0;
+ }
+ pkt->size = data_length;
+ memcpy(pkt->data, data, data_length);
+
+ spin_lock_irqsave(&garmin_data_p->lock, flags);
+ result = list_empty(&garmin_data_p->pktlist);
+ pkt->seq = garmin_data_p->seq_counter++;
+ list_add_tail(&pkt->list, &garmin_data_p->pktlist);
+ spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+
+ /* in serial mode, if someone is waiting for data from
+ the device, iconvert and send the next packet to tty. */
+ if (result && (garmin_data_p->state == STATE_GSP_WAIT_DATA)) {
+ gsp_next_packet(garmin_data_p);
+ }
+ }
+ return result;
+}
+
+
+/* get the next pending packet */
+static struct garmin_packet *pkt_pop(struct garmin_data * garmin_data_p)
+{
+ unsigned long flags;
+ struct garmin_packet *result = 0;
+
+ spin_lock_irqsave(&garmin_data_p->lock, flags);
+ if (!list_empty(&garmin_data_p->pktlist)) {
+ result = (struct garmin_packet *)garmin_data_p->pktlist.next;
+ list_del(&result->list);
+ }
+ spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ return result;
+}
+
+
+/* free up all queued data */
+static void pkt_clear(struct garmin_data * garmin_data_p)
+{
+ unsigned long flags;
+ struct garmin_packet *result = 0;
+
+ dbg("%s", __FUNCTION__);
+
+ spin_lock_irqsave(&garmin_data_p->lock, flags);
+ while (!list_empty(&garmin_data_p->pktlist)) {
+ result = (struct garmin_packet *)garmin_data_p->pktlist.next;
+ list_del(&result->list);
+ kfree(result);
+ }
+ spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+}
+
+
+/******************************************************************************
+ * garmin serial protocol handling handling
+ ******************************************************************************/
+
+/* send an ack packet back to the tty */
+static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id)
+{
+ __u8 pkt[10];
+ __u8 cksum = 0;
+ __u8 *ptr = pkt;
+ unsigned l = 0;
+
+ dbg("%s - pkt-id: 0x%X.", __FUNCTION__, 0xFF & pkt_id);
+
+ *ptr++ = DLE;
+ *ptr++ = ACK;
+ cksum += ACK;
+
+ *ptr++ = 2;
+ cksum += 2;
+
+ *ptr++ = pkt_id;
+ cksum += pkt_id;
+
+ if (pkt_id == DLE) {
+ *ptr++ = DLE;
+ }
+
+ *ptr++ = 0;
+ *ptr++ = 0xFF & (-cksum);
+ *ptr++ = DLE;
+ *ptr++ = ETX;
+
+ l = ptr-pkt;
+
+ send_to_tty(garmin_data_p->port, pkt, l);
+ return 0;
+}
+
+
+
+/*
+ * called for a complete packet received from tty layer
+ *
+ * the complete packet (pkzid ... cksum) is in garmin_data_p->inbuf starting
+ * at GSP_INITIAL_OFFSET.
+ *
+ * count - number of bytes in the input buffer including space reserved for
+ * the usb header: GSP_INITIAL_OFFSET + number of bytes in packet
+ * (including pkt-id, data-length a. cksum)
+ */
+static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
+{
+ const __u8* recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
+ __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer;
+
+ int cksum = 0;
+ int n = 0;
+ int pktid = recpkt[0];
+ int size = recpkt[1];
+
+ usb_serial_debug_data(debug, &garmin_data_p->port->dev,
+ __FUNCTION__, count-GSP_INITIAL_OFFSET, recpkt);
+
+ if (size != (count-GSP_INITIAL_OFFSET-3)) {
+ dbg("%s - invalid size, expected %d bytes, got %d",
+ __FUNCTION__, size, (count-GSP_INITIAL_OFFSET-3));
+ return -EINVPKT;
+ }
+
+ cksum += *recpkt++;
+ cksum += *recpkt++;
+
+ // sanity check, remove after test ...
+ if ((__u8*)&(usbdata[3]) != recpkt) {
+ dbg("%s - ptr mismatch %p - %p",
+ __FUNCTION__, &(usbdata[4]), recpkt);
+ return -EINVPKT;
+ }
+
+ while (n < size) {
+ cksum += *recpkt++;
+ n++;
+ }
+
+ if ((0xff & (cksum + *recpkt)) != 0) {
+ dbg("%s - invalid checksum, expected %02x, got %02x",
+ __FUNCTION__, 0xff & -cksum, 0xff & *recpkt);
+ return -EINVPKT;
+ }
+
+ usbdata[0] = __cpu_to_le32(GARMIN_LAYERID_APPL);
+ usbdata[1] = __cpu_to_le32(pktid);
+ usbdata[2] = __cpu_to_le32(size);
+
+ garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
+ GARMIN_PKTHDR_LENGTH+size);
+
+ /* if this was an abort-transfer command, flush all
+ queued data. */
+ if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
+ garmin_data_p->flags |= FLAGS_DROP_DATA;
+ pkt_clear(garmin_data_p);
+ }
+
+ return count;
+}
+
+
+
+/*
+ * Called for data received from tty
+ *
+ * buf contains the data read, it may span more than one packet or even
+ * incomplete packets
+ *
+ * input record should be a serial-record, but it may not be complete.
+ * Copy it into our local buffer, until an etx is seen (or an error
+ * occurs).
+ * Once the record is complete, convert into a usb packet and send it
+ * to the bulk pipe, send an ack back to the tty.
+ *
+ * If the input is an ack, just send the last queued packet to the
+ * tty layer.
+ *
+ * if the input is an abort command, drop all queued data.
+ */
+
+static int gsp_receive(struct garmin_data * garmin_data_p,
+ const unsigned char *buf, int count)
+{
+ int offs = 0;
+ int ack_or_nak_seen = 0;
+ int i = 0;
+ __u8 *dest = garmin_data_p->inbuffer;
+ int size = garmin_data_p->insize;
+ // dleSeen: set if last byte read was a DLE
+ int dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN;
+ // skip: if set, skip incoming data until possible start of
+ // new packet
+ int skip = garmin_data_p->flags & FLAGS_GSP_SKIP;
+ __u8 data;
+
+ dbg("%s - dle=%d skip=%d size=%d count=%d",
+ __FUNCTION__, dleSeen, skip, size, count);
+
+ if (size == 0) {
+ size = GSP_INITIAL_OFFSET;
+ }
+
+ while (offs < count) {
+
+ data = *(buf+offs);
+ offs ++;
+
+ if (data == DLE) {
+ if (skip) { /* start of a new pkt */
+ skip = 0;
+ size = GSP_INITIAL_OFFSET;
+ dleSeen = 1;
+ } else if (dleSeen) {
+ dest[size++] = data;
+ dleSeen = 0;
+ } else {
+ dleSeen = 1;
+ }
+ } else if (data == ETX) {
+ if (dleSeen) {
+ /* packet complete */
+
+ data = dest[GSP_INITIAL_OFFSET];
+
+ if (data == ACK) {
+ ack_or_nak_seen = ACK;
+ dbg("ACK packet complete.");
+ } else if (data == NAK) {
+ ack_or_nak_seen = NAK;
+ dbg("NAK packet complete.");
+ } else {
+ dbg("packet complete "
+ "- id=0x%X.",
+ 0xFF & data);
+ gsp_rec_packet(garmin_data_p, size);
+ }
+
+ skip = 1;
+ size = GSP_INITIAL_OFFSET;
+ dleSeen = 0;
+ } else {
+ dest[size++] = data;
+ }
+ } else if (!skip) {
+
+ if (dleSeen) {
+ dbg("non-masked DLE at %d - restarting", i);
+ size = GSP_INITIAL_OFFSET;
+ dleSeen = 0;
+ }
+
+ dest[size++] = data;
+ }
+
+ if (size >= GPS_IN_BUFSIZ) {
+ dbg("%s - packet too large.", __FUNCTION__);
+ skip = 1;
+ size = GSP_INITIAL_OFFSET;
+ dleSeen = 0;
+ }
+ }
+
+ garmin_data_p->insize = size;
+
+ // copy flags back to structure
+ if (skip)
+ garmin_data_p->flags |= FLAGS_GSP_SKIP;
+ else
+ garmin_data_p->flags &= ~FLAGS_GSP_SKIP;
+
+ if (dleSeen)
+ garmin_data_p->flags |= FLAGS_GSP_DLESEEN;
+ else
+ garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN;
+
+ if (ack_or_nak_seen) {
+ garmin_data_p->state = STATE_GSP_WAIT_DATA;
+ gsp_next_packet(garmin_data_p);
+ }
+
+ return count;
+}
+
+
+
+
+/*
+ * Sends a usb packet to the tty
+ *
+ * Assumes, that all packages and at an usb-packet boundary.
+ *
+ * return <0 on error, 0 if packet is incomplete or > 0 if packet was sent
+ */
+int gsp_send(struct garmin_data * garmin_data_p, const unsigned char *buf,
+ int count)
+{
+ const unsigned char *src;
+ unsigned char *dst;
+ int pktid = 0;
+ int datalen = 0;
+ int cksum = 0;
+ int i=0;
+ int k;
+
+ dbg("%s - state %d - %d bytes.", __FUNCTION__,
+ garmin_data_p->state, count);
+
+ k = garmin_data_p->outsize;
+ if ((k+count) > GPS_OUT_BUFSIZ) {
+ dbg("packet too large");
+ garmin_data_p->outsize = 0;
+ return -4;
+ }
+
+ memcpy(garmin_data_p->outbuffer+k, buf, count);
+ k += count;
+ garmin_data_p->outsize = k;
+
+ if (k >= GARMIN_PKTHDR_LENGTH) {
+ pktid = getPacketId(garmin_data_p->outbuffer);
+ datalen= getDataLength(garmin_data_p->outbuffer);
+ i = GARMIN_PKTHDR_LENGTH + datalen;
+ if (k < i)
+ return 0;
+ } else {
+ return 0;
+ }
+
+ dbg("%s - %d bytes in buffer, %d bytes in pkt.", __FUNCTION__,
+ k, i);
+
+ /* garmin_data_p->outbuffer now contains a complete packet */
+
+ usb_serial_debug_data(debug, &garmin_data_p->port->dev,
+ __FUNCTION__, k, garmin_data_p->outbuffer);
+
+ garmin_data_p->outsize = 0;
+
+ if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) {
+ dbg("not an application packet (%d)",
+ getLayerId(garmin_data_p->outbuffer));
+ return -1;
+ }
+
+ if (pktid > 255) {
+ dbg("packet-id %d too large", pktid);
+ return -2;
+ }
+
+ if (datalen > 255) {
+ dbg("packet-size %d too large", datalen);
+ return -3;
+ }
+
+ /* the serial protocol should be able to handle this packet */
+
+ k = 0;
+ src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
+ for (i=0; i<datalen; i++) {
+ if (*src++ == DLE)
+ k++;
+ }
+
+ src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
+ if (k > (GARMIN_PKTHDR_LENGTH-2)) {
+ /* can't add stuffing DLEs in place, move data to end
+ of buffer ... */
+ dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen;
+ memcpy(dst, src, datalen);
+ src = dst;
+ }
+
+ dst = garmin_data_p->outbuffer;
+
+ *dst++ = DLE;
+ *dst++ = pktid;
+ cksum += pktid;
+ *dst++ = datalen;
+ cksum += datalen;
+ if (datalen == DLE)
+ *dst++ = DLE;
+
+ for (i=0; i<datalen; i++) {
+ __u8 c = *src++;
+ *dst++ = c;
+ cksum += c;
+ if (c == DLE)
+ *dst++ = DLE;
+ }
+
+ cksum = 0xFF & -cksum;
+ *dst++ = cksum;
+ if (cksum == DLE)
+ *dst++ = DLE;
+ *dst++ = DLE;
+ *dst++ = ETX;
+
+ i = dst-garmin_data_p->outbuffer;
+
+ send_to_tty(garmin_data_p->port, garmin_data_p->outbuffer, i);
+
+ garmin_data_p->pkt_id = pktid;
+ garmin_data_p->state = STATE_WAIT_TTY_ACK;
+
+ return i;
+}
+
+
+
+
+
+/*
+ * Process the next pending data packet - if there is one
+ */
+static void gsp_next_packet(struct garmin_data * garmin_data_p)
+{
+ struct garmin_packet *pkt = 0;
+
+ while ((pkt = pkt_pop(garmin_data_p)) != 0)
+ {
+ dbg("%s - next pkt: %d", __FUNCTION__, pkt->seq);
+ if (gsp_send(garmin_data_p, pkt->data, pkt->size) > 0) {
+ kfree(pkt);
+ return;
+ }
+ kfree(pkt);
+ }
+}
+
+
+
+
+/******************************************************************************
+ * garmin native mode
+ ******************************************************************************/
+
+
+/*
+ * Called for data received from tty
+ *
+ * The input data is expected to be in garmin usb-packet format.
+ *
+ * buf contains the data read, it may span more than one packet
+ * or even incomplete packets
+ */
+static int nat_receive(struct garmin_data * garmin_data_p,
+ const unsigned char *buf, int count)
+{
+ __u8 * dest;
+ int offs = 0;
+ int result = count;
+ int len;
+
+ while (offs < count) {
+ // if buffer contains header, copy rest of data
+ if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH)
+ len = GARMIN_PKTHDR_LENGTH
+ +getDataLength(garmin_data_p->inbuffer);
+ else
+ len = GARMIN_PKTHDR_LENGTH;
+
+ if (len >= GPS_IN_BUFSIZ) {
+ /* seem to be an invalid packet, ignore rest of input */
+ dbg("%s - packet size too large: %d",
+ __FUNCTION__, len);
+ garmin_data_p->insize = 0;
+ count = 0;
+ result = -EINVPKT;
+ } else {
+ len -= garmin_data_p->insize;
+ if (len > (count-offs))
+ len = (count-offs);
+ if (len > 0) {
+ dest = garmin_data_p->inbuffer
+ +garmin_data_p->insize;
+ memcpy(dest, buf+offs, len);
+ garmin_data_p->insize += len;
+ offs += len;
+ }
+ }
+
+ /* do we have a complete packet ? */
+ if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH) {
+ len = GARMIN_PKTHDR_LENGTH+
+ getDataLength(garmin_data_p->inbuffer);
+ if (garmin_data_p->insize >= len) {
+ garmin_write_bulk (garmin_data_p->port,
+ garmin_data_p->inbuffer,
+ len);
+ garmin_data_p->insize = 0;
+
+ /* if this was an abort-transfer command,
+ flush all queued data. */
+ if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
+ garmin_data_p->flags |= FLAGS_DROP_DATA;
+ pkt_clear(garmin_data_p);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+
+/******************************************************************************
+ * private packets
+ ******************************************************************************/
+
+static void priv_status_resp(struct usb_serial_port *port)
+{
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ __le32 *pkt = (__le32 *)garmin_data_p->privpkt;
+
+ pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE);
+ pkt[1] = __cpu_to_le32(PRIV_PKTID_INFO_RESP);
+ pkt[2] = __cpu_to_le32(12);
+ pkt[3] = __cpu_to_le32(VERSION_MAJOR << 16 | VERSION_MINOR);
+ pkt[4] = __cpu_to_le32(garmin_data_p->mode);
+ pkt[5] = __cpu_to_le32(garmin_data_p->serial_num);
+
+ send_to_tty(port, (__u8*)pkt, 6*4);
+}
+
+
+/******************************************************************************
+ * Garmin specific driver functions
+ ******************************************************************************/
+
+static int process_resetdev_request(struct usb_serial_port *port)
+{
+ int status;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED);
+ garmin_data_p->state = STATE_RESET;
+ garmin_data_p->serial_num = 0;
+
+ usb_kill_urb (port->interrupt_in_urb);
+ dbg("%s - usb_reset_device", __FUNCTION__ );
+ status = usb_reset_device(port->serial->dev);
+ if (status)
+ dbg("%s - usb_reset_device failed: %d",
+ __FUNCTION__, status);
+ return status;
+}
+
+
+
+/*
+ * clear all cached data
+ */
+static int garmin_clear(struct garmin_data * garmin_data_p)
+{
+ int status = 0;
+
+ struct usb_serial_port *port = garmin_data_p->port;
+
+ if (port != 0 && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
+ /* send a terminate command */
+ status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
+ sizeof(GARMIN_STOP_TRANSFER_REQ));
+ }
+
+ /* flush all queued data */
+ pkt_clear(garmin_data_p);
+
+ garmin_data_p->insize = 0;
+ garmin_data_p->outsize = 0;
+
+ return status;
+}
+
+
+
+
+
+
+static int garmin_init_session(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ int status = 0;
+
+ if (status == 0) {
+ usb_kill_urb (port->interrupt_in_urb);
+
+ dbg("%s - adding interrupt input", __FUNCTION__);
+ port->interrupt_in_urb->dev = serial->dev;
+ status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+ if (status)
+ dev_err(&serial->dev->dev,
+ "%s - failed submitting interrupt urb,"
+ " error %d\n",
+ __FUNCTION__, status);
+ }
+
+ if (status == 0) {
+ dbg("%s - starting session ...", __FUNCTION__);
+ garmin_data_p->state = STATE_ACTIVE;
+ status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
+ sizeof(GARMIN_START_SESSION_REQ));
+
+ if (status >= 0) {
+
+ garmin_data_p->ignorePkts++;
+
+ /* not needed, but the win32 driver does it too ... */
+ status = garmin_write_bulk(port,
+ GARMIN_START_SESSION_REQ2,
+ sizeof(GARMIN_START_SESSION_REQ2));
+ if (status >= 0) {
+ status = 0;
+ garmin_data_p->ignorePkts++;
+ }
+ }
+ }
+
+ return status;
+}
+
+
+
+
+
+static int garmin_open (struct usb_serial_port *port, struct file *filp)
+{
+ int status = 0;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ /*
+ * Force low_latency on so that our tty_push actually forces the data
+ * through, otherwise it is scheduled, and with high data rates (like
+ * with OHCI) data can get lost.
+ */
+ if (port->tty)
+ port->tty->low_latency = 1;
+
+ garmin_data_p->mode = initial_mode;
+ garmin_data_p->count = 0;
+ garmin_data_p->flags = 0;
+
+ /* shutdown any bulk reads that might be going on */
+ usb_kill_urb (port->write_urb);
+ usb_kill_urb (port->read_urb);
+
+ if (garmin_data_p->state == STATE_RESET) {
+ status = garmin_init_session(port);
+ }
+
+ garmin_data_p->state = STATE_ACTIVE;
+
+ return status;
+}
+
+
+static void garmin_close (struct usb_serial_port *port, struct file * filp)
+{
+ struct usb_serial *serial = port->serial;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d - mode=%d state=%d flags=0x%X", __FUNCTION__,
+ port->number, garmin_data_p->mode,
+ garmin_data_p->state, garmin_data_p->flags);
+
+ if (!serial)
+ return;
+
+ garmin_clear(garmin_data_p);
+
+ /* shutdown our urbs */
+ usb_kill_urb (port->read_urb);
+ usb_kill_urb (port->write_urb);
+
+ if (noResponseFromAppLayer(garmin_data_p) ||
+ ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) {
+ process_resetdev_request(port);
+ garmin_data_p->state = STATE_RESET;
+ } else {
+ garmin_data_p->state = STATE_DISCONNECTED;
+ }
+}
+
+
+static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ /* free up the transfer buffer, as usb_free_urb() does not do this */
+ kfree (urb->transfer_buffer);
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (urb->status) {
+ dbg("%s - nonzero write bulk status received: %d",
+ __FUNCTION__, urb->status);
+ garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
+ }
+
+ schedule_work(&port->work);
+}
+
+
+static int garmin_write_bulk (struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ struct usb_serial *serial = port->serial;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct urb *urb;
+ unsigned char *buffer;
+ int status;
+
+ dbg("%s - port %d, state %d", __FUNCTION__, port->number,
+ garmin_data_p->state);
+
+ garmin_data_p->flags &= ~FLAGS_DROP_DATA;
+
+ buffer = kmalloc (count, GFP_ATOMIC);
+ if (!buffer) {
+ dev_err(&port->dev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ dev_err(&port->dev, "no more free urbs\n");
+ kfree (buffer);
+ return -ENOMEM;
+ }
+
+ memcpy (buffer, buf, count);
+
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);
+
+ usb_fill_bulk_urb (urb, serial->dev,
+ usb_sndbulkpipe (serial->dev,
+ port->bulk_out_endpointAddress),
+ buffer, count,
+ garmin_write_bulk_callback, port);
+ urb->transfer_flags |= URB_ZERO_PACKET;
+
+ if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
+ garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
+ if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
+ pkt_clear(garmin_data_p);
+ garmin_data_p->state = STATE_GSP_WAIT_DATA;
+ }
+ }
+
+ /* send it down the pipe */
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status) {
+ dev_err(&port->dev,
+ "%s - usb_submit_urb(write bulk) "
+ "failed with status = %d\n",
+ __FUNCTION__, status);
+ count = status;
+ } else {
+
+ if (GARMIN_LAYERID_APPL == getLayerId(buffer)
+ && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
+
+ gsp_send_ack(garmin_data_p, buffer[4]);
+ }
+ }
+
+ /* we are done with this urb, so let the host driver
+ * really free it when it is finished with it */
+ usb_free_urb (urb);
+
+ return count;
+}
+
+
+
+static int garmin_write (struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ int pktid, pktsiz, len;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ __le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
+
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buf);
+
+ /* check for our private packets */
+ if (count >= GARMIN_PKTHDR_LENGTH) {
+
+ len = PRIVPKTSIZ;
+ if (count < len)
+ len = count;
+
+ memcpy(garmin_data_p->privpkt, buf, len);
+
+ pktsiz = getDataLength(garmin_data_p->privpkt);
+ pktid = getPacketId(garmin_data_p->privpkt);
+
+ if (count == (GARMIN_PKTHDR_LENGTH+pktsiz)
+ && GARMIN_LAYERID_PRIVATE == getLayerId(garmin_data_p->privpkt)) {
+
+ dbg("%s - processing private request %d",
+ __FUNCTION__, pktid);
+
+ // drop all unfinished transfers
+ garmin_clear(garmin_data_p);
+
+ switch(pktid) {
+
+ case PRIV_PKTID_SET_DEBUG:
+ if (pktsiz != 4)
+ return -EINVPKT;
+ debug = __le32_to_cpu(privpkt[3]);
+ dbg("%s - debug level set to 0x%X",
+ __FUNCTION__, debug);
+ break;
+
+ case PRIV_PKTID_SET_MODE:
+ if (pktsiz != 4)
+ return -EINVPKT;
+ garmin_data_p->mode = __le32_to_cpu(privpkt[3]);
+ dbg("%s - mode set to %d",
+ __FUNCTION__, garmin_data_p->mode);
+ break;
+
+ case PRIV_PKTID_INFO_REQ:
+ priv_status_resp(port);
+ break;
+
+ case PRIV_PKTID_RESET_REQ:
+ garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
+ break;
+
+ case PRIV_PKTID_SET_DEF_MODE:
+ if (pktsiz != 4)
+ return -EINVPKT;
+ initial_mode = __le32_to_cpu(privpkt[3]);
+ dbg("%s - initial_mode set to %d",
+ __FUNCTION__,
+ garmin_data_p->mode);
+ break;
+ }
+ return count;
+ }
+ }
+
+ if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
+ return gsp_receive(garmin_data_p, buf, count);
+ } else { /* MODE_NATIVE */
+ return nat_receive(garmin_data_p, buf, count);
+ }
+}
+
+
+static int garmin_write_room (struct usb_serial_port *port)
+{
+ /*
+ * Report back the bytes currently available in the output buffer.
+ */
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ return GPS_OUT_BUFSIZ-garmin_data_p->outsize;
+}
+
+
+static int garmin_chars_in_buffer (struct usb_serial_port *port)
+{
+ /*
+ * Report back the number of bytes currently in our input buffer.
+ * Will this lock up the driver - the buffer contains an incomplete
+ * package which will not be written to the device until it
+ * has been completed ?
+ */
+ //struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ //return garmin_data_p->insize;
+ return 0;
+}
+
+
+static void garmin_read_process(struct garmin_data * garmin_data_p,
+ unsigned char *data, unsigned data_length)
+{
+ if (garmin_data_p->flags & FLAGS_DROP_DATA) {
+ /* abort-transfer cmd is actice */
+ dbg("%s - pkt dropped", __FUNCTION__);
+ } else if (garmin_data_p->state != STATE_DISCONNECTED &&
+ garmin_data_p->state != STATE_RESET ) {
+
+ /* remember any appl.layer packets, so we know
+ if a reset is required or not when closing
+ the device */
+ if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
+ sizeof(GARMIN_APP_LAYER_REPLY)))
+ garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
+
+ /* if throttling is active or postprecessing is required
+ put the received data in th input queue, otherwise
+ send it directly to the tty port */
+ if (garmin_data_p->flags & FLAGS_QUEUING) {
+ pkt_add(garmin_data_p, data, data_length);
+ } else if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
+ if (getLayerId(data) == GARMIN_LAYERID_APPL) {
+ pkt_add(garmin_data_p, data, data_length);
+ }
+ } else {
+ send_to_tty(garmin_data_p->port, data, data_length);
+ }
+ }
+}
+
+
+static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct usb_serial *serial = port->serial;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ unsigned char *data = urb->transfer_buffer;
+ int status;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (!serial) {
+ dbg("%s - bad serial pointer, exiting", __FUNCTION__);
+ return;
+ }
+
+ if (urb->status) {
+ dbg("%s - nonzero read bulk status received: %d",
+ __FUNCTION__, urb->status);
+ return;
+ }
+
+ usb_serial_debug_data(debug, &port->dev,
+ __FUNCTION__, urb->actual_length, data);
+
+ garmin_read_process(garmin_data_p, data, urb->actual_length);
+
+ /* Continue trying to read until nothing more is received */
+ if (urb->actual_length > 0) {
+ usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_rcvbulkpipe (serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ garmin_read_bulk_callback, port);
+ status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+ if (status)
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __FUNCTION__, status);
+ }
+ return;
+}
+
+
+static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs)
+{
+ int status;
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct usb_serial *serial = port->serial;
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ unsigned char *data = urb->transfer_buffer;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __FUNCTION__, urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
+ return;
+ }
+
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__,
+ urb->actual_length, urb->transfer_buffer);
+
+ if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) &&
+ 0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY,
+ sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {
+
+ dbg("%s - bulk data available.", __FUNCTION__);
+
+ /* bulk data available */
+ usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_rcvbulkpipe (serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ garmin_read_bulk_callback, port);
+ status = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ if (status) {
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __FUNCTION__, status);
+ }
+
+ } else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY))
+ && 0 == memcmp(data, GARMIN_START_SESSION_REPLY,
+ sizeof(GARMIN_START_SESSION_REPLY))) {
+
+ garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN;
+
+ /* save the serial number */
+ garmin_data_p->serial_num
+ = __le32_to_cpup((__le32*)(data+GARMIN_PKTHDR_LENGTH));
+
+ dbg("%s - start-of-session reply seen - serial %u.",
+ __FUNCTION__, garmin_data_p->serial_num);
+ }
+
+ if (garmin_data_p->ignorePkts) {
+ /* this reply belongs to a request generated by the driver,
+ ignore it. */
+ dbg("%s - pkt ignored (%d)",
+ __FUNCTION__, garmin_data_p->ignorePkts);
+ garmin_data_p->ignorePkts--;
+ } else {
+ garmin_read_process(garmin_data_p, data, urb->actual_length);
+ }
+
+ port->interrupt_in_urb->dev = port->serial->dev;
+ status = usb_submit_urb (urb, GFP_ATOMIC);
+ if (status)
+ dev_err(&urb->dev->dev,
+ "%s - Error %d submitting interrupt urb\n",
+ __FUNCTION__, status);
+}
+
+
+/*
+ * Sends the next queued packt to the tty port (garmin native mode only)
+ * and then sets a timer to call itself again until all queued data
+ * is sent.
+ */
+static int garmin_flush_queue(struct garmin_data * garmin_data_p)
+{
+ struct garmin_packet *pkt;
+
+ if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) {
+ pkt = pkt_pop(garmin_data_p);
+ if (pkt != 0) {
+
+ send_to_tty(garmin_data_p->port, pkt->data, pkt->size);
+ kfree(pkt);
+ mod_timer(&garmin_data_p->timer, (1)+jiffies);
+
+ } else {
+ garmin_data_p->flags &= ~FLAGS_QUEUING;
+ }
+ }
+ return 0;
+}
+
+
+static void garmin_throttle (struct usb_serial_port *port)
+{
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+ /* set flag, data received will be put into a queue
+ for later processing */
+ garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED;
+}
+
+
+static void garmin_unthrottle (struct usb_serial_port *port)
+{
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+ garmin_data_p->flags &= ~FLAGS_THROTTLED;
+
+ /* in native mode send queued data to tty, in
+ serial mode nothing needs to be done here */
+ if (garmin_data_p->mode == MODE_NATIVE)
+ garmin_flush_queue(garmin_data_p);
+}
+
+
+
+/*
+ * The timer is currently only used to send queued packets to
+ * the tty in cases where the protocol provides no own handshaking
+ * to initiate the transfer.
+ */
+static void timeout_handler(unsigned long data)
+{
+ struct garmin_data *garmin_data_p = (struct garmin_data *) data;
+
+ /* send the next queued packet to the tty port */
+ if (garmin_data_p->mode == MODE_NATIVE)
+ if (garmin_data_p->flags & FLAGS_QUEUING)
+ garmin_flush_queue(garmin_data_p);
+}
+
+
+
+static int garmin_attach (struct usb_serial *serial)
+{
+ int status = 0;
+ struct usb_serial_port *port = serial->port[0];
+ struct garmin_data * garmin_data_p = 0;
+
+ dbg("%s", __FUNCTION__);
+
+ garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL);
+ if (garmin_data_p == NULL) {
+ dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ memset (garmin_data_p, 0, sizeof(struct garmin_data));
+ init_timer(&garmin_data_p->timer);
+ spin_lock_init(&garmin_data_p->lock);
+ INIT_LIST_HEAD(&garmin_data_p->pktlist);
+ //garmin_data_p->timer.expires = jiffies + session_timeout;
+ garmin_data_p->timer.data = (unsigned long)garmin_data_p;
+ garmin_data_p->timer.function = timeout_handler;
+ garmin_data_p->port = port;
+ garmin_data_p->state = 0;
+ garmin_data_p->count = 0;
+ usb_set_serial_port_data(port, garmin_data_p);
+
+ status = garmin_init_session(port);
+
+ return status;
+}
+
+
+static void garmin_shutdown (struct usb_serial *serial)
+{
+ struct usb_serial_port *port = serial->port[0];
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ dbg("%s", __FUNCTION__);
+
+ usb_kill_urb (port->interrupt_in_urb);
+ del_timer_sync(&garmin_data_p->timer);
+ kfree (garmin_data_p);
+ usb_set_serial_port_data(port, NULL);
+}
+
+
+
+
+
+
+
+/* All of the device info needed */
+static struct usb_serial_device_type garmin_device = {
+ .owner = THIS_MODULE,
+ .name = "Garmin GPS usb/tty",
+ .short_name = "garmin_gps",
+ .id_table = id_table,
+ .num_interrupt_in = 1,
+ .num_bulk_in = 1,
+ .num_bulk_out = 1,
+ .num_ports = 1,
+ .open = garmin_open,
+ .close = garmin_close,
+ .throttle = garmin_throttle,
+ .unthrottle = garmin_unthrottle,
+ .attach = garmin_attach,
+ .shutdown = garmin_shutdown,
+ .write = garmin_write,
+ .write_room = garmin_write_room,
+ .chars_in_buffer = garmin_chars_in_buffer,
+ .write_bulk_callback = garmin_write_bulk_callback,
+ .read_bulk_callback = garmin_read_bulk_callback,
+ .read_int_callback = garmin_read_int_callback,
+};
+
+
+static int __init garmin_init (void)
+{
+ int retval;
+
+ retval = usb_serial_register(&garmin_device);
+ if (retval)
+ goto failed_garmin_register;
+ retval = usb_register(&garmin_driver);
+ if (retval)
+ goto failed_usb_register;
+ info(DRIVER_DESC " " DRIVER_VERSION);
+
+ return 0;
+failed_usb_register:
+ usb_serial_deregister(&garmin_device);
+failed_garmin_register:
+ return retval;
+}
+
+
+static void __exit garmin_exit (void)
+{
+ usb_deregister (&garmin_driver);
+ usb_serial_deregister (&garmin_device);
+}
+
+
+
+
+module_init(garmin_init);
+module_exit(garmin_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(initial_mode, int, S_IRUGO);
+MODULE_PARM_DESC(initial_mode, "Initial mode");
+
ChangeSet 1.1938.446.46, 2004/12/20 15:00:14-08:00, [email protected]
[PATCH] USB: Hub driver: improve error checking and retries [10/13]
Here's another "cleanup" type patch, most of which was written by David
Brownell. It causes the hub driver to retry a couple of different types
of transfers if they timeout (which seems to help with some flakey
devices), and it adds some error checking for the ep0 maxpacket value sent
by the device.
From: David Brownell <[email protected]>
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hub.c | 58 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 41 insertions(+), 17 deletions(-)
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:43:06 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:43:06 -08:00
@@ -240,15 +240,24 @@
schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
}
+/* use a short timeout for hub/port status fetches */
+#define USB_STS_TIMEOUT 1
+#define USB_STS_RETRIES 5
+
/*
* USB 2.0 spec Section 11.24.2.6
*/
static int get_hub_status(struct usb_device *hdev,
struct usb_hub_status *data)
{
- return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
- USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
- data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
+ int i, status = -ETIMEDOUT;
+
+ for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+ status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
+ data, sizeof(*data), HZ * USB_STS_TIMEOUT);
+ }
+ return status;
}
/*
@@ -257,9 +266,14 @@
static int get_port_status(struct usb_device *hdev, int port,
struct usb_port_status *data)
{
- return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
- USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
- data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
+ int i, status = -ETIMEDOUT;
+
+ for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+ status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
+ data, sizeof(*data), HZ * USB_STS_TIMEOUT);
+ }
+ return status;
}
static void kick_khubd(struct usb_hub *hub)
@@ -2163,6 +2177,7 @@
for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
if (USE_NEW_SCHEME(retry_counter)) {
struct usb_device_descriptor *buf;
+ int r = 0;
#define GET_DESCRIPTOR_BUFSIZE 64
buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
@@ -2176,13 +2191,20 @@
* so that recalcitrant full-speed devices with
* 8- or 16-byte ep0-maxpackets won't slow things
* down tremendously by NAKing the unexpectedly
- * early status stage.
+ * early status stage. Also, retry on length 0
+ * or stall; some devices are flakey.
*/
- j = usb_control_msg(udev, usb_rcvaddr0pipe(),
+ for (j = 0; j < 3; ++j) {
+ r = usb_control_msg(udev, usb_rcvaddr0pipe(),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, GET_DESCRIPTOR_BUFSIZE,
(i ? HZ * USB_CTRL_GET_TIMEOUT : HZ));
+ if (r == 0 || r == -EPIPE)
+ continue;
+ if (r < 0)
+ break;
+ }
udev->descriptor.bMaxPacketSize0 =
buf->bMaxPacketSize0;
kfree(buf);
@@ -2202,7 +2224,7 @@
default:
dev_err(&udev->dev, "device descriptor "
"read/%s, error %d\n",
- "64", j);
+ "64", r);
retval = -EMSGSIZE;
continue;
}
@@ -2245,14 +2267,16 @@
if (retval)
goto fail;
- /* Should we verify that the value is valid? */
- /* (YES!) */
- if (udev->ep0.desc.wMaxPacketSize
- != udev->descriptor.bMaxPacketSize0) {
- udev->ep0.desc.wMaxPacketSize
- = udev->descriptor.bMaxPacketSize0;
- dev_dbg(&udev->dev, "ep0 maxpacket = %d\n",
- udev->ep0.desc.wMaxPacketSize);
+ i = udev->descriptor.bMaxPacketSize0;
+ if (udev->ep0.desc.wMaxPacketSize != i) {
+ if (udev->speed != USB_SPEED_FULL ||
+ !(i == 8 || i == 16 || i == 32 || i == 64)) {
+ dev_err(&udev->dev, "ep0 maxpacket = %d\n", i);
+ retval = -EMSGSIZE;
+ goto fail;
+ }
+ dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+ udev->ep0.desc.wMaxPacketSize = i;
ep0_reinit(udev);
}
ChangeSet 1.2252, 2005/01/07 15:24:29-08:00, [email protected]
[PATCH] add feature-removal-schedule.txt documentation
Add Documentation/feature-removal-schedule.txt as a way to notify
everyone when and what is going to be removed.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/feature-removal-schedule.txt | 17 +++++++++++++++++
1 files changed, 17 insertions(+)
diff -Nru a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/feature-removal-schedule.txt 2005-01-07 15:33:15 -08:00
@@ -0,0 +1,17 @@
+The following is a list of files and features that are going to be
+removed in the kernel source tree. Every entry should contain what
+exactly is going away, why it is happening, and who is going to be doing
+the work. When the feature is removed from the kernel, it should also
+be removed from this file.
+
+---------------------------
+
+What: devfs
+When: July 2005
+Files: fs/devfs/*, include/linux/devfs_fs*.h and assorted devfs
+ function calls throughout the kernel tree
+Why: It has been unmaintained for a number of years, has unfixable
+ races, contains a naming policy within the kernel that is
+ against the LSB, and can be replaced by using udev.
+Who: Greg Kroah-Hartman <[email protected]>
+
ChangeSet 1.1938.446.45, 2004/12/20 14:20:30-08:00, [email protected]
[PATCH] USB: Create usb_hcd structures within usbcore [6/13]
This patch alters the dummy_hcd driver, removing the routine that
allocates the hcd structure and introducing inline functions to convert
safely between the public and private hcd structures.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/dummy_hcd.c | 44 +++++++++++++----------------------------
1 files changed, 14 insertions(+), 30 deletions(-)
diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:43:14 -08:00
+++ b/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:43:14 -08:00
@@ -149,7 +149,6 @@
};
struct dummy {
- struct usb_hcd hcd; /* must come first! */
spinlock_t lock;
/*
@@ -178,12 +177,17 @@
static inline struct dummy *hcd_to_dummy (struct usb_hcd *hcd)
{
- return container_of(hcd, struct dummy, hcd);
+ return (struct dummy *) (hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *dummy_to_hcd (struct dummy *dum)
+{
+ return container_of((void *) dum, struct usb_hcd, hcd_priv);
}
static inline struct device *dummy_dev (struct dummy *dum)
{
- return dum->hcd.self.controller;
+ return dummy_to_hcd(dum)->self.controller;
}
static inline struct dummy *ep_to_dummy (struct dummy_ep *ep)
@@ -1368,7 +1372,7 @@
ep->already_seen = ep->setup_stage = 0;
spin_unlock (&dum->lock);
- usb_hcd_giveback_urb (&dum->hcd, urb, 0);
+ usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, 0);
spin_lock (&dum->lock);
goto restart;
@@ -1570,20 +1574,6 @@
/*-------------------------------------------------------------------------*/
-static struct usb_hcd *dummy_alloc (void)
-{
- struct dummy *dum;
-
- dum = kmalloc (sizeof *dum, SLAB_KERNEL);
- if (dum == NULL)
- return NULL;
- the_controller = dum;
- memset (dum, 0, sizeof *dum);
- return &dum->hcd;
-}
-
-/*-------------------------------------------------------------------------*/
-
static inline ssize_t
show_urb (char *buf, size_t size, struct urb *urb)
{
@@ -1711,13 +1701,14 @@
static const struct hc_driver dummy_hcd = {
.description = (char *) driver_name,
+ .product_desc = "Dummy host controller",
+ .hcd_priv_size = sizeof(struct dummy),
+
.flags = HCD_USB2,
.start = dummy_start,
.stop = dummy_stop,
- .hcd_alloc = dummy_alloc,
-
.urb_enqueue = dummy_urb_enqueue,
.urb_dequeue = dummy_urb_dequeue,
@@ -1737,7 +1728,7 @@
dev_info (dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
- hcd = dummy_alloc ();
+ hcd = usb_create_hcd (&dummy_hcd);
if (hcd == NULL) {
dev_dbg (dev, "hcd_alloc failed\n");
return -ENOMEM;
@@ -1745,9 +1736,8 @@
dev_set_drvdata (dev, hcd);
dum = hcd_to_dummy (hcd);
+ the_controller = dum;
- hcd->driver = (struct hc_driver *) &dummy_hcd;
- hcd->description = dummy_hcd.description;
hcd->self.controller = dev;
/* FIXME don't require the pci-based buffer/alloc impls;
@@ -1760,13 +1750,7 @@
goto err1;
}
- usb_bus_init (&hcd->self);
- hcd->self.op = &usb_hcd_operations;
- hcd->self.release = &usb_hcd_release;
- hcd->self.hcpriv = hcd;
hcd->self.bus_name = dev->bus_id;
- hcd->product_desc = "Dummy host controller";
-
usb_register_bus (&hcd->self);
if ((retval = dummy_start (hcd)) < 0)
@@ -1774,7 +1758,7 @@
return retval;
err1:
- kfree (hcd);
+ usb_put_hcd (hcd);
dev_set_drvdata (dev, NULL);
return retval;
}
ChangeSet 1.2253, 2005/01/07 15:29:10-08:00, [email protected]
[PATCH] add cpufreq info to Documentation/feature-removal-schedule.txt
Add 2.4.x cpufreq /proc and sysctl interface removal
to the feature-removal-schedule.
Signed-off-by: Randy Dunlap <[email protected]>
Documentation/feature-removal-schedule.txt | 9 +++++++++
1 files changed, 9 insertions(+)
diff -Nru a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
--- a/Documentation/feature-removal-schedule.txt 2005-01-07 15:32:49 -08:00
+++ b/Documentation/feature-removal-schedule.txt 2005-01-07 15:32:49 -08:00
@@ -15,3 +15,12 @@
against the LSB, and can be replaced by using udev.
Who: Greg Kroah-Hartman <[email protected]>
+---------------------------
+
+What: /proc/sys/cpu and the sysctl interface to cpufreq (2.4.x interfaces)
+When: January 2005
+Files: drivers/cpufreq/: cpufreq_userspace.c, proc_intf.c
+ function calls throughout the kernel tree
+Why: Deprecated, has been replaced/superseded by (what?)....
+Who: Dominik Brodowski <[email protected]>
+
ChangeSet 1.1938.446.41, 2004/12/20 14:18:23-08:00, [email protected]
[PATCH] USB: Create usb_hcd structures within usbcore [2/13]
This patch alters the EHCI driver, removing the routine that allocates the
hcd structure and introducing inline functions to convert safely between
the public and private hcd structures.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-dbg.c | 30 +++++++++++++++-------------
drivers/usb/host/ehci-hcd.c | 45 ++++++++++++++++++++----------------------
drivers/usb/host/ehci-hub.c | 12 +++++------
drivers/usb/host/ehci-mem.c | 31 +++++-----------------------
drivers/usb/host/ehci-q.c | 23 +++++++++++----------
drivers/usb/host/ehci-sched.c | 34 +++++++++++++++----------------
drivers/usb/host/ehci.h | 23 +++++++++++++--------
7 files changed, 94 insertions(+), 104 deletions(-)
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci-dbg.c 2005-01-07 15:43:52 -08:00
@@ -19,13 +19,13 @@
/* this file is part of ehci-hcd.c */
#define ehci_dbg(ehci, fmt, args...) \
- dev_dbg ((ehci)->hcd.self.controller , fmt , ## args )
+ dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
#define ehci_err(ehci, fmt, args...) \
- dev_err ((ehci)->hcd.self.controller , fmt , ## args )
+ dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
#define ehci_info(ehci, fmt, args...) \
- dev_info ((ehci)->hcd.self.controller , fmt , ## args )
+ dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
#define ehci_warn(ehci, fmt, args...) \
- dev_warn ((ehci)->hcd.self.controller , fmt , ## args )
+ dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
#ifdef EHCI_VERBOSE_DEBUG
# define vdbg dbg
@@ -657,7 +657,7 @@
"EHCI %x.%02x, hcd state %d\n",
hcd->self.controller->bus->name,
hcd->self.controller->bus_id,
- i >> 8, i & 0x0ff, ehci->hcd.state);
+ i >> 8, i & 0x0ff, hcd->state);
size -= temp;
next += temp;
@@ -733,18 +733,22 @@
}
static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
-static inline void create_debug_files (struct ehci_hcd *bus)
+static inline void create_debug_files (struct ehci_hcd *ehci)
{
- class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_async);
- class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
- class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
+ struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev;
+
+ class_device_create_file(cldev, &class_device_attr_async);
+ class_device_create_file(cldev, &class_device_attr_periodic);
+ class_device_create_file(cldev, &class_device_attr_registers);
}
-static inline void remove_debug_files (struct ehci_hcd *bus)
+static inline void remove_debug_files (struct ehci_hcd *ehci)
{
- class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_async);
- class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
- class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
+ struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev;
+
+ class_device_remove_file(cldev, &class_device_attr_async);
+ class_device_remove_file(cldev, &class_device_attr_periodic);
+ class_device_remove_file(cldev, &class_device_attr_registers);
}
#endif /* STUB_DEBUG_FILES */
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci-hcd.c 2005-01-07 15:43:52 -08:00
@@ -199,7 +199,7 @@
command |= CMD_RESET;
dbg_cmd (ehci, "reset", command);
writel (command, &ehci->regs->command);
- ehci->hcd.state = USB_STATE_HALT;
+ ehci_to_hcd(ehci)->state = USB_STATE_HALT;
ehci->next_statechange = jiffies;
return handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
}
@@ -210,7 +210,7 @@
u32 temp;
#ifdef DEBUG
- if (!HCD_IS_RUNNING (ehci->hcd.state))
+ if (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
BUG ();
#endif
@@ -219,7 +219,7 @@
temp &= STS_ASS | STS_PSS;
if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
temp, 16 * 125) != 0) {
- ehci->hcd.state = USB_STATE_HALT;
+ ehci_to_hcd(ehci)->state = USB_STATE_HALT;
return;
}
@@ -231,7 +231,7 @@
/* hardware can take 16 microframes to turn off ... */
if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
0, 16 * 125) != 0) {
- ehci->hcd.state = USB_STATE_HALT;
+ ehci_to_hcd(ehci)->state = USB_STATE_HALT;
return;
}
}
@@ -285,7 +285,8 @@
{
if (cap & (1 << 16)) {
int msec = 5000;
- struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller);
+ struct pci_dev *pdev =
+ to_pci_dev(ehci_to_hcd(ehci)->self.controller);
/* request handoff to OS */
cap |= 1 << 24;
@@ -343,7 +344,7 @@
#ifdef CONFIG_PCI
/* EHCI 0.96 and later may have "extended capabilities" */
if (hcd->self.controller->bus == &pci_bus_type) {
- struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller);
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
/* AMD8111 EHCI doesn't work, according to AMD errata */
if ((pdev->vendor == PCI_VENDOR_ID_AMD)
@@ -358,7 +359,7 @@
while (temp && count--) {
u32 cap;
- pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller),
+ pci_read_config_dword (to_pci_dev(hcd->self.controller),
temp, &cap);
ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
switch (cap & 0xff) {
@@ -505,7 +506,7 @@
writel (0, &ehci->regs->segment);
#if 0
// this is deeply broken on almost all architectures
- if (!pci_set_dma_mask (to_pci_dev(ehci->hcd.self.controller), 0xffffffffffffffffULL))
+ if (!pci_set_dma_mask (to_pci_dev(hcd->self.controller), 0xffffffffffffffffULL))
ehci_info (ehci, "enabled 64bit PCI DMA\n");
#endif
}
@@ -570,7 +571,7 @@
register_reboot_notifier (&ehci->reboot_notifier);
}
- ehci->hcd.state = USB_STATE_RUNNING;
+ hcd->state = USB_STATE_RUNNING;
writel (FLAG_CF, &ehci->regs->configured_flag);
readl (&ehci->regs->command); /* unblock posted write */
@@ -627,7 +628,7 @@
del_timer_sync (&ehci->watchdog);
spin_lock_irq(&ehci->lock);
- if (HCD_IS_RUNNING (ehci->hcd.state))
+ if (HCD_IS_RUNNING (hcd->state))
ehci_quiesce (ehci);
ehci_reset (ehci);
@@ -794,8 +795,9 @@
* misplace IRQs, and should let us run completely without IRQs.
* such lossage has been observed on both VT6202 and VT8235.
*/
- if (HCD_IS_RUNNING (ehci->hcd.state) && (ehci->async->qh_next.ptr != 0
- || ehci->periodic_sched != 0))
+ if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
+ (ehci->async->qh_next.ptr != 0 ||
+ ehci->periodic_sched != 0))
timer_action (ehci, TIMER_IO_WATCHDOG);
}
@@ -852,7 +854,7 @@
}
/* remote wakeup [4.3.1] */
- if ((status & STS_PCD) && ehci->hcd.remote_wakeup) {
+ if ((status & STS_PCD) && hcd->remote_wakeup) {
unsigned i = HCS_N_PORTS (ehci->hcs_params);
/* resume root hub? */
@@ -873,7 +875,7 @@
* stop that signaling.
*/
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
- mod_timer (&ehci->hcd.rh_timer,
+ mod_timer (&hcd->rh_timer,
ehci->reset_done [i] + 1);
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
}
@@ -947,7 +949,7 @@
/* if we need to use IAA and it's busy, defer */
if (qh->qh_state == QH_STATE_LINKED
&& ehci->reclaim
- && HCD_IS_RUNNING (ehci->hcd.state)) {
+ && HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)) {
struct ehci_qh *last;
for (last = ehci->reclaim;
@@ -958,7 +960,7 @@
last->reclaim = qh;
/* bypass IAA if the hc can't care */
- } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
+ } else if (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim)
end_unlink_async (ehci, NULL);
/* something else might have unlinked the qh by now */
@@ -1006,7 +1008,7 @@
/* reschedule QH iff another request is queued */
if (!list_empty (&qh->qtd_list)
- && HCD_IS_RUNNING (ehci->hcd.state)) {
+ && HCD_IS_RUNNING (hcd->state)) {
int status;
status = qh_schedule (ehci, qh);
@@ -1062,7 +1064,7 @@
goto idle_timeout;
}
- if (!HCD_IS_RUNNING (ehci->hcd.state))
+ if (!HCD_IS_RUNNING (hcd->state))
qh->qh_state = QH_STATE_IDLE;
switch (qh->qh_state) {
case QH_STATE_LINKED:
@@ -1107,6 +1109,8 @@
static const struct hc_driver ehci_driver = {
.description = hcd_name,
+ .product_desc = "EHCI Host Controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
/*
* generic hardware linkage
@@ -1124,11 +1128,6 @@
.resume = ehci_resume,
#endif
.stop = ehci_stop,
-
- /*
- * memory lifecycle (except per-request)
- */
- .hcd_alloc = ehci_hcd_alloc,
/*
* managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci-hub.c 2005-01-07 15:43:52 -08:00
@@ -44,7 +44,7 @@
/* stop schedules, clean any completed work */
if (HCD_IS_RUNNING(hcd->state)) {
ehci_quiesce (ehci);
- ehci->hcd.state = USB_STATE_QUIESCING;
+ hcd->state = USB_STATE_QUIESCING;
}
ehci->command = readl (&ehci->regs->command);
if (ehci->reclaim)
@@ -59,7 +59,7 @@
if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
t2 |= PORT_SUSPEND;
- if (ehci->hcd.remote_wakeup)
+ if (hcd->remote_wakeup)
t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
else
t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -73,7 +73,7 @@
/* turn off now-idle HC */
ehci_halt (ehci);
- ehci->hcd.state = HCD_STATE_SUSPENDED;
+ hcd->state = HCD_STATE_SUSPENDED;
ehci->next_statechange = jiffies + msecs_to_jiffies(10);
spin_unlock_irq (&ehci->lock);
@@ -145,7 +145,7 @@
}
ehci->next_statechange = jiffies + msecs_to_jiffies(5);
- ehci->hcd.state = USB_STATE_RUNNING;
+ hcd->state = USB_STATE_RUNNING;
/* Now we can safely re-enable irqs */
if (intr_enable)
@@ -212,7 +212,7 @@
unsigned long flags;
/* if !USB_SUSPEND, root hub timers won't get shut down ... */
- if (!HCD_IS_RUNNING(ehci->hcd.state))
+ if (!HCD_IS_RUNNING(hcd->state))
return 0;
/* init status to no-changes */
@@ -499,7 +499,7 @@
if ((temp & PORT_PE) == 0
|| (temp & PORT_RESET) != 0)
goto error;
- if (ehci->hcd.remote_wakeup)
+ if (hcd->remote_wakeup)
temp |= PORT_WAKE_BITS;
writel (temp | PORT_SUSPEND,
&ehci->regs->port_status [wIndex]);
diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
--- a/drivers/usb/host/ehci-mem.c 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci-mem.c 2005-01-07 15:43:52 -08:00
@@ -32,25 +32,6 @@
*/
/*-------------------------------------------------------------------------*/
-/*
- * Allocator / cleanup for the per device structure
- * Called by hcd init / removal code
- */
-static struct usb_hcd *ehci_hcd_alloc (void)
-{
- struct ehci_hcd *ehci;
-
- ehci = (struct ehci_hcd *)
- kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
- if (ehci != 0) {
- memset (ehci, 0, sizeof (struct ehci_hcd));
- ehci->hcd.product_desc = "EHCI Host Controller";
- return &ehci->hcd;
- }
- return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
/* Allocate the key transfer structures from the previously allocated pool */
@@ -169,7 +150,7 @@
ehci->sitd_pool = NULL;
if (ehci->periodic)
- dma_free_coherent (ehci->hcd.self.controller,
+ dma_free_coherent (ehci_to_hcd(ehci)->self.controller,
ehci->periodic_size * sizeof (u32),
ehci->periodic, ehci->periodic_dma);
ehci->periodic = NULL;
@@ -187,7 +168,7 @@
/* QTDs for control/bulk/intr transfers */
ehci->qtd_pool = dma_pool_create ("ehci_qtd",
- ehci->hcd.self.controller,
+ ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_qtd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -197,7 +178,7 @@
/* QHs for control/bulk/intr transfers */
ehci->qh_pool = dma_pool_create ("ehci_qh",
- ehci->hcd.self.controller,
+ ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_qh),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -211,7 +192,7 @@
/* ITD for high speed ISO transfers */
ehci->itd_pool = dma_pool_create ("ehci_itd",
- ehci->hcd.self.controller,
+ ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_itd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -221,7 +202,7 @@
/* SITD for full/low speed split ISO transfers */
ehci->sitd_pool = dma_pool_create ("ehci_sitd",
- ehci->hcd.self.controller,
+ ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_sitd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -231,7 +212,7 @@
/* Hardware periodic table */
ehci->periodic = (__le32 *)
- dma_alloc_coherent (ehci->hcd.self.controller,
+ dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
ehci->periodic_size * sizeof(__le32),
&ehci->periodic_dma, 0);
if (ehci->periodic == 0) {
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci-q.c 2005-01-07 15:43:52 -08:00
@@ -200,7 +200,7 @@
|| QTD_CERR(token) == 0)
&& (!ehci_is_ARC(ehci)
|| urb->dev->tt->hub !=
- ehci->hcd.self.root_hub)) {
+ ehci_to_hcd(ehci)->self.root_hub)) {
#ifdef DEBUG
struct usb_device *tt = urb->dev->tt->hub;
dev_dbg (&tt->dev,
@@ -225,7 +225,7 @@
if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
- hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
+ ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
}
qh_put (qh);
}
@@ -262,7 +262,7 @@
/* complete() can reenter this HCD */
spin_unlock (&ehci->lock);
- usb_hcd_giveback_urb (&ehci->hcd, urb, regs);
+ usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb, regs);
spin_lock (&ehci->lock);
}
@@ -347,13 +347,13 @@
/* stop scanning when we reach qtds the hc is using */
} else if (likely (!stopped
- && HCD_IS_RUNNING (ehci->hcd.state))) {
+ && HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))) {
break;
} else {
stopped = 1;
- if (unlikely (!HCD_IS_RUNNING (ehci->hcd.state)))
+ if (unlikely (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)))
urb->status = -ESHUTDOWN;
/* ignore active urbs unless some previous qtd
@@ -717,7 +717,8 @@
* root hub tt, leave it zeroed.
*/
if (!ehci_is_ARC(ehci)
- || urb->dev->tt->hub != ehci->hcd.self.root_hub)
+ || urb->dev->tt->hub !=
+ ehci_to_hcd(ehci)->self.root_hub)
info2 |= urb->dev->tt->hub->devnum << 16;
/* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */
@@ -778,7 +779,7 @@
(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
cmd |= CMD_ASE | CMD_RUN;
writel (cmd, &ehci->regs->command);
- ehci->hcd.state = USB_STATE_RUNNING;
+ ehci_to_hcd(ehci)->state = USB_STATE_RUNNING;
/* posted write need not be known to HC yet ... */
}
}
@@ -957,7 +958,7 @@
qh_completions (ehci, qh, regs);
if (!list_empty (&qh->qtd_list)
- && HCD_IS_RUNNING (ehci->hcd.state))
+ && HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
qh_link_async (ehci, qh);
else {
qh_put (qh); // refcount from async list
@@ -965,7 +966,7 @@
/* it's not free to turn the async schedule on/off; leave it
* active but idle for a while once it empties.
*/
- if (HCD_IS_RUNNING (ehci->hcd.state)
+ if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)
&& ehci->async->qh_next.qh == 0)
timer_action (ehci, TIMER_ASYNC_OFF);
}
@@ -999,7 +1000,7 @@
/* stop async schedule right now? */
if (unlikely (qh == ehci->async)) {
/* can't get here without STS_ASS set */
- if (ehci->hcd.state != USB_STATE_HALT) {
+ if (ehci_to_hcd(ehci)->state != USB_STATE_HALT) {
writel (cmd & ~CMD_ASE, &ehci->regs->command);
wmb ();
// handshake later, if we need to
@@ -1019,7 +1020,7 @@
prev->qh_next = qh->qh_next;
wmb ();
- if (unlikely (ehci->hcd.state == USB_STATE_HALT)) {
+ if (unlikely (ehci_to_hcd(ehci)->state == USB_STATE_HALT)) {
/* if (unlikely (qh->reclaim != 0))
* this will recurse, probably not much
*/
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci-sched.c 2005-01-07 15:43:52 -08:00
@@ -249,14 +249,14 @@
*/
status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125);
if (status != 0) {
- ehci->hcd.state = USB_STATE_HALT;
+ ehci_to_hcd(ehci)->state = USB_STATE_HALT;
return status;
}
cmd = readl (&ehci->regs->command) | CMD_PSE;
writel (cmd, &ehci->regs->command);
/* posted write ... PSS happens later */
- ehci->hcd.state = USB_STATE_RUNNING;
+ ehci_to_hcd(ehci)->state = USB_STATE_RUNNING;
/* make sure ehci_work scans these */
ehci->next_uframe = readl (&ehci->regs->frame_index)
@@ -274,7 +274,7 @@
*/
status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125);
if (status != 0) {
- ehci->hcd.state = USB_STATE_HALT;
+ ehci_to_hcd(ehci)->state = USB_STATE_HALT;
return status;
}
@@ -348,7 +348,7 @@
qh_get (qh);
/* update per-qh bandwidth for usbfs */
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated += qh->period
+ ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->period
? ((qh->usecs + qh->c_usecs) / qh->period)
: (qh->usecs * 8);
@@ -379,7 +379,7 @@
periodic_unlink (ehci, i, qh);
/* update per-qh bandwidth for usbfs */
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated -= qh->period
+ ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->period
? ((qh->usecs + qh->c_usecs) / qh->period)
: (qh->usecs * 8);
@@ -618,7 +618,7 @@
BUG_ON (qh == 0);
/* ... update usbfs periodic stats */
- hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs++;
+ ehci_to_hcd(ehci)->self.bandwidth_int_reqs++;
done:
spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1258,7 +1258,7 @@
next_uframe = stream->next_uframe % mod;
if (unlikely (list_empty(&stream->td_list))) {
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+ ehci_to_hcd(ehci)->self.bandwidth_allocated
+= stream->bandwidth;
ehci_vdbg (ehci,
"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
@@ -1268,7 +1268,7 @@
next_uframe >> 3, next_uframe & 0x7);
stream->start = jiffies;
}
- hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs++;
+ ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
/* fill iTDs uframe by uframe */
for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
@@ -1390,10 +1390,10 @@
ehci->periodic_sched--;
if (unlikely (!ehci->periodic_sched))
(void) disable_periodic (ehci);
- hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs--;
+ ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
if (unlikely (list_empty (&stream->td_list))) {
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+ ehci_to_hcd(ehci)->self.bandwidth_allocated
-= stream->bandwidth;
ehci_vdbg (ehci,
"deschedule devp %s ep%d%s-iso\n",
@@ -1643,7 +1643,7 @@
if (list_empty(&stream->td_list)) {
/* usbfs ignores TT bandwidth */
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+ ehci_to_hcd(ehci)->self.bandwidth_allocated
+= stream->bandwidth;
ehci_vdbg (ehci,
"sched dev%s ep%d%s-iso [%d] %dms/%04x\n",
@@ -1653,7 +1653,7 @@
stream->interval, le32_to_cpu (stream->splits));
stream->start = jiffies;
}
- hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs++;
+ ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
/* fill sITDs frame by frame */
for (packet = 0, sitd = NULL;
@@ -1753,10 +1753,10 @@
ehci->periodic_sched--;
if (!ehci->periodic_sched)
(void) disable_periodic (ehci);
- hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs--;
+ ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
if (list_empty (&stream->td_list)) {
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+ ehci_to_hcd(ehci)->self.bandwidth_allocated
-= stream->bandwidth;
ehci_vdbg (ehci,
"deschedule devp %s ep%d%s-iso\n",
@@ -1860,7 +1860,7 @@
* Touches as few pages as possible: cache-friendly.
*/
now_uframe = ehci->next_uframe;
- if (HCD_IS_RUNNING (ehci->hcd.state))
+ if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
clock = readl (&ehci->regs->frame_index);
else
clock = now_uframe + mod - 1;
@@ -1894,7 +1894,7 @@
union ehci_shadow temp;
int live;
- live = HCD_IS_RUNNING (ehci->hcd.state);
+ live = HCD_IS_RUNNING (ehci_to_hcd(ehci)->state);
switch (type) {
case Q_TYPE_QH:
/* handle any completions */
@@ -1983,7 +1983,7 @@
if (now_uframe == clock) {
unsigned now;
- if (!HCD_IS_RUNNING (ehci->hcd.state))
+ if (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
break;
ehci->next_uframe = now_uframe;
now = readl (&ehci->regs->frame_index) % mod;
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h 2005-01-07 15:43:52 -08:00
+++ b/drivers/usb/host/ehci.h 2005-01-07 15:43:52 -08:00
@@ -47,13 +47,6 @@
#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */
struct ehci_hcd { /* one per controller */
-
- /* glue to PCI and HCD framework */
- struct usb_hcd hcd; /* must come first! */
- struct ehci_caps __iomem *caps;
- struct ehci_regs __iomem *regs;
- __u32 hcs_params; /* cached register copy */
-
spinlock_t lock;
/* async schedule support */
@@ -91,6 +84,11 @@
unsigned is_arc_rh_tt:1; /* ARC roothub with TT */
+ /* glue to PCI and HCD framework */
+ struct ehci_caps __iomem *caps;
+ struct ehci_regs __iomem *regs;
+ __u32 hcs_params; /* cached register copy */
+
/* irq statistics */
#ifdef EHCI_STATS
struct ehci_stats stats;
@@ -100,8 +98,15 @@
#endif
};
-/* unwrap an HCD pointer to get an EHCI_HCD pointer */
-#define hcd_to_ehci(hcd_ptr) container_of(hcd_ptr, struct ehci_hcd, hcd)
+/* convert between an HCD pointer and the corresponding EHCI_HCD */
+static inline struct ehci_hcd *hcd_to_ehci (struct usb_hcd *hcd)
+{
+ return (struct ehci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci)
+{
+ return container_of ((void *) ehci, struct usb_hcd, hcd_priv);
+}
enum ehci_timer_action {
ChangeSet 1.1938.446.47, 2004/12/20 15:00:38-08:00, [email protected]
[PATCH] USB: Hub driver: several bug fixes and simplifications [11/13]
This patch adds several relatively minor bug fixes and code
simplifications for the hub driver.
Perhaps most significantly, a test is added to usbfs to prevent
users from unbinding the hub driver from a hub with children.
That could cause some bad headaches, and it's best to avoid the
situation.
Don't set unused bits in the change_bits and event_bits fields
(this aids in debugging, nothing more).
Use the correct spinlock in the hub ioctl routine!
Add an argument to hub_port_disable, indicating whether the
device behind the disabled port should be marked NOTATTACHED.
Normally it should, but for retries during usb_reset_device
it should not.
Pass the child device as an argument to hub_port_suspend and
hub_port_resume rather than making them recalculate it.
Call usb_set_device_state in the suspend/resume code rather
than setting udev->state directly.
Set udev->power.power_state in the suspend/resume code so that
the correct values are visible in sysfs.
Recognize during hub_port_resume that the child device udev
might be NULL (this will happen when a new device is plugged
into a suspended port).
Don't allow hub_port_init to drop the usb_address0_sem lock
while a device on the bus is still using address 0!
Make khubd acquire a reference to the hub interface rather than
the hub device. This simplifies disconnect/unbind testing.
Don't print a debugging message about hub events while not
holding some lock to protect the hub.
Remember to drop the reference acquired above if we fail to
lock the hub.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/devio.c | 11 +++++
drivers/usb/core/hub.c | 101 +++++++++++++++++++++++++----------------------
2 files changed, 66 insertions(+), 46 deletions(-)
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c 2005-01-07 15:42:59 -08:00
+++ b/drivers/usb/core/devio.c 2005-01-07 15:42:59 -08:00
@@ -1122,6 +1122,7 @@
int retval = 0;
struct usb_interface *intf = NULL;
struct usb_driver *driver = NULL;
+ int i;
/* get input parameters and alloc buffer */
if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
@@ -1153,6 +1154,16 @@
/* disconnect kernel driver from interface */
case USBDEVFS_DISCONNECT:
+
+ /* don't allow the user to unbind the hub driver from
+ * a hub with children to manage */
+ for (i = 0; i < ps->dev->maxchild; ++i) {
+ if (ps->dev->children[i])
+ retval = -EBUSY;
+ }
+ if (retval)
+ break;
+
down_write(&usb_bus_type.subsys.rwsem);
if (intf->dev.driver) {
driver = to_usb_driver(intf->dev.driver);
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:42:59 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:42:59 -08:00
@@ -465,7 +465,7 @@
schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
/* scan all ports ASAP */
- hub->event_bits[0] = ~0;
+ hub->event_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 1;
kick_khubd(hub);
}
@@ -688,7 +688,7 @@
hub->indicator [0] = INDICATOR_CYCLE;
hub_power_on(hub);
- hub->change_bits[0] = ~0;
+ hub->change_bits[0] = (1UL << (hub->descriptor->bNbrPorts)) - 1;
hub_activate(hub);
return 0;
@@ -816,10 +816,9 @@
switch (code) {
case USBDEVFS_HUB_PORTINFO: {
struct usbdevfs_hub_portinfo *info = user_data;
- unsigned long flags;
int i;
- spin_lock_irqsave(&hub_event_lock, flags);
+ spin_lock_irq(&device_state_lock);
if (hdev->devnum <= 0)
info->nports = 0;
else {
@@ -832,7 +831,7 @@
hdev->children[i]->devnum;
}
}
- spin_unlock_irqrestore(&hub_event_lock, flags);
+ spin_unlock_irq(&device_state_lock);
return info->nports + 1;
}
@@ -1413,11 +1412,11 @@
return status;
}
-static int hub_port_disable(struct usb_device *hdev, int port)
+static int hub_port_disable(struct usb_device *hdev, int port, int set_state)
{
int ret;
- if (hdev->children[port]) {
+ if (hdev->children[port] && set_state) {
usb_set_device_state(hdev->children[port],
USB_STATE_NOTATTACHED);
}
@@ -1439,7 +1438,7 @@
struct usb_hub *hub;
dev_dbg(hubdev(hdev), "logical disconnect on port %d\n", port + 1);
- hub_port_disable(hdev, port);
+ hub_port_disable(hdev, port, 1);
/* FIXME let caller ask to power down the port:
* - some devices won't enumerate without a VBUS power cycle
@@ -1468,12 +1467,11 @@
* tree above them to deliver data, such as a keypress or packet. In
* some cases, this wakes the USB host.
*/
-static int hub_port_suspend(struct usb_device *hdev, int port)
+static int hub_port_suspend(struct usb_device *hdev, int port,
+ struct usb_device *udev)
{
- int status;
- struct usb_device *udev;
+ int status;
- udev = hdev->children[port];
// dev_dbg(hubdev(hdev), "suspend port %d\n", port + 1);
/* enable remote wakeup when appropriate; this lets the device
@@ -1513,7 +1511,7 @@
} else {
/* device has up to 10 msec to fully suspend */
dev_dbg(&udev->dev, "usb suspend\n");
- udev->state = USB_STATE_SUSPENDED;
+ usb_set_device_state(udev, USB_STATE_SUSPENDED);
msleep(10);
}
return status;
@@ -1620,8 +1618,10 @@
} else
status = -EOPNOTSUPP;
} else
- status = hub_port_suspend(udev->parent, port);
+ status = hub_port_suspend(udev->parent, port, udev);
+ if (status == 0)
+ udev->dev.power.power_state = state;
return status;
}
EXPORT_SYMBOL(__usb_suspend_device);
@@ -1675,9 +1675,10 @@
* first two on the host side; they'd be inside hub_port_init()
* during many timeouts, but khubd can't suspend until later.
*/
- udev->state = udev->actconfig
- ? USB_STATE_CONFIGURED
- : USB_STATE_ADDRESS;
+ usb_set_device_state(udev, udev->actconfig
+ ? USB_STATE_CONFIGURED
+ : USB_STATE_ADDRESS);
+ udev->dev.power.power_state = PM_SUSPEND_ON;
/* 10.5.4.5 says be sure devices in the tree are still there.
* For now let's assume the device didn't go crazy on resume,
@@ -1745,12 +1746,10 @@
}
static int
-hub_port_resume(struct usb_device *hdev, int port)
+hub_port_resume(struct usb_device *hdev, int port, struct usb_device *udev)
{
- int status;
- struct usb_device *udev;
+ int status;
- udev = hdev->children[port];
// dev_dbg(hubdev(hdev), "resume port %d\n", port + 1);
/* see 7.1.7.7; affects power usage, but not budgeting */
@@ -1764,7 +1763,8 @@
u16 portchange;
/* drive resume for at least 20 msec */
- dev_dbg(&udev->dev, "RESUME\n");
+ if (udev)
+ dev_dbg(&udev->dev, "RESUME\n");
msleep(25);
#define LIVE_FLAGS ( USB_PORT_STAT_POWER \
@@ -1788,7 +1788,8 @@
} else {
/* TRSMRCY = 10 msec */
msleep(10);
- status = finish_port_resume(udev);
+ if (udev)
+ status = finish_port_resume(udev);
}
}
if (status < 0)
@@ -1838,7 +1839,7 @@
}
} else if (udev->state == USB_STATE_SUSPENDED) {
// NOTE this fails if parent is also suspended...
- status = hub_port_resume(udev->parent, port);
+ status = hub_port_resume(udev->parent, port, udev);
} else {
status = 0;
}
@@ -1937,7 +1938,7 @@
continue;
down (&udev->serialize);
if (portstat & USB_PORT_STAT_SUSPEND)
- status = hub_port_resume(hdev, port);
+ status = hub_port_resume(hdev, port, udev);
else {
status = finish_port_resume(udev);
if (status < 0) {
@@ -2292,6 +2293,8 @@
retval = 0;
fail:
+ if (retval)
+ hub_port_disable(hdev, port, 0);
up(&usb_address0_sem);
return retval;
}
@@ -2424,11 +2427,15 @@
}
#ifdef CONFIG_USB_SUSPEND
- /* If something is connected, but the port is suspended, wake it up.. */
+ /* If something is connected, but the port is suspended, wake it up. */
if (portstatus & USB_PORT_STAT_SUSPEND) {
- status = hub_port_resume(hdev, port);
- if (status < 0)
- dev_dbg(hub_dev, "can't clear suspend on port %d; %d\n", port+1, status);
+ status = hub_port_resume(hdev, port, NULL);
+ if (status < 0) {
+ dev_dbg(hub_dev,
+ "can't clear suspend on port %d; %d\n",
+ port+1, status);
+ goto done;
+ }
}
#endif
@@ -2474,7 +2481,7 @@
&devstat);
if (status < 0) {
dev_dbg(&udev->dev, "get status %d ?\n", status);
- goto loop;
+ goto loop_disable;
}
cpu_to_le16s(&devstat);
if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
@@ -2487,7 +2494,7 @@
schedule_work (&hub->leds);
}
status = -ENOTCONN; /* Don't retry */
- goto loop;
+ goto loop_disable;
}
}
@@ -2527,7 +2534,7 @@
up (&udev->serialize);
if (status)
- goto loop;
+ goto loop_disable;
status = hub_power_remaining(hub);
if (status)
@@ -2537,8 +2544,9 @@
return;
+loop_disable:
+ hub_port_disable(hdev, port, 1);
loop:
- hub_port_disable(hdev, port);
ep0_reinit(udev);
release_address(udev);
usb_put_dev(udev);
@@ -2547,13 +2555,14 @@
}
done:
- hub_port_disable(hdev, port);
+ hub_port_disable(hdev, port, 1);
}
static void hub_events(void)
{
struct list_head *tmp;
struct usb_device *hdev;
+ struct usb_interface *intf;
struct usb_hub *hub;
struct device *hub_dev;
u16 hubstatus;
@@ -2583,10 +2592,8 @@
hub = list_entry(tmp, struct usb_hub, event_list);
hdev = hub->hdev;
- hub_dev = &hub->intf->dev;
-
- usb_get_dev(hdev);
- spin_unlock_irq(&hub_event_lock);
+ intf = hub->intf;
+ hub_dev = &intf->dev;
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
hdev->state, hub->descriptor
@@ -2596,14 +2603,16 @@
(u16) hub->change_bits[0],
(u16) hub->event_bits[0]);
+ usb_get_intf(intf);
+ spin_unlock_irq(&hub_event_lock);
+
/* Lock the device, then check to see if we were
* disconnected while waiting for the lock to succeed. */
- if (locktree(hdev) < 0)
- break;
- if (hdev->state != USB_STATE_CONFIGURED ||
- !hdev->actconfig ||
- hub != usb_get_intfdata(
- hdev->actconfig->interface[0]))
+ if (locktree(hdev) < 0) {
+ usb_put_intf(intf);
+ continue;
+ }
+ if (hub != usb_get_intfdata(intf) || hub->quiescing)
goto loop;
if (hub->error) {
@@ -2675,7 +2684,7 @@
connect_change = 1;
} else {
ret = -ENODEV;
- hub_port_disable(hdev, i);
+ hub_port_disable(hdev, i, 1);
}
dev_dbg (hub_dev,
"resume on port %d, status %d\n",
@@ -2724,7 +2733,7 @@
loop:
usb_unlock_device(hdev);
- usb_put_dev(hdev);
+ usb_put_intf(intf);
} /* end while (1) */
}
ChangeSet 1.1938.446.28, 2004/12/16 14:39:21-08:00, [email protected]
[PATCH] USB Storage: unusual_devs: prolific atapi controler
This adds an unusual devices entry for a Prolific ATAPI-6 conmtroller
that needs the FIX_CAPACITY flag.
Signed-off-by: Alex Butcher <[email protected]>
Signed-off-by: Phil Dibowitz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/storage/unusual_devs.h | 7 +++++++
1 files changed, 7 insertions(+)
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h 2005-01-07 15:47:15 -08:00
+++ b/drivers/usb/storage/unusual_devs.h 2005-01-07 15:47:15 -08:00
@@ -532,6 +532,13 @@
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/* Reported by Alex Butcher <[email protected]> */
+UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001,
+ "Prolific Technology Inc.",
+ "ATAPI-6 Bridge Controller",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
/* Submitted by Benny Sjostrand <[email protected]> */
UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
"Minolta",
ChangeSet 1.1938.446.37, 2004/12/17 15:41:32-08:00, [email protected]
[PATCH] USB: fix up some sparse warnings in the new garmin_gps driver
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/garmin_gps.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff -Nru a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
--- a/drivers/usb/serial/garmin_gps.c 2005-01-07 15:44:39 -08:00
+++ b/drivers/usb/serial/garmin_gps.c 2005-01-07 15:44:39 -08:00
@@ -343,7 +343,7 @@
static struct garmin_packet *pkt_pop(struct garmin_data * garmin_data_p)
{
unsigned long flags;
- struct garmin_packet *result = 0;
+ struct garmin_packet *result = NULL;
spin_lock_irqsave(&garmin_data_p->lock, flags);
if (!list_empty(&garmin_data_p->pktlist)) {
@@ -359,7 +359,7 @@
static void pkt_clear(struct garmin_data * garmin_data_p)
{
unsigned long flags;
- struct garmin_packet *result = 0;
+ struct garmin_packet *result = NULL;
dbg("%s", __FUNCTION__);
@@ -737,10 +737,9 @@
*/
static void gsp_next_packet(struct garmin_data * garmin_data_p)
{
- struct garmin_packet *pkt = 0;
+ struct garmin_packet *pkt = NULL;
- while ((pkt = pkt_pop(garmin_data_p)) != 0)
- {
+ while ((pkt = pkt_pop(garmin_data_p)) != 0) {
dbg("%s - next pkt: %d", __FUNCTION__, pkt->seq);
if (gsp_send(garmin_data_p, pkt->data, pkt->size) > 0) {
kfree(pkt);
@@ -1428,7 +1427,7 @@
{
int status = 0;
struct usb_serial_port *port = serial->port[0];
- struct garmin_data * garmin_data_p = 0;
+ struct garmin_data * garmin_data_p = NULL;
dbg("%s", __FUNCTION__);
ChangeSet 1.1938.446.11, 2004/12/15 16:01:23-08:00, [email protected]
[PATCH] usb-serial: add tty_hangup on disconnect
When a USB serial device is disconnected, user applications performing a
read() now receive an error code, rather than waiting indefinitely. The
included patch is originally from Al Borchers, massaged to apply to
2.6.9 and 2.6.10-rc2. I've tested it on 2.6.9, but not on 2.6.10-rc2.
Al Borcher's original post:
http://www.mail-archive.com/[email protected]/msg27475.html
Signed-off-by: Edwin Olson ([email protected])
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/usb-serial.c | 7 +++++++
1 files changed, 7 insertions(+)
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c 2005-01-07 15:50:08 -08:00
+++ b/drivers/usb/serial/usb-serial.c 2005-01-07 15:50:08 -08:00
@@ -1238,13 +1238,20 @@
void usb_serial_disconnect(struct usb_interface *interface)
{
+ int i;
struct usb_serial *serial = usb_get_intfdata (interface);
struct device *dev = &interface->dev;
+ struct usb_serial_port *port;
dbg ("%s", __FUNCTION__);
usb_set_intfdata (interface, NULL);
if (serial) {
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ if (port && port->tty)
+ tty_hangup(port->tty);
+ }
/* let the last holder of this object
* cause it to be cleaned up */
kref_put(&serial->kref, destroy_serial);
ChangeSet 1.1938.446.9, 2004/12/15 15:11:26-08:00, [email protected]
[PATCH] USB: update drivers/usb/README
This just adds a bit more info to drivers/usb/README, mostly
just pointing to where documentation is to be found (including
current kerneldoc).
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/README | 33 ++++++++++++++++++++++++++++-----
1 files changed, 28 insertions(+), 5 deletions(-)
diff -Nru a/drivers/usb/README b/drivers/usb/README
--- a/drivers/usb/README 2005-01-07 15:50:23 -08:00
+++ b/drivers/usb/README 2005-01-07 15:50:23 -08:00
@@ -1,14 +1,37 @@
+To understand all the Linux-USB framework, you'll use these resources:
+
+ * This source code. This is necessarily an evolving work, and
+ includes kerneldoc that should help you get a current overview.
+ ("make pdfdocs", and then look at "usb.pdf" for host side and
+ "gadget.pdf" for peripheral side.) Also, Documentation/usb has
+ more information.
+
+ * The USB 2.0 specification (from http://www.usb.org), with supplements
+ such as those for USB OTG and the various device classes.
+ The USB specification has a good overview chapter, and USB
+ peripherals conform to the widely known "Chapter 9".
+
+ * Chip specifications for USB controllers. Examples include
+ host controllers (on PCs, servers, and more); peripheral
+ controllers (in devices with Linux firmware, like printers or
+ cell phones); and hard-wired peripherals like Ethernet adapters.
+
+ * Specifications for other protocols implemented by USB peripheral
+ functions. Some are vendor-specific; others are vendor-neutral
+ but just standardized outside of the http://www.usb.org team.
+
Here is a list of what each subdirectory here is, and what is contained in
them.
core/ - This is for the core USB host code, including the
- usbfs files.
+ usbfs files and the hub class driver ("khubd").
-host/ - This is for all of the USB host drivers. This
- includes UHCI, OHCI, EHCI, and any others that might
- be created in the future.
+host/ - This is for USB host controller drivers. This
+ includes UHCI, OHCI, EHCI, and others that might
+ be used with more specialized "embedded" systems.
-gadget/ - This is for all of the USB device controller drivers.
+gadget/ - This is for USB peripheral controller drivers and
+ the various gadget drivers which talk to them.
Individual USB driver directories. A new driver should be added to the
ChangeSet 1.1938.446.34, 2004/12/17 15:39:21-08:00, [email protected]
[PATCH] USB: gadget kconfig doc updates
This updates the "USB Gadget" Kconfig support:
- Highlighting the the two Documentation/usb files have
information about how to interoperate with MS-Windows
using RNDIS or CDC-ACM;
- Flagging CDC ACM and CDC Ethernet support in the config
menu descriptions;
- Providing a bit more description about what a "gadget driver"
does, for the benefit of folk coming to this part of Linux
with background in similar proprietary driver stacks.
- Pointing to the Linux-USB website for this API, and the
kerneldoc.
In short: make important driver framework information more accessible.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/Kconfig | 35 +++++++++++++++++++++++++++++++++--
1 files changed, 33 insertions(+), 2 deletions(-)
diff -Nru a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
--- a/drivers/usb/gadget/Kconfig 2005-01-07 15:45:15 -08:00
+++ b/drivers/usb/gadget/Kconfig 2005-01-07 15:45:15 -08:00
@@ -39,6 +39,9 @@
If in doubt, say "N" and don't enable these drivers; most people
don't have this kind of hardware (except maybe inside Linux PDAs).
+ For more information, see <http://www.linux-usb.org/gadget> and
+ the kernel DocBook documentation for this API.
+
config USB_GADGET_DEBUG_FILES
boolean "Debugging information files"
depends on USB_GADGET && PROC_FS
@@ -59,6 +62,8 @@
help
A USB device uses a controller to talk to its host.
Systems should have only one such upstream link.
+ Many controller drivers are platform-specific; these
+ often need board-specific hooks.
config USB_GADGET_NET2280
boolean "NetChip 2280"
@@ -234,6 +239,21 @@
tristate "USB Gadget Drivers"
depends on USB_GADGET
default USB_ETH
+ help
+ A Linux "Gadget Driver" talks to the USB Peripheral Controller
+ driver through the abstract "gadget" API. Some other operating
+ systems call these "client" drivers, of which "class drivers"
+ are a subset (implementing a USB device class specification).
+ A gadget driver implements one or more USB functions using
+ the peripheral hardware.
+
+ Gadget drivers are hardware-neutral, or "platform independent",
+ except that they sometimes must understand quirks or limitations
+ of the particular controllers they work with. For example, when
+ a controller doesn't support alternate configurations or provide
+ enough of the right types of endpoints, the gadget driver might
+ not be able work with that controller, or might need to implement
+ a less common variant of a device class protocol.
# this first set of drivers all depend on bulk-capable hardware.
@@ -273,7 +293,7 @@
one serve as the USB host instead (in the "B-Host" role).
config USB_ETH
- tristate "Ethernet Gadget"
+ tristate "Ethernet Gadget (with CDC Ethernet support)"
depends on NET
help
This driver implements Ethernet style communication, in either
@@ -314,6 +334,11 @@
If you say "y" here, the Ethernet gadget driver will try to provide
a second device configuration, supporting RNDIS to talk to such
Microsoft USB hosts.
+
+ To make MS-Windows work with this, use Documentation/usb/linux.inf
+ as the "driver info file". For versions of MS-Windows older than
+ XP, you'll need to download drivers from Microsoft's website; a URL
+ is given in comments found in that info file.
config USB_GADGETFS
tristate "Gadget Filesystem (EXPERIMENTAL)"
@@ -352,13 +377,19 @@
normal operation.
config USB_G_SERIAL
- tristate "Serial Gadget"
+ tristate "Serial Gadget (with CDC ACM support)"
help
The Serial Gadget talks to the Linux-USB generic serial driver.
+ This driver supports a CDC-ACM module option, which can be used
+ to interoperate with MS-Windows hosts or with the Linux-USB
+ "cdc-acm" driver.
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_serial".
+ For more information, see Documentation/usb/gadget_serial.txt
+ which includes instructions and a "driver info file" needed to
+ make MS-Windows work with this driver.
# put drivers that need isochronous transfer support (for audio
ChangeSet 1.1938.446.19, 2004/12/15 16:34:18-08:00, [email protected]
[PATCH] USB: EHCI HCD and usb_dev->epmaxpacket (7/15)
Makes EHCI stop referencing the udev->epmaxpacket[] arrays.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-sched.c | 3 +--
1 files changed, 1 insertion(+), 2 deletions(-)
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c 2005-01-07 15:49:06 -08:00
+++ b/drivers/usb/host/ehci-sched.c 2005-01-07 15:49:06 -08:00
@@ -614,11 +614,10 @@
*/
epnum = usb_pipeendpoint (pipe);
is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
+ maxp = usb_maxpacket(dev, pipe, !is_input);
if (is_input) {
- maxp = dev->epmaxpacketin [epnum];
buf1 = (1 << 11);
} else {
- maxp = dev->epmaxpacketout [epnum];
buf1 = 0;
}
ChangeSet 1.1938.446.17, 2004/12/15 16:33:30-08:00, [email protected]
[PATCH] USB: auerswald and usb_dev->ep[] (5/15)
Update the auerswald driver to stop using the now-vanished
usb_epnum_to_ep_desc() function.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/misc/auerswald.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c 2005-01-07 15:49:22 -08:00
+++ b/drivers/usb/misc/auerswald.c 2005-01-07 15:49:22 -08:00
@@ -1123,16 +1123,16 @@
static int auerswald_int_open (pauerswald_t cp)
{
int ret;
- struct usb_endpoint_descriptor *ep;
+ struct usb_host_endpoint *ep;
int irqsize;
dbg ("auerswald_int_open");
- ep = usb_epnum_to_ep_desc (cp->usbdev, USB_DIR_IN | AU_IRQENDP);
+ ep = cp->usbdev->ep_in[AU_IRQENDP];
if (!ep) {
ret = -EFAULT;
goto intoend;
}
- irqsize = ep->wMaxPacketSize;
+ irqsize = ep->desc.wMaxPacketSize;
cp->irqsize = irqsize;
/* allocate the urb and data buffer */
@@ -1151,7 +1151,9 @@
}
}
/* setup urb */
- usb_fill_int_urb (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval);
+ usb_fill_int_urb (cp->inturbp, cp->usbdev,
+ usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp,
+ irqsize, auerswald_int_complete, cp, ep->desc.bInterval);
/* start the urb */
cp->inturbp->status = 0; /* needed! */
ret = usb_submit_urb (cp->inturbp, GFP_KERNEL);
ChangeSet 1.1938.446.22, 2004/12/15 16:35:26-08:00, [email protected]
[PATCH] USB: remove some now-unused HCD infrastructure (10/15)
This removes the code supporting usb_device->hcpriv allocation/deallocation,
and hcd_dev-dev_list, from usbcore and the HCDs.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hcd-pci.c | 2 -
drivers/usb/core/hcd.c | 74 ----------------------------------------
drivers/usb/core/usb.c | 9 ----
drivers/usb/host/ohci-lh7a404.c | 2 -
drivers/usb/host/ohci-omap.c | 1
drivers/usb/host/ohci-pxa27x.c | 2 -
drivers/usb/host/ohci-sa1111.c | 2 -
7 files changed, 92 deletions(-)
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/core/hcd-pci.c 2005-01-07 15:48:43 -08:00
@@ -195,8 +195,6 @@
hcd->self.hcpriv = (void *) hcd;
init_timer (&hcd->rh_timer);
- INIT_LIST_HEAD (&hcd->dev_list);
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0) {
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:48:43 -08:00
@@ -1018,40 +1018,6 @@
/*-------------------------------------------------------------------------*/
-/* called from khubd, or root hub init threads for hcd-private init */
-static int hcd_alloc_dev (struct usb_device *udev)
-{
- struct hcd_dev *dev;
- struct usb_hcd *hcd;
- unsigned long flags;
-
- if (!udev || udev->hcpriv)
- return -EINVAL;
- if (!udev->bus || !udev->bus->hcpriv)
- return -ENODEV;
- hcd = udev->bus->hcpriv;
- if (hcd->state == USB_STATE_QUIESCING)
- return -ENOLINK;
-
- dev = (struct hcd_dev *) kmalloc (sizeof *dev, GFP_KERNEL);
- if (dev == NULL)
- return -ENOMEM;
- memset (dev, 0, sizeof *dev);
-
- INIT_LIST_HEAD (&dev->dev_list);
- INIT_LIST_HEAD (&dev->urb_list);
-
- spin_lock_irqsave (&hcd_data_lock, flags);
- list_add (&dev->dev_list, &hcd->dev_list);
- // refcount is implicit
- udev->hcpriv = dev;
- spin_unlock_irqrestore (&hcd_data_lock, flags);
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
static void urb_unlink (struct urb *urb)
{
unsigned long flags;
@@ -1463,44 +1429,6 @@
/*-------------------------------------------------------------------------*/
-/* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup.
- * we're guaranteed that the device is fully quiesced. also, that each
- * endpoint has been hcd_endpoint_disabled.
- */
-
-static int hcd_free_dev (struct usb_device *udev)
-{
- struct hcd_dev *dev;
- struct usb_hcd *hcd;
- unsigned long flags;
-
- if (!udev || !udev->hcpriv)
- return -EINVAL;
-
- if (!udev->bus || !udev->bus->hcpriv)
- return -ENODEV;
-
- // should udev->devnum == -1 ??
-
- dev = udev->hcpriv;
- hcd = udev->bus->hcpriv;
-
- /* device driver problem with refcounts? */
- if (!list_empty (&dev->urb_list)) {
- dev_dbg (hcd->self.controller, "free busy dev, %s devnum %d (bug!)\n",
- hcd->self.bus_name, udev->devnum);
- return -EINVAL;
- }
-
- spin_lock_irqsave (&hcd_data_lock, flags);
- list_del (&dev->dev_list);
- udev->hcpriv = NULL;
- spin_unlock_irqrestore (&hcd_data_lock, flags);
-
- kfree (dev);
- return 0;
-}
-
/*
* usb_hcd_operations - adapts usb_bus framework to HCD framework (bus glue)
*
@@ -1509,11 +1437,9 @@
* bus glue for non-PCI system busses will need to use this.
*/
struct usb_operations usb_hcd_operations = {
- .allocate = hcd_alloc_dev,
.get_frame_number = hcd_get_frame_number,
.submit_urb = hcd_submit_urb,
.unlink_urb = hcd_unlink_urb,
- .deallocate = hcd_free_dev,
.buffer_alloc = hcd_buffer_alloc,
.buffer_free = hcd_buffer_free,
.disable = hcd_endpoint_disable,
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/core/usb.c 2005-01-07 15:48:43 -08:00
@@ -646,8 +646,6 @@
udev = to_usb_device(dev);
- if (udev->bus && udev->bus->op && udev->bus->op->deallocate)
- udev->bus->op->deallocate(udev);
usb_destroy_configuration(udev);
usb_bus_put(udev->bus);
kfree (udev);
@@ -729,13 +727,6 @@
INIT_LIST_HEAD(&dev->filelist);
init_MUTEX(&dev->serialize);
-
- if (dev->bus->op->allocate)
- if (dev->bus->op->allocate(dev)) {
- usb_bus_put(bus);
- kfree(dev);
- return NULL;
- }
return dev;
}
diff -Nru a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
--- a/drivers/usb/host/ohci-lh7a404.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/host/ohci-lh7a404.c 2005-01-07 15:48:43 -08:00
@@ -151,8 +151,6 @@
hcd->self.bus_name = "lh7a404";
hcd->product_desc = "LH7A404 OHCI";
- INIT_LIST_HEAD (&hcd->dev_list);
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
diff -Nru a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
--- a/drivers/usb/host/ohci-omap.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/host/ohci-omap.c 2005-01-07 15:48:43 -08:00
@@ -335,7 +335,6 @@
hcd->self.bus_name = pdev->dev.bus_id;
hcd->product_desc = "OMAP OHCI";
- INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
diff -Nru a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
--- a/drivers/usb/host/ohci-pxa27x.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/host/ohci-pxa27x.c 2005-01-07 15:48:43 -08:00
@@ -249,8 +249,6 @@
hcd->self.bus_name = "pxa27x";
hcd->product_desc = "PXA27x OHCI";
- INIT_LIST_HEAD (&hcd->dev_list);
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0) {
diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
--- a/drivers/usb/host/ohci-sa1111.c 2005-01-07 15:48:43 -08:00
+++ b/drivers/usb/host/ohci-sa1111.c 2005-01-07 15:48:43 -08:00
@@ -199,8 +199,6 @@
hcd->self.bus_name = "sa1111";
hcd->product_desc = "SA-1111 OHCI";
- INIT_LIST_HEAD (&hcd->dev_list);
-
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
ChangeSet 1.1938.439.46, 2005/01/06 16:39:01-08:00, [email protected]
[PATCH] add printing of udev version to scripts/ver_linux
Since udev is starting to be used a lot of places and I've seen people get
asked about their udev version a few times on lkml I figured it was
perhaps time that scripts/ver_linux reported this info so it would get
into more bugreports by default.
This patch adds printing of udev version to scripts/ver_linux
Signed-off-by: Jesper Juhl <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/Changes | 10 +++++++++-
scripts/ver_linux | 2 ++
2 files changed, 11 insertions(+), 1 deletion(-)
diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes 2005-01-07 15:39:00 -08:00
+++ b/Documentation/Changes 2005-01-07 15:39:00 -08:00
@@ -223,6 +223,11 @@
version v0.99.0 or higher. Running old versions may cause problems
with programs using shared memory.
+Udev
+----
+Udev is a userspace application for populating /dev dynamically with
+only entries for devices actually present. Udev replaces devfs.
+
Networking
==========
@@ -368,6 +373,10 @@
----------
o <http://powertweak.sourceforge.net/>
+Udev
+----
+o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>
+
Networking
**********
@@ -398,5 +407,4 @@
NFS-Utils
---------
o <http://nfs.sourceforge.net/>
-
diff -Nru a/scripts/ver_linux b/scripts/ver_linux
--- a/scripts/ver_linux 2005-01-07 15:39:00 -08:00
+++ b/scripts/ver_linux 2005-01-07 15:39:00 -08:00
@@ -87,6 +87,8 @@
expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}'
+udevinfo -V | awk '{print "udev ", $3}'
+
if [ -e /proc/modules ]; then
X=`cat /proc/modules | sed -e "s/ .*$//"`
echo "Modules Loaded "$X
ChangeSet 1.1938.446.29, 2004/12/17 11:39:40-08:00, [email protected]
[PATCH] USB: HCDs and per-device state (16/15)
SL811 changes getting rid of the "hcd_dev" support, using
usb_host_endpoint to hold the QH. This also eliminates the
"sl811h_req" data type. Compile-tested only!
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/sl811-hcd.c | 149 +++++++++++++++----------------------------
drivers/usb/host/sl811.h | 10 --
2 files changed, 53 insertions(+), 106 deletions(-)
diff -Nru a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
--- a/drivers/usb/host/sl811-hcd.c 2005-01-07 15:47:03 -08:00
+++ b/drivers/usb/host/sl811-hcd.c 2005-01-07 15:47:03 -08:00
@@ -67,7 +67,7 @@
MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION "06 Dec 2004"
+#define DRIVER_VERSION "15 Dec 2004"
#ifndef DEBUG
@@ -314,7 +314,6 @@
static struct sl811h_ep *start(struct sl811 *sl811, u8 bank)
{
struct sl811h_ep *ep;
- struct sl811h_req *req;
struct urb *urb;
int fclock;
u8 control;
@@ -348,13 +347,12 @@
struct sl811h_ep, schedule);
}
- if (unlikely(list_empty(&ep->queue))) {
+ if (unlikely(list_empty(&ep->hep->urb_list))) {
DBG("empty %p queue?\n", ep);
return NULL;
}
- req = container_of(ep->queue.next, struct sl811h_req, queue);
- urb = req->urb;
+ urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
control = ep->defctrl;
/* if this frame doesn't have enough time left to transfer this
@@ -432,17 +430,12 @@
static void finish_request(
struct sl811 *sl811,
struct sl811h_ep *ep,
- struct sl811h_req *req,
+ struct urb *urb,
struct pt_regs *regs,
int status
) __releases(sl811->lock) __acquires(sl811->lock)
{
unsigned i;
- struct urb *urb = req->urb;
-
- list_del(&req->queue);
- kfree(req);
- urb->hcpriv = NULL;
if (usb_pipecontrol(urb->pipe))
ep->nextpid = USB_PID_SETUP;
@@ -457,7 +450,7 @@
spin_lock(&sl811->lock);
/* leave active endpoints in the schedule */
- if (!list_empty(&ep->queue))
+ if (!list_empty(&ep->hep->urb_list))
return;
/* async deschedule? */
@@ -496,7 +489,6 @@
done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs)
{
u8 status;
- struct sl811h_req *req;
struct urb *urb;
int urbstat = -EINPROGRESS;
@@ -505,8 +497,7 @@
status = sl811_read(sl811, bank + SL11H_PKTSTATREG);
- req = container_of(ep->queue.next, struct sl811h_req, queue);
- urb = req->urb;
+ urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
/* we can safely ignore NAKs */
if (status & SL11H_STATMASK_NAK) {
@@ -577,7 +568,7 @@
urb->status = urbstat;
spin_unlock(&urb->lock);
- req = NULL;
+ urb = NULL;
ep->nextpid = USB_PID_ACK;
}
break;
@@ -618,9 +609,8 @@
bank, status, ep, urbstat);
}
- if ((urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)
- && req)
- finish_request(sl811, ep, req, regs, urbstat);
+ if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS))
+ finish_request(sl811, ep, urb, regs, urbstat);
}
static inline u8 checkdone(struct sl811 *sl811)
@@ -643,7 +633,7 @@
ctl = sl811_read(sl811, SL811_EP_B(SL11H_HOSTCTLREG));
if (ctl & SL11H_HCTLMASK_ARM)
sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
- DBG("%s DONE_B: ctrl %02x sts %02x\n", ctl,
+ DBG("%s DONE_B: ctrl %02x sts %02x\n",
(ctl & SL11H_HCTLMASK_ARM) ? "timeout" : "lost",
ctl,
sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
@@ -732,8 +722,8 @@
if (sl811->active_a) {
sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0);
finish_request(sl811, sl811->active_a,
- container_of(sl811->active_a->queue.next,
- struct sl811h_req, queue),
+ container_of(sl811->active_a->hep->urb_list.next,
+ struct urb, urb_list),
NULL, -ESHUTDOWN);
sl811->active_a = NULL;
}
@@ -741,8 +731,8 @@
if (sl811->active_b) {
sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
finish_request(sl811, sl811->active_b,
- container_of(sl811->active_b->queue.next,
- struct sl811h_req, queue),
+ container_of(sl811->active_b->hep->urb_list.next,
+ struct urb, urb_list),
NULL, -ESHUTDOWN);
sl811->active_b = NULL;
}
@@ -816,19 +806,18 @@
/*-------------------------------------------------------------------------*/
static int sl811h_urb_enqueue(
- struct usb_hcd *hcd,
- struct urb *urb,
- int mem_flags
+ struct usb_hcd *hcd,
+ struct usb_host_endpoint *hep,
+ struct urb *urb,
+ int mem_flags
) {
struct sl811 *sl811 = hcd_to_sl811(hcd);
struct usb_device *udev = urb->dev;
- struct hcd_dev *hdev = (struct hcd_dev *) udev->hcpriv;
unsigned int pipe = urb->pipe;
int is_out = !usb_pipein(pipe);
int type = usb_pipetype(pipe);
int epnum = usb_pipeendpoint(pipe);
struct sl811h_ep *ep = NULL;
- struct sl811h_req *req;
unsigned long flags;
int i;
int retval = 0;
@@ -838,16 +827,8 @@
return -ENOSPC;
#endif
- /* avoid all allocations within spinlocks: request or endpoint */
- urb->hcpriv = req = kmalloc(sizeof *req, mem_flags);
- if (!req)
- return -ENOMEM;
- req->urb = urb;
-
- i = epnum << 1;
- if (i && is_out)
- i |= 1;
- if (!hdev->ep[i])
+ /* avoid all allocations within spinlocks */
+ if (!hep->hcpriv)
ep = kcalloc(1, sizeof *ep, mem_flags);
spin_lock_irqsave(&sl811->lock, flags);
@@ -859,15 +840,14 @@
goto fail;
}
- if (hdev->ep[i]) {
+ if (hep->hcpriv) {
kfree(ep);
- ep = hdev->ep[i];
+ ep = hep->hcpriv;
} else if (!ep) {
retval = -ENOMEM;
goto fail;
} else {
- INIT_LIST_HEAD(&ep->queue);
INIT_LIST_HEAD(&ep->schedule);
ep->udev = usb_get_dev(udev);
ep->epnum = epnum;
@@ -911,7 +891,7 @@
break;
}
- hdev->ep[i] = ep;
+ hep->hcpriv = ep;
}
/* maybe put endpoint into schedule */
@@ -966,47 +946,38 @@
spin_lock(&urb->lock);
if (urb->status != -EINPROGRESS) {
spin_unlock(&urb->lock);
- finish_request(sl811, ep, req, NULL, 0);
- req = NULL;
+ finish_request(sl811, ep, urb, NULL, 0);
retval = 0;
goto fail;
}
- list_add_tail(&req->queue, &ep->queue);
+ urb->hcpriv = hep;
spin_unlock(&urb->lock);
start_transfer(sl811);
sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable);
fail:
spin_unlock_irqrestore(&sl811->lock, flags);
- if (retval)
- kfree(req);
return retval;
}
static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
{
struct sl811 *sl811 = hcd_to_sl811(hcd);
- struct usb_device *udev = urb->dev;
- struct hcd_dev *hdev = (struct hcd_dev *) udev->hcpriv;
- unsigned int pipe = urb->pipe;
- int is_out = !usb_pipein(pipe);
+ struct usb_host_endpoint *hep = urb->hcpriv;
unsigned long flags;
- unsigned i;
struct sl811h_ep *ep;
- struct sl811h_req *req = urb->hcpriv;
int retval = 0;
- i = usb_pipeendpoint(pipe) << 1;
- if (i && is_out)
- i |= 1;
+ if (!hep)
+ return -EINVAL;
spin_lock_irqsave(&sl811->lock, flags);
- ep = hdev->ep[i];
+ ep = hep->hcpriv;
if (ep) {
/* finish right away if this urb can't be active ...
* note that some drivers wrongly expect delays
*/
- if (ep->queue.next != &req->queue) {
+ if (ep->hep->urb_list.next != &urb->urb_list) {
/* not front of queue? never active */
/* for active transfers, we expect an IRQ */
@@ -1022,7 +993,7 @@
0);
sl811->active_a = NULL;
} else
- req = NULL;
+ urb = NULL;
#ifdef USE_B
} else if (sl811->active_b == ep) {
if (time_before_eq(sl811->jiffies_a, jiffies)) {
@@ -1036,14 +1007,14 @@
0);
sl811->active_b = NULL;
} else
- req = NULL;
+ urb = NULL;
#endif
} else {
/* front of queue for inactive endpoint */
}
- if (req)
- finish_request(sl811, ep, req, NULL, 0);
+ if (urb)
+ finish_request(sl811, ep, urb, NULL, 0);
else
VDBG("dequeue, urb %p active %s; wait4irq\n", urb,
(sl811->active_a == ep) ? "A" : "B");
@@ -1054,33 +1025,22 @@
}
static void
-sl811h_endpoint_disable(struct usb_hcd *hcd, struct hcd_dev *hdev, int epnum)
+sl811h_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
{
- struct sl811 *sl811 = hcd_to_sl811(hcd);
- struct sl811h_ep *ep;
- unsigned long flags;
- int i;
-
- i = (epnum & 0xf) << 1;
- if (epnum && !(epnum & USB_DIR_IN))
- i |= 1;
-
- spin_lock_irqsave(&sl811->lock, flags);
- ep = hdev->ep[i];
- hdev->ep[i] = NULL;
- spin_unlock_irqrestore(&sl811->lock, flags);
+ struct sl811h_ep *ep = hep->hcpriv;
- if (ep) {
- /* assume we'd just wait for the irq */
- if (!list_empty(&ep->queue))
- msleep(3);
- if (!list_empty(&ep->queue))
- WARN("ep %p not empty?\n", ep);
+ if (!ep)
+ return;
- usb_put_dev(ep->udev);
- kfree(ep);
- }
- return;
+ /* assume we'd just wait for the irq */
+ if (!list_empty(&hep->urb_list))
+ msleep(3);
+ if (!list_empty(&hep->urb_list))
+ WARN("ep %p not empty?\n", ep);
+
+ usb_put_dev(ep->udev);
+ kfree(ep);
+ hep->hcpriv = 0;
}
static int
@@ -1481,7 +1441,7 @@
sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
seq_printf(s, "\n");
list_for_each_entry (ep, &sl811->async, schedule) {
- struct sl811h_req *req;
+ struct urb *urb;
seq_printf(s, "%s%sqh%p, ep%d%s, maxpacket %d"
" nak %d err %d\n",
@@ -1497,10 +1457,10 @@
}; s;}),
ep->maxpacket,
ep->nak_count, ep->error_count);
- list_for_each_entry (req, &ep->queue, queue) {
- seq_printf(s, " urb%p, %d/%d\n", req->urb,
- req->urb->actual_length,
- req->urb->transfer_buffer_length);
+ list_for_each_entry (urb, &ep->hep->urb_list, urb_list) {
+ seq_printf(s, " urb%p, %d/%d\n", urb,
+ urb->actual_length,
+ urb->transfer_buffer_length);
}
}
if (!list_empty(&sl811->async))
@@ -1743,11 +1703,6 @@
sl811->hcd.self.op = &usb_hcd_operations;
sl811->hcd.self.hcpriv = sl811;
- // NOTE: 2.6.11 starts to change the hcd glue layer some more,
- // eventually letting us eliminate struct sl811h_req and a
- // lot of the boilerplate code here
-
- INIT_LIST_HEAD(&sl811->hcd.dev_list);
sl811->hcd.self.release = &usb_hcd_release;
sl811->hcd.description = sl811h_hc_driver.description;
diff -Nru a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h
--- a/drivers/usb/host/sl811.h 2005-01-07 15:47:03 -08:00
+++ b/drivers/usb/host/sl811.h 2005-01-07 15:47:03 -08:00
@@ -162,7 +162,7 @@
}
struct sl811h_ep {
- struct list_head queue;
+ struct usb_host_endpoint *hep;
struct usb_device *udev;
u8 defctrl;
@@ -182,14 +182,6 @@
/* async schedule */
struct list_head schedule;
-};
-
-struct sl811h_req {
- /* FIXME usbcore should maintain endpoints' urb queues
- * directly in 'struct usb_host_endpoint'
- */
- struct urb *urb;
- struct list_head queue;
};
/*-------------------------------------------------------------------------*/
ChangeSet 1.1938.446.15, 2004/12/15 16:32:41-08:00, [email protected]
[PATCH] USB: usbfs changes for usb_dev->ep[] (3/15)
Updates usbfs to stop using usb_epnum_to_ep_desc(). In the process,
it acquires better error detection on its urb submit path.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/devio.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c 2005-01-07 15:49:37 -08:00
+++ b/drivers/usb/core/devio.c 2005-01-07 15:49:37 -08:00
@@ -808,7 +808,7 @@
{
struct usbdevfs_urb uurb;
struct usbdevfs_iso_packet_desc *isopkt = NULL;
- struct usb_endpoint_descriptor *ep_desc;
+ struct usb_host_endpoint *ep;
struct async *as;
struct usb_ctrlrequest *dr = NULL;
unsigned int u, totlen, isofrmlen;
@@ -829,14 +829,17 @@
if ((ret = checkintf(ps, ifnum)))
return ret;
}
+ if ((uurb.endpoint & ~USB_ENDPOINT_DIR_MASK) != 0)
+ ep = ps->dev->ep_in [uurb.endpoint & USB_ENDPOINT_NUMBER_MASK];
+ else
+ ep = ps->dev->ep_out [uurb.endpoint & USB_ENDPOINT_NUMBER_MASK];
+ if (!ep)
+ return -ENOENT;
switch(uurb.type) {
case USBDEVFS_URB_TYPE_CONTROL:
- if ((uurb.endpoint & ~USB_ENDPOINT_DIR_MASK) != 0) {
- if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
- return -ENOENT;
- if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL)
- return -EINVAL;
- }
+ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ != USB_ENDPOINT_XFER_CONTROL)
+ return -EINVAL;
/* min 8 byte setup packet, max arbitrary */
if (uurb.buffer_length < 8 || uurb.buffer_length > PAGE_SIZE)
return -EINVAL;
@@ -865,6 +868,12 @@
break;
case USBDEVFS_URB_TYPE_BULK:
+ switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ case USB_ENDPOINT_XFER_ISOC:
+ return -EINVAL;
+ /* allow single-shot interrupt transfers, at bogus rates */
+ }
uurb.number_of_packets = 0;
if (uurb.buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL;
@@ -876,9 +885,10 @@
/* arbitrary limit */
if (uurb.number_of_packets < 1 || uurb.number_of_packets > 128)
return -EINVAL;
- if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
- return -ENOENT;
- interval = 1 << min (15, ep_desc->bInterval - 1);
+ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ != USB_ENDPOINT_XFER_ISOC)
+ return -EINVAL;
+ interval = 1 << min (15, ep->desc.bInterval - 1);
isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb.number_of_packets;
if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
return -ENOMEM;
@@ -902,12 +912,13 @@
case USBDEVFS_URB_TYPE_INTERRUPT:
uurb.number_of_packets = 0;
- if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
- return -ENOENT;
+ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ != USB_ENDPOINT_XFER_INT)
+ return -EINVAL;
if (ps->dev->speed == USB_SPEED_HIGH)
- interval = 1 << min (15, ep_desc->bInterval - 1);
+ interval = 1 << min (15, ep->desc.bInterval - 1);
else
- interval = ep_desc->bInterval;
+ interval = ep->desc.bInterval;
if (uurb.buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL;
if (!access_ok((uurb.endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length))
ChangeSet 1.1938.446.5, 2004/12/15 14:25:46-08:00, [email protected]
[PATCH] USB: SN9C10x driver updates
SN9C10x driver updates.
Changes: + new, - removed, * cleanup, @ bugfix, = sync with kernels
* SN9C10x system clock fine-tuning when switching from native to compressed
format and viceversa for each image sensor
+ Add sn9c102_i2c_try_raw_read()
+ Frame header available from sysfs interface
+ Documentation updates: new "Video frame formats" paragraph, new entries in
"Credits" and frame header description
+ Plugin's for HV7131D and MI-0343 image sensors
Signed-off-by: Luca Risolia <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/usb/sn9c102.txt | 202 ++++++++++++++----
drivers/usb/media/Makefile | 2
drivers/usb/media/sn9c102.h | 13 -
drivers/usb/media/sn9c102_core.c | 115 +++++++---
drivers/usb/media/sn9c102_hv7131d.c | 271 ++++++++++++++++++++++++
drivers/usb/media/sn9c102_mi0343.c | 363 +++++++++++++++++++++++++++++++++
drivers/usb/media/sn9c102_pas106b.c | 45 +---
drivers/usb/media/sn9c102_pas202bcb.c | 49 +---
drivers/usb/media/sn9c102_sensor.h | 62 ++++-
drivers/usb/media/sn9c102_tas5110c1b.c | 22 +-
drivers/usb/media/sn9c102_tas5130d1b.c | 22 +-
11 files changed, 1004 insertions(+), 162 deletions(-)
diff -Nru a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt
--- a/Documentation/usb/sn9c102.txt 2005-01-07 15:50:54 -08:00
+++ b/Documentation/usb/sn9c102.txt 2005-01-07 15:50:54 -08:00
@@ -11,16 +11,17 @@
1. Copyright
2. Disclaimer
3. License
-4. Overview
-5. Driver installation
+4. Overview and features
+5. Module dependencies
6. Module loading
7. Module parameters
8. Optional device control through "sysfs"
9. Supported devices
-10. How to add support for new image sensors
+10. How to add plug-in's for new image sensors
11. Notes for V4L2 application developers
-12. Contact information
-13. Credits
+12. Video frame formats
+13. Contact information
+14. Credits
1. Copyright
@@ -51,16 +52,18 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-4. Overview
-===========
+4. Overview and features
+========================
This driver attempts to support the video and audio streaming capabilities of
-the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 (or SUI-102) PC
-Camera Controllers.
+the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 PC Camera
+Controllers.
It's worth to note that SONiX has never collaborated with the author during the
development of this project, despite several requests for enough detailed
specifications of the register tables, compression engine and video data format
-of the above chips.
+of the above chips. Nevertheless, these informations are no longer necessary,
+becouse all the aspects related to these chips are known and have been
+described in detail in this documentation.
The driver relies on the Video4Linux2 and USB core modules. It has been
designed to run properly on SMP systems as well.
@@ -79,15 +82,16 @@
pixel area of image sensor;
- image downscaling with arbitrary scaling factors from 1, 2 and 4 in both
directions (see "Notes for V4L2 application developers" paragraph);
-- two different video formats for uncompressed or compressed data (see also
- "Notes for V4L2 application developers" paragraph);
+- two different video formats for uncompressed or compressed data in low or
+ high compression quality (see also "Notes for V4L2 application developers"
+ and "Video frame formats" paragraphs);
- full support for the capabilities of many of the possible image sensors that
can be connected to the SN9C10x bridges, including, for istance, red, green,
blue and global gain adjustments and exposure (see "Supported devices"
paragraph for details);
- use of default color settings for sunlight conditions;
-- dynamic I/O interface for both SN9C10x and image sensor control (see
- "Optional device control through 'sysfs'" paragraph);
+- dynamic I/O interface for both SN9C10x and image sensor control and
+ monitoring (see "Optional device control through 'sysfs'" paragraph);
- dynamic driver control thanks to various module parameters (see "Module
parameters" paragraph);
- up to 64 cameras can be handled at the same time; they can be connected and
@@ -177,7 +181,7 @@
-------------------------------------------------------------------------------
-8. Optional device control through "sysfs"
+8. Optional device control through "sysfs" [1]
==========================================
It is possible to read and write both the SN9C10x and the image sensor
registers by using the "sysfs" filesystem interface.
@@ -195,9 +199,9 @@
SN9C10x bridge, while the other two control the sensor chip. "reg" and
"i2c_reg" hold the values of the current register index where the following
reading/writing operations are addressed at through "val" and "i2c_val". Their
-use is not intended for end-users, unless you know what you are doing. Note
-that "i2c_reg" and "i2c_val" won't be created if the sensor does not actually
-support the standard I2C protocol. Also, remember that you must be logged in as
+use is not intended for end-users. Note that "i2c_reg" and "i2c_val" won't be
+created if the sensor does not actually support the standard I2C protocol or
+its registers are not 8-bit long. Also, remember that you must be logged in as
root before writing to them.
As an example, suppose we were to want to read the value contained in the
@@ -216,7 +220,48 @@
[root@localhost #] echo 2 > val
Note that the SN9C10x always returns 0 when some of its registers are read.
-To avoid race conditions, all the I/O accesses to the files are serialized.
+To avoid race conditions, all the I/O accesses to the above files are
+serialized.
+
+The sysfs interface also provides the "frame_header" entry, which exports the
+frame header of the most recent requested and captured video frame. The header
+is 12-bytes long and is appended to every video frame by the SN9C10x
+controllers. As an example, this additional information can be used by the user
+application for implementing auto-exposure features via software.
+
+The following table describes the frame header:
+
+Byte # Value Description
+------ ----- -----------
+0x00 0xFF Frame synchronisation pattern.
+0x01 0xFF Frame synchronisation pattern.
+0x02 0x00 Frame synchronisation pattern.
+0x03 0xC4 Frame synchronisation pattern.
+0x04 0xC4 Frame synchronisation pattern.
+0x05 0x96 Frame synchronisation pattern.
+0x06 0x00 or 0x01 Unknown meaning. The exact value depends on the chip.
+0x07 0xXX Variable value, whose bits are ff00uzzc, where ff is a
+ frame counter, u is unknown, zz is a size indicator
+ (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for
+ "compression enabled" (1 = yes, 0 = no).
+0x08 0xXX Brightness sum inside Auto-Exposure area (low-byte).
+0x09 0xXX Brightness sum inside Auto-Exposure area (high-byte).
+ For a pure white image, this number will be equal to 500
+ times the area of the specified AE area. For images
+ that are not pure white, the value scales down according
+ to relative whiteness.
+0x0A 0xXX Brightness sum outside Auto-Exposure area (low-byte).
+0x0B 0xXX Brightness sum outside Auto-Exposure area (high-byte).
+ For a pure white image, this number will be equal to 125
+ times the area outside of the specified AE area. For
+ images that are not pure white, the value scales down
+ according to relative whiteness.
+
+The AE area (sx, sy, ex, ey) in the active window can be set by programming the
+registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit
+corresponds to 32 pixels.
+
+[1] The frame header has been documented by Bertrik Sikken.
9. Supported devices
@@ -275,8 +320,10 @@
Model Manufacturer
----- ------------
-PAS106B PixArt Imaging Inc.
-PAS202BCB PixArt Imaging Inc.
+HV7131D Hynix Semiconductor, Inc.
+MI-0343 Micron Technology, Inc.
+PAS106B PixArt Imaging, Inc.
+PAS202BCB PixArt Imaging, Inc.
TAS5110C1B Taiwan Advanced Sensor Corporation
TAS5130D1B Taiwan Advanced Sensor Corporation
@@ -295,15 +342,15 @@
driver.
-10. How to add support for new image sensors
-============================================
-It should be easy to write code for new sensors by using the small API that I
-have created for this purpose, which is present in "sn9c102_sensor.h"
+10. How to add plug-in's for new image sensors
+==============================================
+It should be easy to write plug-in's for new sensors by using the small API
+that has been created for this purpose, which is present in "sn9c102_sensor.h"
(documentation is included there). As an example, have a look at the code in
"sn9c102_pas106b.c", which uses the mentioned interface.
-At the moment, possible unsupported image sensors are: HV7131x series (VGA),
-MI03x series (VGA), OV7620 (VGA), OV7630 (VGA), CIS-VF10 (VGA).
+At the moment, possible unsupported image sensors are: CIS-VF10 (VGA),
+OV7620 (VGA), OV7630 (VGA).
11. Notes for V4L2 application developers
@@ -332,29 +379,98 @@
This driver supports two different video formats: the first one is the "8-bit
Sequential Bayer" format and can be used to obtain uncompressed video data
from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without the initial and final frame headers). The
-compression quality may vary from 0 to 1 and can be selected or queried thanks
-to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum
-flexibility, the default active video format depends on how the image sensor
-being used is initialized (as described in the documentation of the API for the
-image sensors supplied by this driver).
+"raw" compressed video data (without frame headers not related to the
+compressed data). The compression quality may vary from 0 to 1 and can be
+selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
+ioctl's. For maximum flexibility, both the default active video format and the
+default compression quality depend on how the image sensor being used is
+initialized (as described in the documentation of the API for the image sensors
+supplied by this driver).
-12. Contact information
+12. Video frame formats [1]
=======================
-I may be contacted by e-mail at <[email protected]>.
+The SN9C10x PC Camera Controllers can send images in two possible video
+formats over the USB: either native "Sequential RGB Bayer" or Huffman
+compressed. The latter is used to achieve high frame rates. The current video
+format may be selected or queried from the user application by calling the
+VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2 API
+specifications.
+
+The name "Sequential Bayer" indicates the organization of the red, green and
+blue pixels in one video frame. Each pixel is associated with a 8-bit long
+value and is disposed in memory according to the pattern shown below:
+
+B[0] G[1] B[2] G[3] ... B[m-2] G[m-1]
+G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1]
+...
+... B[(n-1)(m-2)] G[(n-1)(m-1)]
+... G[n(m-2)] R[n(m-1)]
+
+The above matrix also represents the sequential or progressive read-out mode of
+the (n, m) Bayer color filter array used in many CCD/CMOS image sensors.
+
+One compressed video frame consists of a bitstream that encodes for every R, G,
+or B pixel the difference between the value of the pixel itself and some
+reference pixel value. Pixels are organised in the Bayer pattern and the Bayer
+sub-pixels are tracked individually and alternatingly. For example, in the
+first line values for the B and G1 pixels are alternatingly encoded, while in
+the second line values for the G2 and R pixels are alternatingly encoded.
+
+The pixel reference value is calculated as follows:
+- the 4 top left pixels are encoded in raw uncompressed 8-bit format;
+- the value in the top two rows is the value of the pixel left of the current
+ pixel;
+- the value in the left column is the value of the pixel above the current
+ pixel;
+- for all other pixels, the reference value is the average of the value of the
+ pixel on the left and the value of the pixel above the current pixel;
+- there is one code in the bitstream that specifies the value of a pixel
+ directly (in 4-bit resolution);
+- pixel values need to be clamped inside the range [0..255] for proper
+ decoding.
+
+The algorithm purely describes the conversion from compressed Bayer code used
+in the SN9C10x chips to uncompressed Bayer. Additional steps are required to
+convert this to a color image (i.e. a color interpolation algorithm).
+
+The following Huffman codes have been found:
+0: +0 (relative to reference pixel value)
+100: +4
+101: -4?
+1110xxxx: set absolute value to xxxx.0000
+1101: +11
+1111: -11
+11001: +20
+110000: -20
+110001: ??? - these codes are apparently not used
-I can accept GPG/PGP encrypted e-mail. My GPG key ID is 'FCE635A4'.
-My public 1024-bit key should be available at any keyserver; the fingerprint
-is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
+[1] The Huffman compression algorithm has been reverse-engineered and
+ documented by Bertrik Sikken.
+
+
+13. Contact information
+=======================
+The author may be contacted by e-mail at <[email protected]>.
+GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
+'FCE635A4'; the public 1024-bit key should be available at any keyserver;
+the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
-13. Credits
+
+14. Credits
===========
-I would thank the following persons:
+Many thanks to following persons for their contribute (listed in alphabetical
+order):
-- Stefano Mozzi, who donated 45 EU;
- Luca Capello for the donation of a webcam;
-- Mizuno Takafumi for the donation of a webcam;
+- Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the
+ donation of a webcam;
- Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB
- image sensor.
+ image sensor;
+- Stefano Mozzi, who donated 45 EU;
+- Bertrik Sikken, who reverse-engineered and documented the Huffman compression
+ algorithm used in the SN9C10x controllers and implemented the first decoder;
+- Mizuno Takafumi for the donation of a webcam;
+- An "anonymous" donator (who didn't want his name to be revealed) for the
+ donation of a webcam.
diff -Nru a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
--- a/drivers/usb/media/Makefile 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/Makefile 2005-01-07 15:50:54 -08:00
@@ -2,7 +2,7 @@
# Makefile for USB Media drivers
#
-sn9c102-objs := sn9c102_core.o sn9c102_pas106b.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o sn9c102_pas202bcb.o
+sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
obj-$(CONFIG_USB_DABUSB) += dabusb.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
diff -Nru a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
--- a/drivers/usb/media/sn9c102.h 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102.h 2005-01-07 15:50:54 -08:00
@@ -46,8 +46,8 @@
#define SN9C102_URBS 2
#define SN9C102_ISO_PACKETS 7
#define SN9C102_ALTERNATE_SETTING 8
-#define SN9C102_URB_TIMEOUT msecs_to_jiffies(3)
-#define SN9C102_CTRL_TIMEOUT msecs_to_jiffies(100)
+#define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
+#define SN9C102_CTRL_TIMEOUT msecs_to_jiffies(300)
/*****************************************************************************/
@@ -55,8 +55,8 @@
#define SN9C102_MODULE_AUTHOR "(C) 2004 Luca Risolia"
#define SN9C102_AUTHOR_EMAIL "<[email protected]>"
#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.19"
-#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 19)
+#define SN9C102_MODULE_VERSION "1:1.20"
+#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 20)
enum sn9c102_bridge {
BRIDGE_SN9C101 = 0x01,
@@ -101,8 +101,12 @@
STREAM_ON,
};
+typedef char sn9c102_sof_header_t[12];
+typedef char sn9c102_eof_header_t[4];
+
struct sn9c102_sysfs_attr {
u8 reg, i2c_reg;
+ sn9c102_sof_header_t frame_header;
};
static DECLARE_MUTEX(sn9c102_sysfs_lock);
@@ -131,6 +135,7 @@
struct v4l2_jpegcompression compression;
struct sn9c102_sysfs_attr sysfs;
+ sn9c102_sof_header_t sof_header;
u16 reg[32];
enum sn9c102_dev_state state;
diff -Nru a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
--- a/drivers/usb/media/sn9c102_core.c 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102_core.c 2005-01-07 15:50:54 -08:00
@@ -82,9 +82,6 @@
/*****************************************************************************/
-typedef char sn9c102_sof_header_t[12];
-typedef char sn9c102_eof_header_t[4];
-
static sn9c102_sof_header_t sn9c102_sof_header[] = {
{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x00},
{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
@@ -277,9 +274,9 @@
if (r & 0x04)
return 0;
if (sensor->frequency & SN9C102_I2C_400KHZ)
- udelay(5*8);
+ udelay(5*16);
else
- udelay(16*8);
+ udelay(16*16);
}
return -EBUSY;
}
@@ -306,18 +303,19 @@
int
-sn9c102_i2c_try_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address)
+sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
+ struct sn9c102_sensor* sensor, u8 data0, u8 data1,
+ u8 n, u8 buffer[])
{
struct usb_device* udev = cam->usbdev;
u8* data = cam->control_buffer;
int err = 0, res;
- /* Write cycle - address */
+ /* Write cycle */
data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
- data[1] = sensor->slave_write_id;
- data[2] = address;
+ data[1] = data0; /* I2C slave id */
+ data[2] = data1; /* address */
data[7] = 0x10;
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
@@ -326,11 +324,11 @@
err += sn9c102_i2c_wait(cam, sensor);
- /* Read cycle - 1 byte */
+ /* Read cycle - n bytes */
data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
- 0x10 | 0x02;
- data[1] = sensor->slave_read_id;
+ (n << 4) | 0x02;
+ data[1] = data0;
data[7] = 0x10;
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
@@ -339,7 +337,7 @@
err += sn9c102_i2c_wait(cam, sensor);
- /* The read byte will be placed in data[4] */
+ /* The first read byte will be placed in data[4] */
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
if (res < 0)
@@ -347,12 +345,18 @@
err += sn9c102_i2c_detect_read_error(cam, sensor);
- if (err)
+ PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
+ data[4])
+
+ if (err) {
DBG(3, "I2C read failed for %s image sensor", sensor->name)
+ return -1;
+ }
- PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[4])
+ if (buffer)
+ memcpy(buffer, data, sizeof(buffer));
- return err ? -1 : (int)data[4];
+ return (int)data[4];
}
@@ -395,12 +399,21 @@
}
+int
+sn9c102_i2c_try_read(struct sn9c102_device* cam,
+ struct sn9c102_sensor* sensor, u8 address)
+{
+ return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
+ address, 1, NULL);
+}
+
+
int
sn9c102_i2c_try_write(struct sn9c102_device* cam,
struct sn9c102_sensor* sensor, u8 address, u8 value)
{
return sn9c102_i2c_try_raw_write(cam, sensor, 3,
- sensor->slave_write_id, address,
+ sensor->i2c_slave_id, address,
value, 0, 0, 0);
}
@@ -433,9 +446,11 @@
for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
for (j = 0; j < n; j++)
/* It's enough to compare 7 bytes */
- if (!memcmp(mem + i, sn9c102_sof_header[j], 7))
- /* Skips the header */
+ if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) {
+ memcpy(cam->sof_header, mem + i, soflen);
+ /* Skip the header */
return mem + i + soflen;
+ }
return NULL;
}
@@ -563,6 +578,9 @@
(*f) = NULL;
spin_unlock_irqrestore(&cam->queue_lock
, lock_flags);
+ memcpy(cam->sysfs.frame_header,
+ cam->sof_header,
+ sizeof(sn9c102_sof_header_t));
DBG(3, "Video frame captured: "
"%lu bytes", (unsigned long)(b))
@@ -746,15 +764,14 @@
(cam->stream == STREAM_OFF) ||
(cam->state & DEV_DISCONNECTED),
SN9C102_URB_TIMEOUT);
- if (err) {
+ if (cam->state & DEV_DISCONNECTED)
+ return -ENODEV;
+ else if (err) {
cam->state |= DEV_MISCONFIGURED;
- DBG(1, "The camera is misconfigured. To use "
- "it, close and open /dev/video%d "
- "again.", cam->v4ldev->minor)
+ DBG(1, "The camera is misconfigured. To use it, close and "
+ "open /dev/video%d again.", cam->v4ldev->minor)
return err;
}
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
return 0;
}
@@ -894,6 +911,11 @@
return -ENODEV;
}
+ if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
+ up(&sn9c102_sysfs_lock);
+ return -ENOSYS;
+ }
+
value = sn9c102_strtou8(buf, len, &count);
if (!count) {
up(&sn9c102_sysfs_lock);
@@ -937,7 +959,7 @@
up(&sn9c102_sysfs_lock);
return count;
-}
+}
static ssize_t
@@ -988,7 +1010,7 @@
return -ENODEV;
}
- if (cam->sensor->slave_read_id == SN9C102_I2C_SLAVEID_UNAVAILABLE) {
+ if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
up(&sn9c102_sysfs_lock);
return -ENOSYS;
}
@@ -1129,6 +1151,24 @@
}
+static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
+{
+ struct sn9c102_device* cam;
+ ssize_t count;
+
+ cam = video_get_drvdata(to_video_device(cd));
+ if (!cam)
+ return -ENODEV;
+
+ count = sizeof(cam->sysfs.frame_header);
+ memcpy(buf, cam->sysfs.frame_header, count);
+
+ DBG(3, "Frame header, read bytes: %zd", count)
+
+ return count;
+}
+
+
static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
sn9c102_show_reg, sn9c102_store_reg);
static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
@@ -1140,6 +1180,8 @@
static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
+static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
+ sn9c102_show_frame_header, NULL);
static void sn9c102_create_sysfs(struct sn9c102_device* cam)
@@ -1148,14 +1190,14 @@
video_device_create_file(v4ldev, &class_device_attr_reg);
video_device_create_file(v4ldev, &class_device_attr_val);
+ video_device_create_file(v4ldev, &class_device_attr_frame_header);
if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
video_device_create_file(v4ldev, &class_device_attr_green);
else if (cam->bridge == BRIDGE_SN9C103) {
video_device_create_file(v4ldev, &class_device_attr_blue);
video_device_create_file(v4ldev, &class_device_attr_red);
}
- if (cam->sensor->slave_write_id != SN9C102_I2C_SLAVEID_UNAVAILABLE ||
- cam->sensor->slave_read_id != SN9C102_I2C_SLAVEID_UNAVAILABLE) {
+ if (cam->sensor->sysfs_ops) {
video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
video_device_create_file(v4ldev, &class_device_attr_i2c_val);
}
@@ -1164,11 +1206,11 @@
/*****************************************************************************/
static int
-sn9c102_set_format(struct sn9c102_device* cam, struct v4l2_pix_format* fmt)
+sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
{
int err = 0;
- if (fmt->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80, 0x18);
else
err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f, 0x18);
@@ -1273,7 +1315,9 @@
cam->compression.quality = cam->reg[0x17] & 0x01 ? 0 : 1;
else
err += sn9c102_set_compression(cam, &cam->compression);
- err += sn9c102_set_format(cam, &s->pix_format);
+ err += sn9c102_set_pix_format(cam, &s->pix_format);
+ if (s->set_pix_format)
+ err += s->set_pix_format(cam, &s->pix_format);
if (err)
return err;
@@ -2077,8 +2121,10 @@
sn9c102_release_buffers(cam);
- err += sn9c102_set_format(cam, pix);
+ err += sn9c102_set_pix_format(cam, pix);
err += sn9c102_set_crop(cam, &rect);
+ if (s->set_pix_format)
+ err += s->set_pix_format(cam, pix);
if (s->set_crop)
err += s->set_crop(cam, &rect);
err += sn9c102_set_scale(cam, scale);
@@ -2551,6 +2597,7 @@
DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor)
sn9c102_create_sysfs(cam);
+ DBG(2, "Optional device control through 'sysfs' interface ready")
usb_set_intfdata(intf, cam);
diff -Nru a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/media/sn9c102_hv7131d.c 2005-01-07 15:50:54 -08:00
@@ -0,0 +1,271 @@
+/***************************************************************************
+ * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2004 by Luca Risolia <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static struct sn9c102_sensor hv7131d;
+
+
+static int hv7131d_init(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ err += sn9c102_write_reg(cam, 0x00, 0x10);
+ err += sn9c102_write_reg(cam, 0x00, 0x11);
+ err += sn9c102_write_reg(cam, 0x00, 0x14);
+ err += sn9c102_write_reg(cam, 0x60, 0x17);
+ err += sn9c102_write_reg(cam, 0x0e, 0x18);
+ err += sn9c102_write_reg(cam, 0xf2, 0x19);
+
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ err += sn9c102_i2c_write(cam, 0x02, 0x00);
+ err += sn9c102_i2c_write(cam, 0x28, 0x00);
+
+ return err;
+}
+
+
+static int hv7131d_get_ctrl(struct sn9c102_device* cam,
+ struct v4l2_control* ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ {
+ int r1 = sn9c102_i2c_read(cam, 0x26),
+ r2 = sn9c102_i2c_read(cam, 0x27);
+ if (r1 < 0 || r2 < 0)
+ return -EIO;
+ ctrl->value = (r1 << 8) | (r2 & 0xff);
+ }
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
+ return -EIO;
+ ctrl->value = 0x3f - (ctrl->value & 0x3f);
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
+ return -EIO;
+ ctrl->value = 0x3f - (ctrl->value & 0x3f);
+ return 0;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
+ return -EIO;
+ ctrl->value = 0x3f - (ctrl->value & 0x3f);
+ return 0;
+ case SN9C102_V4L2_CID_RESET_LEVEL:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
+ return -EIO;
+ ctrl->value &= 0x3f;
+ return 0;
+ case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x34)) < 0)
+ return -EIO;
+ ctrl->value &= 0x07;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+
+static int hv7131d_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ err += sn9c102_i2c_write(cam, 0x26, ctrl->value >> 8);
+ err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_RESET_LEVEL:
+ err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
+ err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int hv7131d_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = &hv7131d;
+ int err = 0;
+ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
+ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int hv7131d_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x42, 0x19);
+ else
+ err += sn9c102_write_reg(cam, 0xf2, 0x19);
+
+ return err;
+}
+
+
+static struct sn9c102_sensor hv7131d = {
+ .name = "HV7131D",
+ .maintainer = "Luca Risolia <[email protected]>",
+ .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x11,
+ .init = &hv7131d_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x0250,
+ .maximum = 0xffff,
+ .step = 0x0001,
+ .default_value = 0x0250,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x20,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x1e,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_RESET_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "reset level",
+ .minimum = 0x19,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x30,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "pixel bias voltage",
+ .minimum = 0x00,
+ .maximum = 0x07,
+ .step = 0x01,
+ .default_value = 0x02,
+ .flags = 0,
+ },
+ },
+ .get_ctrl = &hv7131d_get_ctrl,
+ .set_ctrl = &hv7131d_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &hv7131d_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &hv7131d_set_pix_format
+};
+
+
+int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
+{
+ int r0 = 0, r1 = 0, err = 0;
+
+ err += sn9c102_write_reg(cam, 0x01, 0x01);
+ err += sn9c102_write_reg(cam, 0x00, 0x01);
+ err += sn9c102_write_reg(cam, 0x28, 0x17);
+ if (err)
+ return -EIO;
+
+ r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
+ r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
+ if (r0 < 0 || r1 < 0)
+ return -EIO;
+
+ if (r0 != 0x00 && r1 != 0x04)
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &hv7131d);
+
+ return 0;
+}
diff -Nru a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/media/sn9c102_mi0343.c 2005-01-07 15:50:54 -08:00
@@ -0,0 +1,363 @@
+/***************************************************************************
+ * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2004 by Luca Risolia <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static struct sn9c102_sensor mi0343;
+static u8 mi0343_i2c_data[5+1];
+
+
+static int mi0343_init(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ err += sn9c102_write_reg(cam, 0x00, 0x10);
+ err += sn9c102_write_reg(cam, 0x00, 0x11);
+ err += sn9c102_write_reg(cam, 0x0a, 0x14);
+ err += sn9c102_write_reg(cam, 0x40, 0x01);
+ err += sn9c102_write_reg(cam, 0x20, 0x17);
+ err += sn9c102_write_reg(cam, 0x07, 0x18);
+ err += sn9c102_write_reg(cam, 0xa0, 0x19);
+
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x0d, 0x00, 0x01, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x0d, 0x00, 0x00, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x03, 0x01, 0xe1, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x04, 0x02, 0x81, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x05, 0x00, 0x17, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x06, 0x00, 0x11, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+ 0x62, 0x04, 0x9a, 0, 0);
+
+ return err;
+}
+
+
+static int mi0343_get_ctrl(struct sn9c102_device* cam,
+ struct v4l2_control* ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x09, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ ctrl->value = mi0343_i2c_data[2];
+ return 0;
+ case V4L2_CID_GAIN:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x35, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ break;
+ case V4L2_CID_HFLIP:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x20, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0;
+ return 0;
+ case V4L2_CID_VFLIP:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x20, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0;
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x2d, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x2c, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+ 0x2e, 2+1, mi0343_i2c_data) < 0)
+ return -EIO;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ case V4L2_CID_RED_BALANCE:
+ case V4L2_CID_BLUE_BALANCE:
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8);
+ if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
+ ctrl->value -= 0x10;
+ else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
+ ctrl->value -= 0x60;
+ else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
+ ctrl->value -= 0xe0;
+ }
+
+ return 0;
+}
+
+
+static int mi0343_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ u16 reg = 0;
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ case V4L2_CID_RED_BALANCE:
+ case V4L2_CID_BLUE_BALANCE:
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if (ctrl->value <= (0x3f-0x10))
+ reg = 0x10 + ctrl->value;
+ else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
+ reg = 0x60 + (ctrl->value - (0x3f-0x10));
+ else
+ reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
+ break;
+ }
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x09, ctrl->value, 0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_GAIN:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x35, reg >> 8, reg & 0xff,
+ 0, 0);
+ break;
+ case V4L2_CID_HFLIP:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x20, ctrl->value ? 0x40:0x00,
+ ctrl->value ? 0x20:0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_VFLIP:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x20, ctrl->value ? 0x80:0x00,
+ ctrl->value ? 0x80:0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x2d, reg >> 8, reg & 0xff,
+ 0, 0);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x2c, reg >> 8, reg & 0xff,
+ 0, 0);
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x2b, reg >> 8, reg & 0xff,
+ 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x2e, reg >> 8, reg & 0xff,
+ 0, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int mi0343_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = &mi0343;
+ int err = 0;
+ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
+ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int mi0343_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x0a, 0x00, 0x03, 0, 0);
+ err += sn9c102_write_reg(cam, 0x20, 0x19);
+ } else {
+ err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+ mi0343.i2c_slave_id,
+ 0x0a, 0x00, 0x05, 0, 0);
+ err += sn9c102_write_reg(cam, 0xa0, 0x19);
+ }
+
+ return err;
+}
+
+
+static struct sn9c102_sensor mi0343 = {
+ .name = "MI-0343",
+ .maintainer = "Luca Risolia <[email protected]>",
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x5d,
+ .init = &mi0343_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0x0f,
+ .step = 0x01,
+ .default_value = 0x06,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "global gain",
+ .minimum = 0x00,
+ .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ },
+ .get_ctrl = &mi0343_get_ctrl,
+ .set_ctrl = &mi0343_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &mi0343_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &mi0343_set_pix_format
+};
+
+
+int sn9c102_probe_mi0343(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ err += sn9c102_write_reg(cam, 0x01, 0x01);
+ err += sn9c102_write_reg(cam, 0x00, 0x01);
+ err += sn9c102_write_reg(cam, 0x28, 0x17);
+ if (err)
+ return -EIO;
+
+ if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
+ 2, mi0343_i2c_data) < 0)
+ return -EIO;
+
+ if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3)
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &mi0343);
+
+ return 0;
+}
diff -Nru a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
--- a/drivers/usb/media/sn9c102_pas106b.c 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102_pas106b.c 2005-01-07 15:50:54 -08:00
@@ -96,11 +96,6 @@
return -EIO;
ctrl->value &= 0xf8;
return 0;
- case SN9C102_V4L2_CID_DAC_SIGN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x07)) < 0)
- return -EIO;
- ctrl->value &= 0x01;
- return 0;
default:
return -EINVAL;
}
@@ -136,13 +131,6 @@
case SN9C102_V4L2_CID_DAC_MAGNITUDE:
err += sn9c102_i2c_write(cam, 0x08, ctrl->value << 3);
break;
- case SN9C102_V4L2_CID_DAC_SIGN:
- {
- int r;
- err += (r = sn9c102_i2c_read(cam, 0x07)) < 0 ? r : 0;
- err += sn9c102_i2c_write(cam, 0x07, r | ctrl->value);
- }
- break;
default:
return -EINVAL;
}
@@ -167,13 +155,27 @@
}
+static int pas106b_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x2c, 0x17);
+ else
+ err += sn9c102_write_reg(cam, 0x20, 0x17);
+
+ return err;
+}
+
+
static struct sn9c102_sensor pas106b = {
.name = "PAS106B",
.maintainer = "Luca Risolia <[email protected]>",
+ .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
- .slave_read_id = 0x40,
- .slave_write_id = 0x40,
+ .i2c_slave_id = 0x40,
.init = &pas106b_init,
.qctrl = {
{
@@ -182,7 +184,7 @@
.name = "exposure",
.minimum = 0x125,
.maximum = 0xfff,
- .step = 0x01,
+ .step = 0x001,
.default_value = 0x140,
.flags = 0,
},
@@ -246,16 +248,6 @@
.default_value = 0x01,
.flags = 0,
},
- {
- .id = SN9C102_V4L2_CID_DAC_SIGN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "DAC sign",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
},
.get_ctrl = &pas106b_get_ctrl,
.set_ctrl = &pas106b_set_ctrl,
@@ -279,7 +271,8 @@
.height = 288,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.priv = 8, /* we use this field as 'bits per pixel' */
- }
+ },
+ .set_pix_format = &pas106b_set_pix_format
};
diff -Nru a/drivers/usb/media/sn9c102_pas202bcb.c b/drivers/usb/media/sn9c102_pas202bcb.c
--- a/drivers/usb/media/sn9c102_pas202bcb.c 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102_pas202bcb.c 2005-01-07 15:50:54 -08:00
@@ -6,7 +6,7 @@
* <[email protected]> *
* http://cadu.homelinux.com:8080/ *
* *
- * DAC Magnitude, DAC sign, exposure and green gain controls added by *
+ * DAC Magnitude, exposure and green gain controls added by *
* Luca Risolia <[email protected]> *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -95,17 +95,26 @@
if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
return -EIO;
return 0;
- case SN9C102_V4L2_CID_DAC_SIGN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0b)) < 0)
- return -EIO;
- ctrl->value &= 0x01;
- return 0;
default:
return -EINVAL;
}
}
+static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x24, 0x17);
+ else
+ err += sn9c102_write_reg(cam, 0x20, 0x17);
+
+ return err;
+}
+
+
static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
const struct v4l2_control* ctrl)
{
@@ -131,13 +140,6 @@
case SN9C102_V4L2_CID_DAC_MAGNITUDE:
err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
break;
- case SN9C102_V4L2_CID_DAC_SIGN:
- {
- int r;
- err += (r = sn9c102_i2c_read(cam, 0x0b)) < 0 ? r : 0;
- err += sn9c102_i2c_write(cam, 0x0b, r | ctrl->value);
- }
- break;
default:
return -EINVAL;
}
@@ -166,10 +168,10 @@
.name = "PAS202BCB",
.maintainer = "Carlos Eduardo Medaglia Dyonisio "
"<[email protected]>",
+ .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
- .slave_read_id = 0x40,
- .slave_write_id = 0x40,
+ .i2c_slave_id = 0x40,
.init = &pas202bcb_init,
.qctrl = {
{
@@ -178,7 +180,7 @@
.name = "exposure",
.minimum = 0x01e5,
.maximum = 0x3fff,
- .step = 0x01,
+ .step = 0x0001,
.default_value = 0x01e5,
.flags = 0,
},
@@ -232,16 +234,6 @@
.default_value = 0x04,
.flags = 0,
},
- {
- .id = SN9C102_V4L2_CID_DAC_SIGN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "DAC sign",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
},
.get_ctrl = &pas202bcb_get_ctrl,
.set_ctrl = &pas202bcb_set_ctrl,
@@ -265,7 +257,8 @@
.height = 480,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.priv = 8,
- }
+ },
+ .set_pix_format = &pas202bcb_set_pix_format
};
@@ -286,7 +279,7 @@
r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
-
+
if (r0 < 0 || r1 < 0)
return -EIO;
diff -Nru a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
--- a/drivers/usb/media/sn9c102_sensor.h 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102_sensor.h 2005-01-07 15:50:54 -08:00
@@ -62,6 +62,8 @@
ahead.
Functions must return 0 on success, the appropriate error otherwise.
*/
+extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
+extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
@@ -74,8 +76,10 @@
*/
#define SN9C102_SENSOR_TABLE \
static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \
+ &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ \
&sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \
&sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \
+ &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \
&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \
&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \
NULL, \
@@ -97,7 +101,7 @@
{ USB_DEVICE(0x0c45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */ \
{ USB_DEVICE(0x0c45, 0x6028), }, /* PAS202BCB */ \
{ USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \
- { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131[D|E1] */ \
+ { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \
{ USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \
{ USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */ \
{ USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \
@@ -147,15 +151,23 @@
u8 address);
/*
- This must be used if and only if the sensor doesn't implement the standard
- I2C protocol. There a number of good reasons why you must use the
- single-byte versions of this function: do not abuse. It writes n bytes,
- from data0 to datan, (registers 0x09 - 0x09+n of SN9C10X chip).
+ These must be used if and only if the sensor doesn't implement the standard
+ I2C protocol. There are a number of good reasons why you must use the
+ single-byte versions of these functions: do not abuse. The first function
+ writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C10X
+ chip. The second one programs the registers 0x09 and 0x10 with data0 and
+ data1, and places the n bytes read from the sensor register table in the
+ buffer pointed by 'buffer'. Both the functions return -1 on error; the write
+ version returns 0 on success, while the read version returns the first read
+ byte.
*/
extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
struct sn9c102_sensor* sensor, u8 n,
u8 data0, u8 data1, u8 data2, u8 data3,
u8 data4, u8 data5);
+extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
+ struct sn9c102_sensor* sensor, u8 data0,
+ u8 data1, u8 n, u8 buffer[]);
/* To be used after the sensor struct has been attached to the camera struct */
extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
@@ -166,16 +178,21 @@
extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
/*
- NOTE: there are no debugging functions here. To uniform the output you must
- use the dev_info()/dev_warn()/dev_err() macros defined in device.h, already
- included here, the argument being the struct device 'dev' of the sensor
- structure. Do NOT use these macros before the sensor is attached or the
- kernel will crash! However you should not need to notify the user about
+ NOTE: there are no exported debugging functions. To uniform the output you
+ must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
+ already included here, the argument being the struct device 'dev' of the
+ sensor structure. Do NOT use these macros before the sensor is attached or
+ the kernel will crash! However, you should not need to notify the user about
common errors or other messages, since this is done by the master module.
*/
/*****************************************************************************/
+enum sn9c102_i2c_sysfs_ops {
+ SN9C102_I2C_READ = 0x01,
+ SN9C102_I2C_WRITE = 0x02,
+};
+
enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
SN9C102_I2C_100KHZ = 0x01,
SN9C102_I2C_400KHZ = 0x02,
@@ -186,13 +203,13 @@
SN9C102_I2C_3WIRES,
};
-#define SN9C102_I2C_SLAVEID_FICTITIOUS 0xff
-#define SN9C102_I2C_SLAVEID_UNAVAILABLE 0x00
-
struct sn9c102_sensor {
char name[32], /* sensor name */
maintainer[64]; /* name of the mantainer <email> */
+ /* Supported operations through the 'sysfs' interface */
+ enum sn9c102_i2c_sysfs_ops sysfs_ops;
+
/*
These sensor capabilities must be provided if the SN9C10X controller
needs to communicate through the sensor serial interface by using
@@ -202,10 +219,10 @@
enum sn9c102_i2c_interface interface;
/*
- These identifiers must be provided if the image sensor implements
+ This identifier must be provided if the image sensor implements
the standard I2C protocol.
*/
- u8 slave_read_id, slave_write_id; /* reg. 0x09 */
+ u8 i2c_slave_id; /* reg. 0x09 */
/*
NOTE: Where not noted,most of the functions below are not mandatory.
@@ -215,7 +232,7 @@
int (*init)(struct sn9c102_device* cam);
/*
- This function is called after the sensor has been attached.
+ This function will be called after the sensor has been attached.
It should be used to initialize the sensor only, but may also
configure part of the SN9C10X chip if necessary. You don't need to
setup picture settings like brightness, contrast, etc.. here, if
@@ -315,6 +332,14 @@
matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
*/
+ int (*set_pix_format)(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix);
+ /*
+ To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
+ SN9C10X pixel format or viceversa. On error return the corresponding
+ error code without rolling back.
+ */
+
const struct device* dev;
/*
This is the argument for dev_err(), dev_info() and dev_warn(). It
@@ -341,7 +366,8 @@
/* Private ioctl's for control settings supported by some image sensors */
#define SN9C102_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
-#define SN9C102_V4L2_CID_DAC_SIGN V4L2_CID_PRIVATE_BASE + 1
-#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 2
+#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
+#define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2
+#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3
#endif /* _SN9C102_SENSOR_H_ */
diff -Nru a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
--- a/drivers/usb/media/sn9c102_tas5110c1b.c 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c 2005-01-07 15:50:54 -08:00
@@ -93,7 +93,21 @@
/* Don't change ! */
err += sn9c102_write_reg(cam, 0x14, 0x1a);
err += sn9c102_write_reg(cam, 0x0a, 0x1b);
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
+ err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
+
+ return err;
+}
+
+
+static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x2b, 0x19);
+ else
+ err += sn9c102_write_reg(cam, 0xfb, 0x19);
return err;
}
@@ -102,10 +116,9 @@
static struct sn9c102_sensor tas5110c1b = {
.name = "TAS5110C1B",
.maintainer = "Luca Risolia <[email protected]>",
+ .sysfs_ops = SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_3WIRES,
- .slave_read_id = SN9C102_I2C_SLAVEID_UNAVAILABLE,
- .slave_write_id = SN9C102_I2C_SLAVEID_FICTITIOUS,
.init = &tas5110c1b_init,
.qctrl = {
{
@@ -141,7 +154,8 @@
.height = 288,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.priv = 8,
- }
+ },
+ .set_pix_format = &tas5110c1b_set_pix_format
};
diff -Nru a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
--- a/drivers/usb/media/sn9c102_tas5130d1b.c 2005-01-07 15:50:54 -08:00
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c 2005-01-07 15:50:54 -08:00
@@ -98,7 +98,21 @@
/* Do NOT change! */
err += sn9c102_write_reg(cam, 0x1f, 0x1a);
err += sn9c102_write_reg(cam, 0x1a, 0x1b);
- err += sn9c102_write_reg(cam, 0xf3, 0x19);
+ err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
+
+ return err;
+}
+
+
+static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x63, 0x19);
+ else
+ err += sn9c102_write_reg(cam, 0xf3, 0x19);
return err;
}
@@ -107,10 +121,9 @@
static struct sn9c102_sensor tas5130d1b = {
.name = "TAS5130D1B",
.maintainer = "Luca Risolia <[email protected]>",
+ .sysfs_ops = SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_3WIRES,
- .slave_read_id = SN9C102_I2C_SLAVEID_UNAVAILABLE,
- .slave_write_id = SN9C102_I2C_SLAVEID_FICTITIOUS,
.init = &tas5130d1b_init,
.qctrl = {
{
@@ -156,7 +169,8 @@
.height = 480,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.priv = 8,
- }
+ },
+ .set_pix_format = &tas5130d1b_set_pix_format
};
ChangeSet 1.1938.444.4, 2004/12/15 11:15:21-08:00, [email protected]
[PATCH] select HOTPLUG
The patch below changes all dependencies on HOTPLUG to selects.
The help text of HOTPLUG is adjusted in a way, that manually selecting
it is only required for external modules.
If an option already depends on PCMCIA or selects FW_LOADER an explicit
select of HOTPLUG is not required.
Signed-off-by: Adrian Bunk <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
arch/ia64/Kconfig | 13 +++++++------
arch/ppc64/Kconfig | 3 ++-
arch/s390/Kconfig | 3 ++-
drivers/base/Kconfig | 2 +-
drivers/net/pcmcia/Kconfig | 2 +-
drivers/net/tokenring/Kconfig | 2 +-
drivers/net/wireless/Kconfig | 2 +-
drivers/parport/Kconfig | 2 +-
drivers/pci/hotplug/Kconfig | 2 +-
drivers/pcmcia/Kconfig | 2 +-
init/Kconfig | 17 +++--------------
11 files changed, 21 insertions(+), 29 deletions(-)
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/arch/ia64/Kconfig 2005-01-07 15:51:45 -08:00
@@ -241,13 +241,14 @@
performance hit.
config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
- depends on SMP && HOTPLUG && EXPERIMENTAL
+ bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ depends on SMP && EXPERIMENTAL
+ select HOTPLUG
default n
- ---help---
- Say Y here to experiment with turning CPUs off and on. CPUs
- can be controlled through /sys/devices/system/cpu/cpu#.
- Say N if you want to disable CPU hotplug.
+ ---help---
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu/cpu#.
+ Say N if you want to disable CPU hotplug.
config PREEMPT
bool "Preemptible Kernel"
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/arch/ppc64/Kconfig 2005-01-07 15:51:45 -08:00
@@ -301,7 +301,8 @@
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
- depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PSERIES
+ depends on SMP && EXPERIMENTAL && PPC_PSERIES
+ select HOTPLUG
---help---
Say Y here to be able to turn CPUs off and on.
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/arch/s390/Kconfig 2005-01-07 15:51:45 -08:00
@@ -81,7 +81,8 @@
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
- depends on SMP && HOTPLUG && EXPERIMENTAL
+ depends on SMP && EXPERIMENTAL
+ select HOTPLUG
default n
help
Say Y here to experiment with turning CPUs off and on. CPUs
diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig
--- a/drivers/base/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/base/Kconfig 2005-01-07 15:51:45 -08:00
@@ -20,7 +20,7 @@
config FW_LOADER
tristate "Hotplug firmware loading support"
- depends on HOTPLUG
+ select HOTPLUG
---help---
This option is provided for the case where no in-kernel-tree modules
require hotplug firmware loading support, but a module built outside
diff -Nru a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
--- a/drivers/net/pcmcia/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/net/pcmcia/Kconfig 2005-01-07 15:51:45 -08:00
@@ -3,7 +3,7 @@
#
menu "PCMCIA network device support"
- depends on NETDEVICES && HOTPLUG && PCMCIA!=n
+ depends on NETDEVICES && PCMCIA!=n
config NET_PCMCIA
bool "PCMCIA network device support"
diff -Nru a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
--- a/drivers/net/tokenring/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/net/tokenring/Kconfig 2005-01-07 15:51:45 -08:00
@@ -84,7 +84,7 @@
config TMS380TR
tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
- depends on TR && (PCI || ISA) && HOTPLUG
+ depends on TR && (PCI || ISA)
select FW_LOADER
---help---
This driver provides generic support for token ring adapters
diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/net/wireless/Kconfig 2005-01-07 15:51:45 -08:00
@@ -311,7 +311,7 @@
depends on NET_RADIO && PCI
config PRISM54
tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus'
- depends on PCI && NET_RADIO && EXPERIMENTAL && HOTPLUG
+ depends on PCI && NET_RADIO && EXPERIMENTAL
select FW_LOADER
---help---
Enable PCI and Cardbus support for the following chipset based cards:
diff -Nru a/drivers/parport/Kconfig b/drivers/parport/Kconfig
--- a/drivers/parport/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/parport/Kconfig 2005-01-07 15:51:45 -08:00
@@ -83,7 +83,7 @@
config PARPORT_PC_PCMCIA
tristate "Support for PCMCIA management for PC-style ports"
- depends on PARPORT!=n && HOTPLUG && (PCMCIA!=n && PARPORT_PC=m && PARPORT_PC || PARPORT_PC=y && PCMCIA)
+ depends on PARPORT!=n && (PCMCIA!=n && PARPORT_PC=m && PARPORT_PC || PARPORT_PC=y && PCMCIA)
help
Say Y here if you need PCMCIA support for your PC-style parallel
ports. If unsure, say N.
diff -Nru a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
--- a/drivers/pci/hotplug/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/pci/hotplug/Kconfig 2005-01-07 15:51:45 -08:00
@@ -3,11 +3,11 @@
#
menu "PCI Hotplug Support"
- depends on HOTPLUG
config HOTPLUG_PCI
tristate "Support for PCI Hotplug (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL
+ select HOTPLUG
---help---
Say Y here if you have a motherboard with a PCI Hotplug controller.
This allows you to add and remove PCI cards while the machine is
diff -Nru a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
--- a/drivers/pcmcia/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/drivers/pcmcia/Kconfig 2005-01-07 15:51:45 -08:00
@@ -6,10 +6,10 @@
#
menu "PCCARD (PCMCIA/CardBus) support"
- depends on HOTPLUG
config PCCARD
tristate "PCCard (PCMCIA/CardBus) support"
+ select HOTPLUG
---help---
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
computer. These are credit-card size devices such as network cards,
diff -Nru a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig 2005-01-07 15:51:45 -08:00
+++ b/init/Kconfig 2005-01-07 15:51:45 -08:00
@@ -195,20 +195,9 @@
bool "Support for hot-pluggable devices" if !ARCH_S390
default ARCH_S390
help
- Say Y here if you want to plug devices into your computer while
- the system is running, and be able to use them quickly. In many
- cases, the devices can likewise be unplugged at any time too.
-
- One well known example of this is PCMCIA- or PC-cards, credit-card
- size devices such as network cards, modems or hard drives which are
- plugged into slots found on all modern laptop computers. Another
- example, used on modern desktops as well as laptops, is USB.
-
- Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
- software (at <http://linux-hotplug.sourceforge.net/>) and install it.
- Then your kernel will automatically call out to a user mode "policy
- agent" (/sbin/hotplug) to load modules and set up software needed
- to use devices as you hotplug them.
+ This option is provided for the case where no in-kernel-tree
+ modules require HOTPLUG functionality, but a module built
+ outside the kernel tree does. Such modules require Y here.
config KOBJECT_UEVENT
bool "Kernel Userspace Events"
ChangeSet 1.1938.446.24, 2004/12/15 16:36:14-08:00, [email protected]
[PATCH] USB: EHCI and HCD API updates (12/15)
Updates the EHCI HCD to match API updates. This includes both new
changes (struct hcd_dev gone) and older ones (endpoints now properly
enabled/disabled, so "re"init paths aren't needed). Hmm, the ISO
stuff could avoid that lookup now too.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-hcd.c | 20 ++++++++------------
drivers/usb/host/ehci-q.c | 33 ++++++---------------------------
drivers/usb/host/ehci-sched.c | 33 ++++++++++++++-------------------
drivers/usb/host/ehci.h | 3 ++-
4 files changed, 30 insertions(+), 59 deletions(-)
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c 2005-01-07 15:48:28 -08:00
+++ b/drivers/usb/host/ehci-hcd.c 2005-01-07 15:48:28 -08:00
@@ -895,6 +895,7 @@
*/
static int ehci_urb_enqueue (
struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep,
struct urb *urb,
int mem_flags
) {
@@ -909,12 +910,12 @@
default:
if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
return -ENOMEM;
- return submit_async (ehci, urb, &qtd_list, mem_flags);
+ return submit_async (ehci, ep, urb, &qtd_list, mem_flags);
case PIPE_INTERRUPT:
if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
return -ENOMEM;
- return intr_submit (ehci, urb, &qtd_list, mem_flags);
+ return intr_submit (ehci, ep, urb, &qtd_list, mem_flags);
case PIPE_ISOCHRONOUS:
if (urb->dev->speed == USB_SPEED_HIGH)
@@ -1014,23 +1015,18 @@
// bulk qh holds the data toggle
static void
-ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
+ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- int epnum;
unsigned long flags;
struct ehci_qh *qh, *tmp;
/* ASSERT: any requests/urbs are being unlinked */
/* ASSERT: nobody can be submitting urbs for this any more */
- epnum = ep & USB_ENDPOINT_NUMBER_MASK;
- if (epnum != 0 && (ep & USB_DIR_IN))
- epnum |= 0x10;
-
rescan:
spin_lock_irqsave (&ehci->lock, flags);
- qh = (struct ehci_qh *) dev->ep [epnum];
+ qh = ep->hcpriv;
if (!qh)
goto done;
@@ -1072,12 +1068,12 @@
/* caller was supposed to have unlinked any requests;
* that's not our job. just leak this memory.
*/
- ehci_err (ehci, "qh %p (#%d) state %d%s\n",
- qh, epnum, qh->qh_state,
+ ehci_err (ehci, "qh %p (#%02x) state %d%s\n",
+ qh, ep->desc.bEndpointAddress, qh->qh_state,
list_empty (&qh->qtd_list) ? "" : "(has tds)");
break;
}
- dev->ep[epnum] = NULL;
+ ep->hcpriv = NULL;
done:
spin_unlock_irqrestore (&ehci->lock, flags);
return;
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c 2005-01-07 15:48:28 -08:00
+++ b/drivers/usb/host/ehci-q.c 2005-01-07 15:48:28 -08:00
@@ -832,26 +832,8 @@
qtd = list_entry (qtd_list->next, struct ehci_qtd,
qtd_list);
- /* control qh may need patching after enumeration */
+ /* control qh may need patching ... */
if (unlikely (epnum == 0)) {
- /* set_address changes the address */
- if ((qh->hw_info1 & QH_ADDR_MASK) == 0)
- qh->hw_info1 |= cpu_to_le32 (
- usb_pipedevice (urb->pipe));
-
- /* for full speed, ep0 maxpacket can grow */
- else if (!(qh->hw_info1
- & __constant_cpu_to_le32 (0x3 << 12))) {
- u32 info, max;
-
- info = le32_to_cpu (qh->hw_info1);
- max = urb->dev->descriptor.bMaxPacketSize0;
- if (max > (0x07ff & (info >> 16))) {
- info &= ~(0x07ff << 16);
- info |= max << 16;
- qh->hw_info1 = cpu_to_le32 (info);
- }
- }
/* usb_reset_device() briefly reverts to address 0 */
if (usb_pipedevice (urb->pipe) == 0)
@@ -908,33 +890,30 @@
static int
submit_async (
struct ehci_hcd *ehci,
+ struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
int mem_flags
) {
struct ehci_qtd *qtd;
- struct hcd_dev *dev;
int epnum;
unsigned long flags;
struct ehci_qh *qh = NULL;
qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list);
- dev = (struct hcd_dev *)urb->dev->hcpriv;
- epnum = usb_pipeendpoint (urb->pipe);
- if (usb_pipein (urb->pipe) && !usb_pipecontrol (urb->pipe))
- epnum |= 0x10;
+ epnum = ep->desc.bEndpointAddress;
#ifdef EHCI_URB_TRACE
ehci_dbg (ehci,
"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
__FUNCTION__, urb->dev->devpath, urb,
- epnum & 0x0f, usb_pipein (urb->pipe) ? "in" : "out",
+ epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
urb->transfer_buffer_length,
- qtd, dev ? dev->ep [epnum] : (void *)~0);
+ qtd, ep->hcpriv);
#endif
spin_lock_irqsave (&ehci->lock, flags);
- qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]);
+ qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
/* Control/bulk operations through TTs don't need scheduling,
* the HC and TT handle it when the TT has a buffer ready.
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c 2005-01-07 15:48:28 -08:00
+++ b/drivers/usb/host/ehci-sched.c 2005-01-07 15:48:28 -08:00
@@ -525,6 +525,7 @@
static int intr_submit (
struct ehci_hcd *ehci,
+ struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
int mem_flags
@@ -532,23 +533,17 @@
unsigned epnum;
unsigned long flags;
struct ehci_qh *qh;
- struct hcd_dev *dev;
- int is_input;
int status = 0;
struct list_head empty;
/* get endpoint and transfer/schedule data */
- epnum = usb_pipeendpoint (urb->pipe);
- is_input = usb_pipein (urb->pipe);
- if (is_input)
- epnum |= 0x10;
+ epnum = ep->desc.bEndpointAddress;
spin_lock_irqsave (&ehci->lock, flags);
- dev = (struct hcd_dev *)urb->dev->hcpriv;
/* get qh and force any scheduling errors */
INIT_LIST_HEAD (&empty);
- qh = qh_append_tds (ehci, urb, &empty, epnum, &dev->ep [epnum]);
+ qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
if (qh == 0) {
status = -ENOMEM;
goto done;
@@ -559,7 +554,7 @@
}
/* then queue the urb's tds to the qh */
- qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]);
+ qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
BUG_ON (qh == 0);
/* ... update usbfs periodic stats */
@@ -689,7 +684,6 @@
*/
if (stream->refcount == 1) {
int is_in;
- struct hcd_dev *dev = stream->udev->hcpriv;
// BUG_ON (!list_empty(&stream->td_list));
@@ -719,7 +713,7 @@
is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
stream->bEndpointAddress &= 0x0f;
- dev->ep[is_in + stream->bEndpointAddress] = NULL;
+ stream->ep->hcpriv = NULL;
if (stream->rescheduled) {
ehci_info (ehci, "ep%d%s-iso rescheduled "
@@ -746,24 +740,25 @@
iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
{
unsigned epnum;
- struct hcd_dev *dev;
struct ehci_iso_stream *stream;
+ struct usb_host_endpoint *ep;
unsigned long flags;
epnum = usb_pipeendpoint (urb->pipe);
if (usb_pipein(urb->pipe))
- epnum += 0x10;
+ ep = urb->dev->ep_in[epnum];
+ else
+ ep = urb->dev->ep_out[epnum];
spin_lock_irqsave (&ehci->lock, flags);
-
- dev = (struct hcd_dev *)urb->dev->hcpriv;
- stream = dev->ep [epnum];
+ stream = ep->hcpriv;
if (unlikely (stream == 0)) {
stream = iso_stream_alloc(GFP_ATOMIC);
if (likely (stream != 0)) {
/* dev->ep owns the initial refcount */
- dev->ep[epnum] = stream;
+ ep->hcpriv = stream;
+ stream->ep = ep;
iso_stream_init(stream, urb->dev, urb->pipe,
urb->interval);
}
@@ -771,8 +766,8 @@
/* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */
} else if (unlikely (stream->hw_info1 != 0)) {
ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
- urb->dev->devpath, epnum & 0x0f,
- (epnum & 0x10) ? "in" : "out");
+ urb->dev->devpath, epnum,
+ usb_pipein(urb->pipe) ? "in" : "out");
stream = NULL;
}
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h 2005-01-07 15:48:28 -08:00
+++ b/drivers/usb/host/ehci.h 2005-01-07 15:48:28 -08:00
@@ -36,7 +36,7 @@
/* ehci_hcd->lock guards shared data against other CPUs:
* ehci_hcd: async, reclaim, periodic (and shadow), ...
- * hcd_dev: ep[]
+ * usb_host_endpoint: hcpriv
* ehci_qh: qh_next, qtd_list
* ehci_qtd: qtd_list
*
@@ -430,6 +430,7 @@
struct list_head td_list; /* queued itds/sitds */
struct list_head free_list; /* list of unused itds/sitds */
struct usb_device *udev;
+ struct usb_host_endpoint *ep;
/* output of (re)scheduling */
unsigned long start; /* jiffies */
ChangeSet 1.1938.446.25, 2004/12/15 16:37:08-08:00, [email protected]
[PATCH] USB: OHCI and HCD API changes (13/15)
Updates the OHCI HCD to match API updates. This includes both new
changes (struct hcd_dev gone) and older ones (endpoints now properly
enabled/disabled, so "re"init paths aren't needed).
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ohci-hcd.c | 23 ++++++++--------------
drivers/usb/host/ohci-q.c | 46 +++++++++++++++++++-------------------------
2 files changed, 29 insertions(+), 40 deletions(-)
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c 2005-01-07 15:48:16 -08:00
+++ b/drivers/usb/host/ohci-hcd.c 2005-01-07 15:48:16 -08:00
@@ -165,6 +165,7 @@
*/
static int ohci_urb_enqueue (
struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep,
struct urb *urb,
int mem_flags
) {
@@ -181,7 +182,7 @@
#endif
/* every endpoint has a ed, locate and maybe (re)initialize it */
- if (! (ed = ed_get (ohci, urb->dev, pipe, urb->interval)))
+ if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval)))
return -ENOMEM;
/* for the private part of the URB we need the number of TDs (size) */
@@ -338,26 +339,21 @@
*/
static void
-ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
+ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int epnum = ep & USB_ENDPOINT_NUMBER_MASK;
unsigned long flags;
- struct ed *ed;
+ struct ed *ed = ep->hcpriv;
unsigned limit = 1000;
/* ASSERT: any requests/urbs are being unlinked */
/* ASSERT: nobody can be submitting urbs for this any more */
- epnum <<= 1;
- if (epnum != 0 && !(ep & USB_DIR_IN))
- epnum |= 1;
+ if (!ed)
+ return;
rescan:
spin_lock_irqsave (&ohci->lock, flags);
- ed = dev->ep [epnum];
- if (!ed)
- goto done;
if (!HCD_IS_RUNNING (ohci->hcd.state)) {
sanitize:
@@ -387,14 +383,13 @@
/* caller was supposed to have unlinked any requests;
* that's not our job. can't recover; must leak ed.
*/
- ohci_err (ohci, "leak ed %p (#%d) state %d%s\n",
- ed, epnum, ed->state,
+ ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n",
+ ed, ep->desc.bEndpointAddress, ed->state,
list_empty (&ed->td_list) ? "" : " (has tds)");
td_free (ohci, ed->dummy);
break;
}
- dev->ep [epnum] = NULL;
-done:
+ ep->hcpriv = NULL;
spin_unlock_irqrestore (&ohci->lock, flags);
return;
}
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c 2005-01-07 15:48:16 -08:00
+++ b/drivers/usb/host/ohci-q.c 2005-01-07 15:48:16 -08:00
@@ -386,37 +386,30 @@
/*-------------------------------------------------------------------------*/
/* get and maybe (re)init an endpoint. init _should_ be done only as part
- * of usb_set_configuration() or usb_set_interface() ... but the USB stack
- * isn't very stateful, so we re-init whenever the HC isn't looking.
+ * of enumeration, usb_set_configuration() or usb_set_interface().
*/
static struct ed *ed_get (
struct ohci_hcd *ohci,
+ struct usb_host_endpoint *ep,
struct usb_device *udev,
unsigned int pipe,
int interval
) {
- int is_out = !usb_pipein (pipe);
- int type = usb_pipetype (pipe);
- struct hcd_dev *dev = (struct hcd_dev *) udev->hcpriv;
struct ed *ed;
- unsigned ep;
unsigned long flags;
- ep = usb_pipeendpoint (pipe) << 1;
- if (type != PIPE_CONTROL && is_out)
- ep |= 1;
-
spin_lock_irqsave (&ohci->lock, flags);
- if (!(ed = dev->ep [ep])) {
+ if (!(ed = ep->hcpriv)) {
struct td *td;
+ int is_out;
+ u32 info;
ed = ed_alloc (ohci, GFP_ATOMIC);
if (!ed) {
/* out of memory */
goto done;
}
- dev->ep [ep] = ed;
/* dummy td; end of td list for ed */
td = td_alloc (ohci, GFP_ATOMIC);
@@ -430,38 +423,39 @@
ed->hwTailP = cpu_to_hc32 (ohci, td->td_dma);
ed->hwHeadP = ed->hwTailP; /* ED_C, ED_H zeroed */
ed->state = ED_IDLE;
- ed->type = type;
- }
- /* NOTE: only ep0 currently needs this "re"init logic, during
- * enumeration (after set_address).
- */
- if (ed->state == ED_IDLE) {
- u32 info;
+ is_out = !(ep->desc.bEndpointAddress & USB_DIR_IN);
+ /* FIXME usbcore changes dev->devnum before SET_ADDRESS
+ * suceeds ... otherwise we wouldn't need "pipe".
+ */
info = usb_pipedevice (pipe);
- info |= (ep >> 1) << 7;
- info |= usb_maxpacket (udev, pipe, is_out) << 16;
+ ed->type = usb_pipetype(pipe);
+
+ info |= (ep->desc.bEndpointAddress & ~USB_DIR_IN) << 7;
+ info |= ep->desc.wMaxPacketSize << 16;
if (udev->speed == USB_SPEED_LOW)
info |= ED_LOWSPEED;
/* only control transfers store pids in tds */
- if (type != PIPE_CONTROL) {
+ if (ed->type != PIPE_CONTROL) {
info |= is_out ? ED_OUT : ED_IN;
- if (type != PIPE_BULK) {
+ if (ed->type != PIPE_BULK) {
/* periodic transfers... */
- if (type == PIPE_ISOCHRONOUS)
+ if (ed->type == PIPE_ISOCHRONOUS)
info |= ED_ISO;
else if (interval > 32) /* iso can be bigger */
interval = 32;
ed->interval = interval;
ed->load = usb_calc_bus_time (
udev->speed, !is_out,
- type == PIPE_ISOCHRONOUS,
- usb_maxpacket (udev, pipe, is_out))
+ ed->type == PIPE_ISOCHRONOUS,
+ ep->desc.wMaxPacketSize)
/ 1000;
}
}
ed->hwINFO = cpu_to_hc32(ohci, info);
+
+ ep->hcpriv = ed;
}
done:
ChangeSet 1.1938.439.45, 2005/01/06 16:38:08-08:00, [email protected]
[PATCH] debugfs-typo-fix
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/debugfs.h | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/include/linux/debugfs.h b/include/linux/debugfs.h
--- a/include/linux/debugfs.h 2005-01-07 15:39:26 -08:00
+++ b/include/linux/debugfs.h 2005-01-07 15:39:26 -08:00
@@ -82,7 +82,7 @@
struct dentry *parent,
u8 *value)
{
- return EFF_PTR(-ENODEV);
+ return ERR_PTR(-ENODEV);
}
#endif
ChangeSet 1.1938.439.51, 2005/01/06 17:29:21-08:00, [email protected]
[PATCH] USB: another workaround for cdc-acm
there are a lot of buggy modems.
Signed-Off-By: Oliver Neukum <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/class/cdc-acm.c | 15 +++++++++++++++
drivers/usb/class/cdc-acm.h | 3 ++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c 2005-01-07 15:37:12 -08:00
+++ b/drivers/usb/class/cdc-acm.c 2005-01-07 15:37:12 -08:00
@@ -532,7 +532,17 @@
u8 call_management_function = 0;
int call_interface_num = -1;
int data_interface_num;
+ unsigned long quirks;
+ /* handle quirks deadly to normal probing*/
+ quirks = (unsigned long)id->driver_info;
+ if (quirks == NO_UNION_NORMAL) {
+ data_interface = usb_ifnum_to_if(usb_dev, 1);
+ control_interface = usb_ifnum_to_if(usb_dev, 0);
+ goto skip_normal_probe;
+ }
+
+ /* normal probing*/
if (!buffer) {
err("Wierd descriptor references");
return -EINVAL;
@@ -607,6 +617,7 @@
if (data_interface_num != call_interface_num)
dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
+skip_normal_probe:
if (usb_interface_claimed(data_interface)) { /* valid in this context */
dev_dbg(&intf->dev,"The data interface isn't available\n");
return -EBUSY;
@@ -805,6 +816,10 @@
*/
static struct usb_device_id acm_ids[] = {
+ /* quirky and broken devices */
+ { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 1) },
{ USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 2) },
diff -Nru a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
--- a/drivers/usb/class/cdc-acm.h 2005-01-07 15:37:12 -08:00
+++ b/drivers/usb/class/cdc-acm.h 2005-01-07 15:37:12 -08:00
@@ -125,4 +125,5 @@
#define CDC_DATA_INTERFACE_TYPE 0x0a
-
+/* constants describing various quirks and errors */
+#define NO_UNION_NORMAL 1
ChangeSet 1.1938.444.6, 2004/12/16 13:16:18-08:00, [email protected]
debugfs: add debugfs
debugfs is a filesystem that is just for debug data. Start moving stuff out of proc and sysfs now :)
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/DocBook/kernel-api.tmpl | 9
fs/Makefile | 1
fs/debugfs/Makefile | 4
fs/debugfs/file.c | 262 ++++++++++++++++++++++++++++
fs/debugfs/inode.c | 315 ++++++++++++++++++++++++++++++++++
include/linux/debugfs.h | 90 +++++++++
lib/Kconfig.debug | 10 +
7 files changed, 691 insertions(+)
diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl 2005-01-07 15:47:39 -08:00
+++ b/Documentation/DocBook/kernel-api.tmpl 2005-01-07 15:47:39 -08:00
@@ -105,6 +105,15 @@
</sect1>
</chapter>
+ <chapter id="debugfs">
+ <title>The debugfs filesystem</title>
+
+ <sect1><title>debugfs interface</title>
+!Efs/debugfs/inode.c
+!Efs/debugfs/file.c
+ </sect1>
+ </chapter>
+
<chapter id="vfs">
<title>The Linux VFS</title>
<sect1><title>The Directory Cache</title>
diff -Nru a/fs/Makefile b/fs/Makefile
--- a/fs/Makefile 2005-01-07 15:47:39 -08:00
+++ b/fs/Makefile 2005-01-07 15:47:39 -08:00
@@ -94,3 +94,4 @@
obj-$(CONFIG_BEFS_FS) += befs/
obj-$(CONFIG_HOSTFS) += hostfs/
obj-$(CONFIG_HPPFS) += hppfs/
+obj-$(CONFIG_DEBUG_FS) += debugfs/
diff -Nru a/fs/debugfs/Makefile b/fs/debugfs/Makefile
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/fs/debugfs/Makefile 2005-01-07 15:47:39 -08:00
@@ -0,0 +1,4 @@
+debugfs-objs := inode.o file.o
+
+obj-$(CONFIG_DEBUG_FS) += debugfs.o
+
diff -Nru a/fs/debugfs/file.c b/fs/debugfs/file.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/fs/debugfs/file.c 2005-01-07 15:47:39 -08:00
@@ -0,0 +1,262 @@
+/*
+ * file.c - part of debugfs, a tiny little debug file system
+ *
+ * Copyright (C) 2004 Greg Kroah-Hartman <[email protected]>
+ * Copyright (C) 2004 IBM Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * debugfs is for people to use instead of /proc or /sys.
+ * See Documentation/DocBook/kernel-api for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/debugfs.h>
+
+static ssize_t default_read_file(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return 0;
+}
+
+static ssize_t default_write_file(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return count;
+}
+
+static int default_open(struct inode *inode, struct file *file)
+{
+ if (inode->u.generic_ip)
+ file->private_data = inode->u.generic_ip;
+
+ return 0;
+}
+
+struct file_operations debugfs_file_operations = {
+ .read = default_read_file,
+ .write = default_write_file,
+ .open = default_open,
+};
+
+#define simple_type(type, format, temptype, strtolfn) \
+static ssize_t read_file_##type(struct file *file, char __user *user_buf, \
+ size_t count, loff_t *ppos) \
+{ \
+ char buf[32]; \
+ type *val = file->private_data; \
+ \
+ snprintf(buf, sizeof(buf), format, *val); \
+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));\
+} \
+static ssize_t write_file_##type(struct file *file, const char __user *user_buf,\
+ size_t count, loff_t *ppos) \
+{ \
+ char *endp; \
+ char buf[32]; \
+ int buf_size; \
+ type *val = file->private_data; \
+ temptype tmp; \
+ \
+ memset(buf, 0x00, sizeof(buf)); \
+ buf_size = min(count, (sizeof(buf)-1)); \
+ if (copy_from_user(buf, user_buf, buf_size)) \
+ return -EFAULT; \
+ \
+ tmp = strtolfn(buf, &endp, 0); \
+ if ((endp == buf) || ((type)tmp != tmp)) \
+ return -EINVAL; \
+ *val = tmp; \
+ return count; \
+} \
+static struct file_operations fops_##type = { \
+ .read = read_file_##type, \
+ .write = write_file_##type, \
+ .open = default_open, \
+};
+simple_type(u8, "%c", unsigned long, simple_strtoul);
+simple_type(u16, "%hi", unsigned long, simple_strtoul);
+simple_type(u32, "%i", unsigned long, simple_strtoul);
+
+/**
+ * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value. If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_u8(const char *name, mode_t mode,
+ struct dentry *parent, u8 *value)
+{
+ return debugfs_create_file(name, mode, parent, value, &fops_u8);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_u8);
+
+/**
+ * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value. If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_u16(const char *name, mode_t mode,
+ struct dentry *parent, u16 *value)
+{
+ return debugfs_create_file(name, mode, parent, value, &fops_u16);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_u16);
+
+/**
+ * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value. If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_u32(const char *name, mode_t mode,
+ struct dentry *parent, u32 *value)
+{
+ return debugfs_create_file(name, mode, parent, value, &fops_u32);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_u32);
+
+static ssize_t read_file_bool(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[3];
+ u32 *val = file->private_data;
+
+ if (val)
+ buf[0] = 'Y';
+ else
+ buf[0] = 'N';
+ buf[1] = '\n';
+ buf[2] = 0x00;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[32];
+ int buf_size;
+ u32 *val = file->private_data;
+
+ buf_size = min(count, (sizeof(buf)-1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ switch (buf[0]) {
+ case 'y':
+ case 'Y':
+ case '1':
+ *val = 1;
+ break;
+ case 'n':
+ case 'N':
+ case '0':
+ *val = 0;
+ break;
+ }
+
+ return count;
+}
+
+static struct file_operations fops_bool = {
+ .read = read_file_bool,
+ .write = write_file_bool,
+ .open = default_open,
+};
+
+/**
+ * debugfs_create_bool - create a file in the debugfs filesystem that is used to read and write a boolean value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value. If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_bool(const char *name, mode_t mode,
+ struct dentry *parent, u32 *value)
+{
+ return debugfs_create_file(name, mode, parent, value, &fops_bool);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_bool);
+
diff -Nru a/fs/debugfs/inode.c b/fs/debugfs/inode.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/fs/debugfs/inode.c 2005-01-07 15:47:39 -08:00
@@ -0,0 +1,315 @@
+/*
+ * file.c - part of debugfs, a tiny little debug file system
+ *
+ * Copyright (C) 2004 Greg Kroah-Hartman <[email protected]>
+ * Copyright (C) 2004 IBM Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * debugfs is for people to use instead of /proc or /sys.
+ * See Documentation/DocBook/kernel-api for more details.
+ *
+ */
+
+/* uncomment to get debug messages from the debug filesystem, ah the irony. */
+/* #define DEBUG */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/debugfs.h>
+
+#define DEBUGFS_MAGIC 0x64626720
+
+/* declared over in file.c */
+extern struct file_operations debugfs_file_operations;
+
+static struct vfsmount *debugfs_mount;
+static int debugfs_mount_count;
+
+static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+{
+ struct inode *inode = new_inode(sb);
+
+ if (inode) {
+ inode->i_mode = mode;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ switch (mode & S_IFMT) {
+ default:
+ init_special_inode(inode, mode, dev);
+ break;
+ case S_IFREG:
+ inode->i_fop = &debugfs_file_operations;
+ break;
+ case S_IFDIR:
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+
+ /* directory inodes start off with i_nlink == 2 (for "." entry) */
+ inode->i_nlink++;
+ break;
+ }
+ }
+ return inode;
+}
+
+/* SMP-safe */
+static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
+ int mode, dev_t dev)
+{
+ struct inode *inode = debugfs_get_inode(dir->i_sb, mode, dev);
+ int error = -EPERM;
+
+ if (dentry->d_inode)
+ return -EEXIST;
+
+ if (inode) {
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ error = 0;
+ }
+ return error;
+}
+
+static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ int res;
+
+ mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ res = debugfs_mknod(dir, dentry, mode, 0);
+ if (!res)
+ dir->i_nlink++;
+ return res;
+}
+
+static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+ mode = (mode & S_IALLUGO) | S_IFREG;
+ return debugfs_mknod(dir, dentry, mode, 0);
+}
+
+static inline int debugfs_positive(struct dentry *dentry)
+{
+ return dentry->d_inode && !d_unhashed(dentry);
+}
+
+static int debug_fill_super(struct super_block *sb, void *data, int silent)
+{
+ static struct tree_descr debug_files[] = {{""}};
+
+ return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
+}
+
+static struct dentry * get_dentry(struct dentry *parent, const char *name)
+{
+ struct qstr qstr;
+
+ qstr.name = name;
+ qstr.len = strlen(name);
+ qstr.hash = full_name_hash(name,qstr.len);
+ return lookup_hash(&qstr,parent);
+}
+
+static struct super_block *debug_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+ void *data)
+{
+ return get_sb_single(fs_type, flags, data, debug_fill_super);
+}
+
+static struct file_system_type debug_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "debugfs",
+ .get_sb = debug_get_sb,
+ .kill_sb = kill_litter_super,
+};
+
+static int debugfs_create_by_name(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct dentry **dentry)
+{
+ int error = 0;
+
+ /* If the parent is not specified, we create it in the root.
+ * We need the root dentry to do this, which is in the super
+ * block. A pointer to that is in the struct vfsmount that we
+ * have around.
+ */
+ if (!parent ) {
+ if (debugfs_mount && debugfs_mount->mnt_sb) {
+ parent = debugfs_mount->mnt_sb->s_root;
+ }
+ }
+ if (!parent) {
+ pr_debug("debugfs: Ah! can not find a parent!\n");
+ return -EFAULT;
+ }
+
+ *dentry = NULL;
+ down(&parent->d_inode->i_sem);
+ *dentry = get_dentry (parent, name);
+ if (!IS_ERR(dentry)) {
+ if ((mode & S_IFMT) == S_IFDIR)
+ error = debugfs_mkdir(parent->d_inode, *dentry, mode);
+ else
+ error = debugfs_create(parent->d_inode, *dentry, mode);
+ } else
+ error = PTR_ERR(dentry);
+ up(&parent->d_inode->i_sem);
+
+ return error;
+}
+
+/**
+ * debugfs_create_file - create a file in the debugfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.u.generic_ip pointer will point to this value on
+ * the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ * this file.
+ *
+ * This is the basic "create a file" function for debugfs. It allows for a
+ * wide range of flexibility in createing a file, or a directory (if you
+ * want to create a directory, the debugfs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent, void *data,
+ struct file_operations *fops)
+{
+ struct dentry *dentry = NULL;
+ int error;
+
+ pr_debug("debugfs: creating file '%s'\n",name);
+
+ error = simple_pin_fs("debugfs", &debugfs_mount, &debugfs_mount_count);
+ if (error)
+ goto exit;
+
+ error = debugfs_create_by_name(name, mode, parent, &dentry);
+ if (error) {
+ dentry = NULL;
+ goto exit;
+ }
+
+ if (dentry->d_inode) {
+ if (data)
+ dentry->d_inode->u.generic_ip = data;
+ if (fops)
+ dentry->d_inode->i_fop = fops;
+ }
+exit:
+ return dentry;
+}
+EXPORT_SYMBOL_GPL(debugfs_create_file);
+
+/**
+ * debugfs_create_dir - create a directory in the debugfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the directory to
+ * create.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * directory will be created in the root of the debugfs filesystem.
+ *
+ * This function creates a directory in debugfs with the given name.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
+{
+ return debugfs_create_file(name,
+ S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+ parent, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_dir);
+
+/**
+ * debugfs_remove - removes a file or directory from the debugfs filesystem
+ *
+ * @dentry: a pointer to a the dentry of the file or directory to be
+ * removed.
+ *
+ * This function removes a file or directory in debugfs that was previously
+ * created with a call to another debugfs function (like
+ * debufs_create_file() or variants thereof.)
+ *
+ * This function is required to be called in order for the file to be
+ * removed, no automatic cleanup of files will happen when a module is
+ * removed, you are responsible here.
+ */
+void debugfs_remove(struct dentry *dentry)
+{
+ struct dentry *parent;
+
+ if (!dentry)
+ return;
+
+ parent = dentry->d_parent;
+ if (!parent || !parent->d_inode)
+ return;
+
+ down(&parent->d_inode->i_sem);
+ if (debugfs_positive(dentry)) {
+ if (dentry->d_inode) {
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ simple_rmdir(parent->d_inode, dentry);
+ else
+ simple_unlink(parent->d_inode, dentry);
+ dput(dentry);
+ }
+ }
+ up(&parent->d_inode->i_sem);
+ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+}
+EXPORT_SYMBOL_GPL(debugfs_remove);
+
+static int __init debugfs_init(void)
+{
+ return register_filesystem(&debug_fs_type);
+}
+
+static void __exit debugfs_exit(void)
+{
+ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ unregister_filesystem(&debug_fs_type);
+}
+
+core_initcall(debugfs_init);
+module_exit(debugfs_exit);
+MODULE_LICENSE("GPL");
+
diff -Nru a/include/linux/debugfs.h b/include/linux/debugfs.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/include/linux/debugfs.h 2005-01-07 15:47:39 -08:00
@@ -0,0 +1,90 @@
+/*
+ * debugfs.h - a tiny little debug file system
+ *
+ * Copyright (C) 2004 Greg Kroah-Hartman <[email protected]>
+ * Copyright (C) 2004 IBM Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * debugfs is for people to use instead of /proc or /sys.
+ * See Documentation/DocBook/kernel-api for more details.
+ */
+
+#ifndef _DEBUGFS_H_
+#define _DEBUGFS_H_
+
+#if defined(CONFIG_DEBUG_FS)
+struct dentry *debugfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent, void *data,
+ struct file_operations *fops);
+
+struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
+
+void debugfs_remove(struct dentry *dentry);
+
+struct dentry *debugfs_create_u8(const char *name, mode_t mode,
+ struct dentry *parent, u8 *value);
+struct dentry *debugfs_create_u16(const char *name, mode_t mode,
+ struct dentry *parent, u16 *value);
+struct dentry *debugfs_create_u32(const char *name, mode_t mode,
+ struct dentry *parent, u32 *value);
+struct dentry *debugfs_create_bool(const char *name, mode_t mode,
+ struct dentry *parent, u32 *value);
+
+#else
+/*
+ * We do not return NULL from these functions if CONFIG_DEBUG_FS is not enabled
+ * so users have a chance to detect if there was a real error or not. We don't
+ * want to duplicate the design decision mistakes of procfs and devfs again.
+ */
+
+static inline struct dentry *debugfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent,
+ void *data,
+ struct file_operations *fops)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_dir(const char *name,
+ struct dentry *parent)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline void debugfs_remove(struct dentry *dentry)
+{ }
+
+static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode,
+ struct dentry *parent,
+ u8 *value)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_u16(const char *name, mode_t mode,
+ struct dentry *parent,
+ u8 *value)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_u32(const char *name, mode_t mode,
+ struct dentry *parent,
+ u8 *value)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode,
+ struct dentry *parent,
+ u8 *value)
+{
+ return EFF_PTR(-ENODEV);
+}
+
+#endif
+
+#endif
diff -Nru a/lib/Kconfig.debug b/lib/Kconfig.debug
--- a/lib/Kconfig.debug 2005-01-07 15:47:39 -08:00
+++ b/lib/Kconfig.debug 2005-01-07 15:47:39 -08:00
@@ -107,6 +107,16 @@
If you're truly short on disk space or don't expect to report any
bugs back to the UML developers, say N, otherwise say Y.
+config DEBUG_FS
+ bool "Debug Filesystem"
+ depends on DEBUG_KERNEL
+ help
+ debugfs is a virtual file system that kernel developers use to put
+ debugging files into. Enable this option to be able to read and
+ write to these files.
+
+ If unsure, say N.
+
if !X86_64
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
ChangeSet 1.1938.444.26, 2004/12/21 11:21:08-08:00, [email protected]
[PATCH] USB: fix Scheduling while atomic warning when resuming.
From: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-hub.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c 2005-01-07 15:40:46 -08:00
+++ b/drivers/usb/host/ehci-hub.c 2005-01-07 15:40:46 -08:00
@@ -122,7 +122,7 @@
writel (temp, &ehci->regs->port_status [i]);
}
i = HCS_N_PORTS (ehci->hcs_params);
- msleep (20);
+ mdelay (20);
while (i--) {
temp = readl (&ehci->regs->port_status [i]);
if ((temp & PORT_SUSPEND) == 0)
ChangeSet 1.1938.439.55, 2005/01/07 09:07:22-08:00, [email protected]
[PATCH] USB: ohci diagnostic tweak
This changes the OHCI "USB HC TakeOver failed" message to be a bit
more informative, by fingering the root cause: a BIOS/SMM bug.
That way they're more likely to either bug the board vendor, or find
workarounds (like tweaking the BIOS setup, or the ohci_hcd no_handshake
parameter) before giving up or (wrongly) reporting a Linux bug.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ohci-hcd.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c 2005-01-07 15:35:13 -08:00
+++ b/drivers/usb/host/ohci-hcd.c 2005-01-07 15:35:13 -08:00
@@ -441,7 +441,8 @@
while (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_IR) {
msleep (10);
if (--temp == 0) {
- ohci_err (ohci, "USB HC TakeOver failed!\n");
+ ohci_err (ohci, "USB HC takeover failed!"
+ " (BIOS/SMM bug)\n");
return -EBUSY;
}
}
ChangeSet 1.1938.444.9, 2004/12/17 14:50:31-08:00, [email protected]
[PATCH] add ATA over Ethernet driver
Provide support for ATA over Ethernet devices
Signed-off-by: Ed L. Cashin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/aoe/aoe.txt | 75 +++++
Documentation/aoe/autoload.sh | 17 +
Documentation/aoe/mkdevs.sh | 33 ++
Documentation/aoe/mkshelf.sh | 23 +
Documentation/aoe/status.sh | 15 +
MAINTAINERS | 6
drivers/Makefile | 1
drivers/block/Kconfig | 8
drivers/block/aoe/Makefile | 6
drivers/block/aoe/aoe.h | 163 ++++++++++
drivers/block/aoe/aoeblk.c | 251 ++++++++++++++++
drivers/block/aoe/aoechr.c | 295 +++++++++++++++++++
drivers/block/aoe/aoecmd.c | 627 ++++++++++++++++++++++++++++++++++++++++++
drivers/block/aoe/aoedev.c | 194 ++++++++++++
drivers/block/aoe/aoemain.c | 93 ++++++
drivers/block/aoe/aoenet.c | 173 +++++++++++
16 files changed, 1980 insertions(+)
diff -Nru a/Documentation/aoe/aoe.txt b/Documentation/aoe/aoe.txt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/aoe.txt 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,75 @@
+The EtherDrive (R) HOWTO for users of 2.6 kernels is found at ...
+
+ http://www.coraid.com/support/linux/EtherDrive-2.6-HOWTO.html
+
+ It has many tips and hints!
+
+CREATING DEVICE NODES
+
+ Users of udev should find device nodes created automatically. Two
+ scripts are provided in Documentation/aoe as examples of static
+ device node creation for using the aoe driver.
+
+ rm -rf /dev/etherd
+ sh Documentation/aoe/mkdevs.sh /dev/etherd
+
+ ... or to make just one shelf's worth of block device nodes ...
+
+ sh Documentation/aoe/mkshelf.sh /dev/etherd 0
+
+ There is also an autoload script that shows how to edit
+ /etc/modprobe.conf to ensure that the aoe module is loaded when
+ necessary.
+
+USING DEVICE NODES
+
+ "cat /dev/etherd/err" blocks, waiting for error diagnostic output,
+ like any retransmitted packets.
+
+ "echo eth2 eth4 > /dev/etherd/interfaces" tells the aoe driver to
+ limit ATA over Ethernet traffic to eth2 and eth4. AoE traffic from
+ untrusted networks should be ignored as a matter of security.
+
+ "echo > /dev/etherd/discover" tells the driver to find out what AoE
+ devices are available.
+
+ The block devices are named like this:
+
+ e{shelf}.{slot}
+ e{shelf}.{slot}p{part}
+
+ ... so that "e0.2" is the third blade from the left (slot 2) in the
+ first shelf (shelf address zero). That's the whole disk. The first
+ partition on that disk would be "e0.2p1".
+
+USING SYSFS
+
+ Each aoe block device in /sys/block has the extra attributes of
+ state, mac, and netif. The state attribute is "up" when the device
+ is ready for I/O and "down" if detected but unusable. The
+ "down,closewait" state shows that the device is still open and
+ cannot come up again until it has been closed.
+
+ The mac attribute is the ethernet address of the remote AoE device.
+ The netif attribute is the network interface on the localhost
+ through which we are communicating with the remote AoE device.
+
+ There is a script in this directory that formats this information
+ in a convenient way.
+
+ root@makki linux# sh Documentation/aoe/status.sh
+ device mac netif state
+ e6.0 0010040010c6 eth0 up
+ e6.1 001004001067 eth0 up
+ e6.2 001004001068 eth0 up
+ e6.3 001004001065 eth0 up
+ e6.4 001004001066 eth0 up
+ e6.5 0010040010c7 eth0 up
+ e6.6 0010040010c8 eth0 up
+ e6.7 0010040010c9 eth0 up
+ e6.8 0010040010ca eth0 up
+ e6.9 0010040010cb eth0 up
+ e9.0 001004000020 eth1 up
+ e9.5 001004000025 eth1 up
+ e9.9 001004000029 eth1 up
+
diff -Nru a/Documentation/aoe/autoload.sh b/Documentation/aoe/autoload.sh
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/autoload.sh 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,17 @@
+#!/bin/sh
+# set aoe to autoload by installing the
+# aliases in /etc/modprobe.conf
+
+f=/etc/modprobe.conf
+
+if test ! -r $f || test ! -w $f; then
+ echo "cannot configure $f for module autoloading" 1>&2
+ exit 1
+fi
+
+grep major-152 $f >/dev/null
+if [ $? = 1 ]; then
+ echo alias block-major-152 aoe >> $f
+ echo alias char-major-152 aoe >> $f
+fi
+
diff -Nru a/Documentation/aoe/mkdevs.sh b/Documentation/aoe/mkdevs.sh
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/mkdevs.sh 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+n_shelves=10
+
+if test "$#" != "1"; then
+ echo "Usage: sh mkdevs.sh {dir}" 1>&2
+ exit 1
+fi
+dir=$1
+
+MAJOR=152
+
+echo "Creating AoE devnode files in $dir ..."
+
+set -e
+
+mkdir -p $dir
+
+# (Status info is in sysfs. See status.sh.)
+# rm -f $dir/stat
+# mknod -m 0400 $dir/stat c $MAJOR 1
+rm -f $dir/err
+mknod -m 0400 $dir/err c $MAJOR 2
+rm -f $dir/discover
+mknod -m 0200 $dir/discover c $MAJOR 3
+rm -f $dir/interfaces
+mknod -m 0200 $dir/interfaces c $MAJOR 4
+
+i=0
+while test $i -lt $n_shelves; do
+ sh -xc "sh `dirname $0`/mkshelf.sh $dir $i"
+ i=`expr $i + 1`
+done
diff -Nru a/Documentation/aoe/mkshelf.sh b/Documentation/aoe/mkshelf.sh
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/mkshelf.sh 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,23 @@
+#! /bin/sh
+
+if test "$#" != "2"; then
+ echo "Usage: sh mkshelf.sh {dir} {shelfaddress}" 1>&2
+ exit 1
+fi
+dir=$1
+shelf=$2
+MAJOR=152
+
+set -e
+
+minor=`echo 10 \* $shelf \* 16 | bc`
+for slot in `seq 0 9`; do
+ for part in `seq 0 15`; do
+ name=e$shelf.$slot
+ test "$part" != "0" && name=${name}p$part
+ rm -f $dir/$name
+ mknod -m 0660 $dir/$name b $MAJOR $minor
+
+ minor=`expr $minor + 1`
+ done
+done
diff -Nru a/Documentation/aoe/status.sh b/Documentation/aoe/status.sh
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/status.sh 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,15 @@
+# collate and present sysfs information about AoE storage
+
+set -e
+format="%8s\t%12s\t%8s\t%8s\n"
+
+printf "$format" device mac netif state
+
+for d in `ls -d /sys/block/etherd* | grep -v p`; do
+ dev=`echo "$d" | sed 's/.*!//'`
+ printf "$format" \
+ "$dev" \
+ "`cat \"$d/mac\"`" \
+ "`cat \"$d/netif\"`" \
+ "`cat \"$d/state\"`"
+done | sort
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS 2005-01-07 15:45:50 -08:00
+++ b/MAINTAINERS 2005-01-07 15:45:50 -08:00
@@ -328,6 +328,12 @@
W: http://julien.lerouge.free.fr
S: Maintained
+ATA OVER ETHERNET DRIVER
+P: Ed L. Cashin
+M: [email protected]
+W: http://www.coraid.com/support/linux
+S: Supported
+
ATM
P: Chas Williams
M: [email protected]
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile 2005-01-07 15:45:50 -08:00
+++ b/drivers/Makefile 2005-01-07 15:45:50 -08:00
@@ -42,6 +42,7 @@
obj-$(CONFIG_SBUS) += sbus/
obj-$(CONFIG_ZORRO) += zorro/
obj-$(CONFIG_MAC) += macintosh/
+obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/
obj-$(CONFIG_PARIDE) += block/paride/
obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_USB) += usb/
diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig
--- a/drivers/block/Kconfig 2005-01-07 15:45:50 -08:00
+++ b/drivers/block/Kconfig 2005-01-07 15:45:50 -08:00
@@ -429,4 +429,12 @@
source "drivers/block/Kconfig.iosched"
+config ATA_OVER_ETH
+ tristate "ATA over Ethernet support"
+ depends on NET
+ default m
+ help
+ This driver provides Support for ATA over Ethernet block
+ devices like the Coraid EtherDrive (R) Storage Blade.
+
endmenu
diff -Nru a/drivers/block/aoe/Makefile b/drivers/block/aoe/Makefile
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/Makefile 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,6 @@
+#
+# Makefile for ATA over Ethernet
+#
+
+obj-$(CONFIG_ATA_OVER_ETH) += aoe.o
+aoe-objs := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o
diff -Nru a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoe.h 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,163 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+#define VERSION "4"
+#define AOE_MAJOR 152
+#define DEVICE_NAME "aoe"
+#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor))
+#define AOEMAJOR(sysminor) ((sysminor) / 10)
+#define AOEMINOR(sysminor) ((sysminor) % 10)
+#define WHITESPACE " \t\v\f\n"
+
+enum {
+ AOECMD_ATA,
+ AOECMD_CFG,
+
+ AOEFL_RSP = (1<<3),
+ AOEFL_ERR = (1<<2),
+
+ AOEAFL_EXT = (1<<6),
+ AOEAFL_DEV = (1<<4),
+ AOEAFL_ASYNC = (1<<1),
+ AOEAFL_WRITE = (1<<0),
+
+ AOECCMD_READ = 0,
+ AOECCMD_TEST,
+ AOECCMD_PTEST,
+ AOECCMD_SET,
+ AOECCMD_FSET,
+
+ AOE_HVER = 0x10,
+ ETH_P_AOE = 0x88a2,
+};
+
+struct aoe_hdr {
+ unsigned char dst[6];
+ unsigned char src[6];
+ unsigned char type[2];
+ unsigned char verfl;
+ unsigned char err;
+ unsigned char major[2];
+ unsigned char minor;
+ unsigned char cmd;
+ unsigned char tag[4];
+};
+
+struct aoe_atahdr {
+ unsigned char aflags;
+ unsigned char errfeat;
+ unsigned char scnt;
+ unsigned char cmdstat;
+ unsigned char lba0;
+ unsigned char lba1;
+ unsigned char lba2;
+ unsigned char lba3;
+ unsigned char lba4;
+ unsigned char lba5;
+ unsigned char res[2];
+};
+
+struct aoe_cfghdr {
+ unsigned char bufcnt[2];
+ unsigned char fwver[2];
+ unsigned char res;
+ unsigned char aoeccmd;
+ unsigned char cslen[2];
+};
+
+enum {
+ DEVFL_UP = 1, /* device is installed in system and ready for AoE->ATA commands */
+ DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */
+ DEVFL_EXT = (1<<2), /* device accepts lba48 commands */
+ DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */
+ DEVFL_WC_UPDATE = (1<<4), /* this device needs to update write cache status */
+ DEVFL_WORKON = (1<<4),
+
+ BUFFL_FAIL = 1,
+};
+
+enum {
+ MAXATADATA = 1024,
+ NPERSHELF = 10,
+ FREETAG = -1,
+ MIN_BUFS = 8,
+};
+
+struct buf {
+ struct list_head bufs;
+ ulong flags;
+ ulong nframesout;
+ char *bufaddr;
+ ulong resid;
+ ulong bv_resid;
+ sector_t sector;
+ struct bio *bio;
+ struct bio_vec *bv;
+};
+
+struct frame {
+ int tag;
+ ulong waited;
+ struct buf *buf;
+ char *bufaddr;
+ int writedatalen;
+ int ndata;
+
+ /* largest possible */
+ char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
+};
+
+struct aoedev {
+ struct aoedev *next;
+ unsigned char addr[6]; /* remote mac addr */
+ ushort flags;
+ ulong sysminor;
+ ulong aoemajor;
+ ulong aoeminor;
+ ulong rttavg; /* round trip average of requests/responses */
+ u16 fw_ver; /* version of blade's firmware */
+ struct work_struct work;/* disk create work struct */
+ struct gendisk *gd;
+ request_queue_t blkq;
+ struct hd_geometry geo;
+ sector_t ssize;
+ struct timer_list timer;
+ spinlock_t lock;
+ struct net_device *ifp; /* interface ed is attached to */
+ struct sk_buff *skblist;/* packets needing to be sent */
+ mempool_t *bufpool; /* for deadlock-free Buf allocation */
+ struct list_head bufq; /* queue of bios to work on */
+ struct buf *inprocess; /* the one we're currently working on */
+ ulong lasttag; /* last tag sent */
+ ulong nframes; /* number of frames below */
+ struct frame *frames;
+};
+
+
+int aoeblk_init(void);
+void aoeblk_exit(void);
+void aoeblk_gdalloc(void *);
+void aoedisk_rm_sysfs(struct aoedev *d);
+
+int aoechr_init(void);
+void aoechr_exit(void);
+void aoechr_error(char *);
+void aoechr_hdump(char *, int len);
+
+void aoecmd_work(struct aoedev *d);
+void aoecmd_cfg(ushort, unsigned char);
+void aoecmd_ata_rsp(struct sk_buff *);
+void aoecmd_cfg_rsp(struct sk_buff *);
+
+int aoedev_init(void);
+void aoedev_exit(void);
+struct aoedev *aoedev_bymac(unsigned char *);
+void aoedev_downdev(struct aoedev *d);
+struct aoedev *aoedev_set(ulong, unsigned char *, struct net_device *, ulong);
+int aoedev_busy(void);
+
+int aoenet_init(void);
+void aoenet_exit(void);
+void aoenet_xmit(struct sk_buff *);
+int is_aoe_netif(struct net_device *ifp);
+int set_aoe_iflist(char *str);
+
+u64 mac_addr(char addr[6]);
diff -Nru a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoeblk.c 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,251 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoeblk.c
+ * block device routines
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/genhd.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+/* add attributes for our block devices in sysfs
+ * (see drivers/block/genhd.c:disk_attr_show, etc.)
+ */
+struct disk_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct gendisk *, char *);
+};
+
+static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
+{
+ struct aoedev *d = disk->private_data;
+
+ return snprintf(page, PAGE_SIZE,
+ "%s%s\n",
+ (d->flags & DEVFL_UP) ? "up" : "down",
+ (d->flags & DEVFL_CLOSEWAIT) ? ",closewait" : "");
+}
+static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page)
+{
+ struct aoedev *d = disk->private_data;
+
+ return snprintf(page, PAGE_SIZE, "%012llx\n", mac_addr(d->addr));
+}
+static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page)
+{
+ struct aoedev *d = disk->private_data;
+
+ return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name);
+}
+
+static struct disk_attribute disk_attr_state = {
+ .attr = {.name = "state", .mode = S_IRUGO },
+ .show = aoedisk_show_state
+};
+static struct disk_attribute disk_attr_mac = {
+ .attr = {.name = "mac", .mode = S_IRUGO },
+ .show = aoedisk_show_mac
+};
+static struct disk_attribute disk_attr_netif = {
+ .attr = {.name = "netif", .mode = S_IRUGO },
+ .show = aoedisk_show_netif
+};
+
+static void
+aoedisk_add_sysfs(struct aoedev *d)
+{
+ sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
+ sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
+ sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
+}
+void
+aoedisk_rm_sysfs(struct aoedev *d)
+{
+ sysfs_remove_link(&d->gd->kobj, "state");
+ sysfs_remove_link(&d->gd->kobj, "mac");
+ sysfs_remove_link(&d->gd->kobj, "netif");
+}
+
+static int
+aoeblk_open(struct inode *inode, struct file *filp)
+{
+ struct aoedev *d;
+
+ d = inode->i_bdev->bd_disk->private_data;
+ return (d->flags & DEVFL_UP) ? 0 : -ENODEV;
+}
+
+static int
+aoeblk_release(struct inode *inode, struct file *filp)
+{
+ struct aoedev *d;
+ ulong flags;
+
+ d = inode->i_bdev->bd_disk->private_data;
+
+ spin_lock_irqsave(&d->lock, flags);
+
+ if (inode->i_bdev->bd_openers == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
+ d->flags &= ~DEVFL_CLOSEWAIT;
+ spin_unlock_irqrestore(&d->lock, flags);
+ aoecmd_cfg(d->aoemajor, d->aoeminor);
+ return 0;
+ }
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ return 0;
+}
+
+static int
+aoeblk_make_request(request_queue_t *q, struct bio *bio)
+{
+ struct aoedev *d;
+ struct buf *buf;
+ struct sk_buff *sl;
+ ulong flags;
+
+ blk_queue_bounce(q, &bio);
+
+ d = bio->bi_bdev->bd_disk->private_data;
+ buf = mempool_alloc(d->bufpool, GFP_NOIO);
+ if (buf == NULL) {
+ printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation "
+ "failure\n");
+ bio_endio(bio, bio->bi_size, -ENOMEM);
+ return 0;
+ }
+ memset(buf, 0, sizeof(*buf));
+ INIT_LIST_HEAD(&buf->bufs);
+ buf->bio = bio;
+ buf->resid = bio->bi_size;
+ buf->sector = bio->bi_sector;
+ buf->bv = buf->bio->bi_io_vec;
+ buf->bv_resid = buf->bv->bv_len;
+ buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
+
+ spin_lock_irqsave(&d->lock, flags);
+
+ if ((d->flags & DEVFL_UP) == 0) {
+ printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n",
+ d->aoemajor, d->aoeminor);
+ spin_unlock_irqrestore(&d->lock, flags);
+ mempool_free(buf, d->bufpool);
+ bio_endio(bio, bio->bi_size, -ENXIO);
+ return 0;
+ }
+
+ list_add_tail(&buf->bufs, &d->bufq);
+ aoecmd_work(d);
+
+ sl = d->skblist;
+ d->skblist = NULL;
+
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ aoenet_xmit(sl);
+ return 0;
+}
+
+/* This ioctl implementation expects userland to have the device node
+ * permissions set so that only priviledged users can open an aoe
+ * block device directly.
+ */
+static int
+aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg)
+{
+ struct aoedev *d;
+
+ if (!arg)
+ return -EINVAL;
+
+ d = inode->i_bdev->bd_disk->private_data;
+ if ((d->flags & DEVFL_UP) == 0) {
+ printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
+ return -ENODEV;
+ }
+
+ if (cmd == HDIO_GETGEO) {
+ d->geo.start = get_start_sect(inode->i_bdev);
+ if (!copy_to_user((void *) arg, &d->geo, sizeof d->geo))
+ return 0;
+ return -EFAULT;
+ }
+ printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);
+ return -EINVAL;
+}
+
+static struct block_device_operations aoe_bdops = {
+ .open = aoeblk_open,
+ .release = aoeblk_release,
+ .ioctl = aoeblk_ioctl,
+ .owner = THIS_MODULE,
+};
+
+/* alloc_disk and add_disk can sleep */
+void
+aoeblk_gdalloc(void *vp)
+{
+ struct aoedev *d = vp;
+ struct gendisk *gd;
+ ulong flags;
+ enum { NPARTITIONS = 16 };
+
+ gd = alloc_disk(NPARTITIONS);
+
+ spin_lock_irqsave(&d->lock, flags);
+
+ if (gd == NULL) {
+ printk(KERN_CRIT "aoe: aoeblk_gdalloc: cannot allocate disk "
+ "structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
+ d->flags &= ~DEVFL_WORKON;
+ spin_unlock_irqrestore(&d->lock, flags);
+ return;
+ }
+
+ blk_queue_make_request(&d->blkq, aoeblk_make_request);
+ gd->major = AOE_MAJOR;
+ gd->first_minor = d->sysminor * NPARTITIONS;
+ gd->fops = &aoe_bdops;
+ gd->private_data = d;
+ gd->capacity = d->ssize;
+ snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%ld",
+ d->aoemajor, d->aoeminor);
+
+ gd->queue = &d->blkq;
+ d->gd = gd;
+ d->flags &= ~DEVFL_WORKON;
+ d->flags |= DEVFL_UP;
+
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ add_disk(gd);
+ aoedisk_add_sysfs(d);
+
+ printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
+ "sectors\n", mac_addr(d->addr), d->aoemajor, d->aoeminor,
+ d->fw_ver, d->ssize);
+}
+
+void __exit
+aoeblk_exit(void)
+{
+ unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
+}
+
+int __init
+aoeblk_init(void)
+{
+ int n;
+
+ n = register_blkdev(AOE_MAJOR, DEVICE_NAME);
+ if (n < 0) {
+ printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
+ return n;
+ }
+ return 0;
+}
+
diff -Nru a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoechr.c 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,295 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoechr.c
+ * AoE character device driver
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include "aoe.h"
+
+enum {
+ //MINOR_STAT = 1, (moved to sysfs)
+ MINOR_ERR = 2,
+ MINOR_DISCOVER,
+ MINOR_INTERFACES,
+ MSGSZ = 2048,
+ NARGS = 10,
+ NMSG = 100, /* message backlog to retain */
+};
+
+struct aoe_chardev {
+ ulong minor;
+ char name[32];
+};
+
+enum { EMFL_VALID = 1 };
+
+struct ErrMsg {
+ short flags;
+ short len;
+ char *msg;
+};
+
+static struct ErrMsg emsgs[NMSG];
+static int emsgs_head_idx, emsgs_tail_idx;
+static struct semaphore emsgs_sema;
+static spinlock_t emsgs_lock;
+static int nblocked_emsgs_readers;
+static struct class_simple *aoe_class;
+static struct aoe_chardev chardevs[] = {
+ { MINOR_ERR, "err" },
+ { MINOR_DISCOVER, "discover" },
+ { MINOR_INTERFACES, "interfaces" },
+};
+
+static int
+discover(void)
+{
+ aoecmd_cfg(0xffff, 0xff);
+ return 0;
+}
+
+static int
+interfaces(char *str)
+{
+ if (set_aoe_iflist(str)) {
+ printk(KERN_CRIT
+ "%s: could not set interface list: %s\n",
+ __FUNCTION__, "too many interfaces");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void
+aoechr_error(char *msg)
+{
+ struct ErrMsg *em;
+ char *mp;
+ ulong flags, n;
+
+ n = strlen(msg);
+
+ spin_lock_irqsave(&emsgs_lock, flags);
+
+ em = emsgs + emsgs_tail_idx;
+ if ((em->flags & EMFL_VALID)) {
+bail: spin_unlock_irqrestore(&emsgs_lock, flags);
+ return;
+ }
+
+ mp = kmalloc(n, GFP_ATOMIC);
+ if (mp == NULL) {
+ printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n);
+ goto bail;
+ }
+
+ memcpy(mp, msg, n);
+ em->msg = mp;
+ em->flags |= EMFL_VALID;
+ em->len = n;
+
+ emsgs_tail_idx++;
+ emsgs_tail_idx %= ARRAY_SIZE(emsgs);
+
+ spin_unlock_irqrestore(&emsgs_lock, flags);
+
+ if (nblocked_emsgs_readers)
+ up(&emsgs_sema);
+}
+
+#define PERLINE 16
+void
+aoechr_hdump(char *buf, int n)
+{
+ int bufsiz;
+ char *fbuf;
+ int linelen;
+ char *p, *e, *fp;
+
+ bufsiz = n * 3; /* 2 hex digits and a space */
+ bufsiz += n / PERLINE + 1; /* the newline characters */
+ bufsiz += 1; /* the final '\0' */
+
+ fbuf = kmalloc(bufsiz, GFP_ATOMIC);
+ if (!fbuf) {
+ printk(KERN_INFO
+ "%s: cannot allocate memory\n",
+ __FUNCTION__);
+ return;
+ }
+
+ for (p = buf; n <= 0;) {
+ linelen = n > PERLINE ? PERLINE : n;
+ n -= linelen;
+
+ fp = fbuf;
+ for (e=p+linelen; p<e; p++)
+ fp += sprintf(fp, "%2.2X ", *p & 255);
+ sprintf(fp, "\n");
+ aoechr_error(fbuf);
+ }
+
+ kfree(fbuf);
+}
+
+static ssize_t
+aoechr_write(struct file *filp, const char *buf, size_t cnt, loff_t *offp)
+{
+ char *str = kcalloc(1, cnt+1, GFP_KERNEL);
+ int ret;
+
+ if (!str) {
+ printk(KERN_CRIT "aoe: aoechr_write: cannot allocate memory\n");
+ return -ENOMEM;
+ }
+
+ ret = -EFAULT;
+ if (copy_from_user(str, buf, cnt)) {
+ printk(KERN_INFO "aoe: aoechr_write: copy from user failed\n");
+ goto out;
+ }
+
+ str[cnt] = '\0';
+ ret = -EINVAL;
+ switch ((unsigned long) filp->private_data) {
+ default:
+ printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n");
+ break;
+ case MINOR_DISCOVER:
+ ret = discover();
+ break;
+ case MINOR_INTERFACES:
+ ret = interfaces(str);
+ break;
+ }
+ if (ret == 0)
+ ret = cnt;
+ out:
+ kfree(str);
+ return ret;
+}
+
+static int
+aoechr_open(struct inode *inode, struct file *filp)
+{
+ int n, i;
+
+ n = MINOR(inode->i_rdev);
+ filp->private_data = (void *) (unsigned long) n;
+
+ for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
+ if (chardevs[i].minor == n)
+ return 0;
+ return -EINVAL;
+}
+
+static int
+aoechr_rel(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static ssize_t
+aoechr_read(struct file *filp, char *buf, size_t cnt, loff_t *off)
+{
+ int n;
+ char *mp;
+ struct ErrMsg *em;
+ ssize_t len;
+ ulong flags;
+
+ n = (int) filp->private_data;
+ switch (n) {
+ case MINOR_ERR:
+ spin_lock_irqsave(&emsgs_lock, flags);
+loop:
+ em = emsgs + emsgs_head_idx;
+ if ((em->flags & EMFL_VALID) == 0) {
+ if (filp->f_flags & O_NDELAY) {
+ spin_unlock_irqrestore(&emsgs_lock, flags);
+ return -EAGAIN;
+ }
+ nblocked_emsgs_readers++;
+
+ spin_unlock_irqrestore(&emsgs_lock, flags);
+
+ n = down_interruptible(&emsgs_sema);
+
+ spin_lock_irqsave(&emsgs_lock, flags);
+
+ nblocked_emsgs_readers--;
+
+ if (n) {
+ spin_unlock_irqrestore(&emsgs_lock, flags);
+ return -ERESTARTSYS;
+ }
+ goto loop;
+ }
+ if (em->len > cnt) {
+ spin_unlock_irqrestore(&emsgs_lock, flags);
+ return -EAGAIN;
+ }
+ mp = em->msg;
+ len = em->len;
+ em->msg = NULL;
+ em->flags &= ~EMFL_VALID;
+
+ emsgs_head_idx++;
+ emsgs_head_idx %= ARRAY_SIZE(emsgs);
+
+ spin_unlock_irqrestore(&emsgs_lock, flags);
+
+ n = copy_to_user(buf, mp, len);
+ kfree(mp);
+ return n == 0 ? len : -EFAULT;
+ default:
+ return -EFAULT;
+ }
+}
+
+struct file_operations aoe_fops = {
+ .write = aoechr_write,
+ .read = aoechr_read,
+ .open = aoechr_open,
+ .release = aoechr_rel,
+ .owner = THIS_MODULE,
+};
+
+int __init
+aoechr_init(void)
+{
+ int n, i;
+
+ n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops);
+ if (n < 0) {
+ printk(KERN_ERR "aoe: aoechr_init: can't register char device\n");
+ return n;
+ }
+ sema_init(&emsgs_sema, 0);
+ spin_lock_init(&emsgs_lock);
+ aoe_class = class_simple_create(THIS_MODULE, "aoe");
+ if (IS_ERR(aoe_class)) {
+ unregister_chrdev(AOE_MAJOR, "aoechr");
+ return PTR_ERR(aoe_class);
+ }
+ for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
+ class_simple_device_add(aoe_class,
+ MKDEV(AOE_MAJOR, chardevs[i].minor),
+ NULL, chardevs[i].name);
+
+ return 0;
+}
+
+void __exit
+aoechr_exit(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
+ class_simple_device_remove(MKDEV(AOE_MAJOR, chardevs[i].minor));
+ class_simple_destroy(aoe_class);
+ unregister_chrdev(AOE_MAJOR, "aoechr");
+}
+
diff -Nru a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoecmd.c 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,627 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoecmd.c
+ * Filesystem request handling methods
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+#define TIMERTICK (HZ / 10)
+#define MINTIMER (2 * TIMERTICK)
+#define MAXTIMER (HZ << 1)
+#define MAXWAIT (60 * 3) /* After MAXWAIT seconds, give up and fail dev */
+
+static struct sk_buff *
+new_skb(struct net_device *if_dev, ulong len)
+{
+ struct sk_buff *skb;
+
+ skb = alloc_skb(len, GFP_ATOMIC);
+ if (skb) {
+ skb->nh.raw = skb->mac.raw = skb->data;
+ skb->dev = if_dev;
+ skb->protocol = __constant_htons(ETH_P_AOE);
+ skb->priority = 0;
+ skb_put(skb, len);
+ skb->next = skb->prev = NULL;
+
+ /* tell the network layer not to perform IP checksums
+ * or to get the NIC to do it
+ */
+ skb->ip_summed = CHECKSUM_NONE;
+ }
+ return skb;
+}
+
+static struct sk_buff *
+skb_prepare(struct aoedev *d, struct frame *f)
+{
+ struct sk_buff *skb;
+ char *p;
+
+ skb = new_skb(d->ifp, f->ndata + f->writedatalen);
+ if (!skb) {
+ printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
+ return NULL;
+ }
+
+ p = skb->mac.raw;
+ memcpy(p, f->data, f->ndata);
+
+ if (f->writedatalen) {
+ p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
+ memcpy(p, f->bufaddr, f->writedatalen);
+ }
+
+ return skb;
+}
+
+static struct frame *
+getframe(struct aoedev *d, int tag)
+{
+ struct frame *f, *e;
+
+ f = d->frames;
+ e = f + d->nframes;
+ for (; f<e; f++)
+ if (f->tag == tag)
+ return f;
+ return NULL;
+}
+
+/*
+ * Leave the top bit clear so we have tagspace for userland.
+ * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
+ * This driver reserves tag -1 to mean "unused frame."
+ */
+static int
+newtag(struct aoedev *d)
+{
+ register ulong n;
+
+ n = jiffies & 0xffff;
+ return n |= (++d->lasttag & 0x7fff) << 16;
+}
+
+static int
+aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
+{
+ u16 type = __constant_cpu_to_be16(ETH_P_AOE);
+ u16 aoemajor = __cpu_to_be16(d->aoemajor);
+ u32 host_tag = newtag(d);
+ u32 tag = __cpu_to_be32(host_tag);
+
+ memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
+ memcpy(h->dst, d->addr, sizeof h->dst);
+ memcpy(h->type, &type, sizeof type);
+ h->verfl = AOE_HVER;
+ memcpy(h->major, &aoemajor, sizeof aoemajor);
+ h->minor = d->aoeminor;
+ h->cmd = AOECMD_ATA;
+ memcpy(h->tag, &tag, sizeof tag);
+
+ return host_tag;
+}
+
+static void
+aoecmd_ata_rw(struct aoedev *d, struct frame *f)
+{
+ struct aoe_hdr *h;
+ struct aoe_atahdr *ah;
+ struct buf *buf;
+ struct sk_buff *skb;
+ ulong bcnt;
+ register sector_t sector;
+ char writebit, extbit;
+
+ writebit = 0x10;
+ extbit = 0x4;
+
+ buf = d->inprocess;
+
+ sector = buf->sector;
+ bcnt = buf->bv_resid;
+ if (bcnt > MAXATADATA)
+ bcnt = MAXATADATA;
+
+ /* initialize the headers & frame */
+ h = (struct aoe_hdr *) f->data;
+ ah = (struct aoe_atahdr *) (h+1);
+ f->ndata = sizeof *h + sizeof *ah;
+ memset(h, 0, f->ndata);
+ f->tag = aoehdr_atainit(d, h);
+ f->waited = 0;
+ f->buf = buf;
+ f->bufaddr = buf->bufaddr;
+
+ /* set up ata header */
+ ah->scnt = bcnt >> 9;
+ ah->lba0 = sector;
+ ah->lba1 = sector >>= 8;
+ ah->lba2 = sector >>= 8;
+ ah->lba3 = sector >>= 8;
+ if (d->flags & DEVFL_EXT) {
+ ah->aflags |= AOEAFL_EXT;
+ ah->lba4 = sector >>= 8;
+ ah->lba5 = sector >>= 8;
+ } else {
+ extbit = 0;
+ ah->lba3 &= 0x0f;
+ ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */
+ }
+
+ if (bio_data_dir(buf->bio) == WRITE) {
+ ah->aflags |= AOEAFL_WRITE;
+ f->writedatalen = bcnt;
+ } else {
+ writebit = 0;
+ f->writedatalen = 0;
+ }
+
+ ah->cmdstat = WIN_READ | writebit | extbit;
+
+ /* mark all tracking fields and load out */
+ buf->nframesout += 1;
+ buf->bufaddr += bcnt;
+ buf->bv_resid -= bcnt;
+/* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
+ buf->resid -= bcnt;
+ buf->sector += bcnt >> 9;
+ if (buf->resid == 0) {
+ d->inprocess = NULL;
+ } else if (buf->bv_resid == 0) {
+ buf->bv++;
+ buf->bv_resid = buf->bv->bv_len;
+ buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
+ }
+
+ skb = skb_prepare(d, f);
+ if (skb) {
+ skb->next = d->skblist;
+ d->skblist = skb;
+ }
+}
+
+/* enters with d->lock held */
+void
+aoecmd_work(struct aoedev *d)
+{
+ struct frame *f;
+ struct buf *buf;
+loop:
+ f = getframe(d, FREETAG);
+ if (f == NULL)
+ return;
+ if (d->inprocess == NULL) {
+ if (list_empty(&d->bufq))
+ return;
+ buf = container_of(d->bufq.next, struct buf, bufs);
+ list_del(d->bufq.next);
+/*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
+ d->inprocess = buf;
+ }
+ aoecmd_ata_rw(d, f);
+ goto loop;
+}
+
+static void
+rexmit(struct aoedev *d, struct frame *f)
+{
+ struct sk_buff *skb;
+ struct aoe_hdr *h;
+ char buf[128];
+ u32 n;
+ u32 net_tag;
+
+ n = newtag(d);
+
+ snprintf(buf, sizeof buf,
+ "%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08x\n",
+ "retransmit",
+ d->aoemajor, d->aoeminor, f->tag, jiffies, n);
+ aoechr_error(buf);
+
+ h = (struct aoe_hdr *) f->data;
+ f->tag = n;
+ net_tag = __cpu_to_be32(n);
+ memcpy(h->tag, &net_tag, sizeof net_tag);
+
+ skb = skb_prepare(d, f);
+ if (skb) {
+ skb->next = d->skblist;
+ d->skblist = skb;
+ }
+}
+
+static int
+tsince(int tag)
+{
+ int n;
+
+ n = jiffies & 0xffff;
+ n -= tag & 0xffff;
+ if (n < 0)
+ n += 1<<16;
+ return n;
+}
+
+static void
+rexmit_timer(ulong vp)
+{
+ struct aoedev *d;
+ struct frame *f, *e;
+ struct sk_buff *sl;
+ register long timeout;
+ ulong flags, n;
+
+ d = (struct aoedev *) vp;
+ sl = NULL;
+
+ /* timeout is always ~150% of the moving average */
+ timeout = d->rttavg;
+ timeout += timeout >> 1;
+
+ spin_lock_irqsave(&d->lock, flags);
+
+ if (d->flags & DEVFL_TKILL) {
+tdie: spin_unlock_irqrestore(&d->lock, flags);
+ return;
+ }
+ f = d->frames;
+ e = f + d->nframes;
+ for (; f<e; f++) {
+ if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
+ n = f->waited += timeout;
+ n /= HZ;
+ if (n > MAXWAIT) { /* waited too long. device failure. */
+ aoedev_downdev(d);
+ goto tdie;
+ }
+ rexmit(d, f);
+ }
+ }
+
+ sl = d->skblist;
+ d->skblist = NULL;
+ if (sl) {
+ n = d->rttavg <<= 1;
+ if (n > MAXTIMER)
+ d->rttavg = MAXTIMER;
+ }
+
+ d->timer.expires = jiffies + TIMERTICK;
+ add_timer(&d->timer);
+
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ aoenet_xmit(sl);
+}
+
+static void
+ataid_complete(struct aoedev *d, unsigned char *id)
+{
+ u64 ssize;
+ u16 n;
+
+ /* word 83: command set supported */
+ n = __le16_to_cpu(*((u16 *) &id[83<<1]));
+
+ /* word 86: command set/feature enabled */
+ n |= __le16_to_cpu(*((u16 *) &id[86<<1]));
+
+ if (n & (1<<10)) { /* bit 10: LBA 48 */
+ d->flags |= DEVFL_EXT;
+
+ /* word 100: number lba48 sectors */
+ ssize = __le64_to_cpu(*((u64 *) &id[100<<1]));
+
+ /* set as in ide-disk.c:init_idedisk_capacity */
+ d->geo.cylinders = ssize;
+ d->geo.cylinders /= (255 * 63);
+ d->geo.heads = 255;
+ d->geo.sectors = 63;
+ } else {
+ d->flags &= ~DEVFL_EXT;
+
+ /* number lba28 sectors */
+ ssize = __le32_to_cpu(*((u32 *) &id[60<<1]));
+
+ /* NOTE: obsolete in ATA 6 */
+ d->geo.cylinders = __le16_to_cpu(*((u16 *) &id[54<<1]));
+ d->geo.heads = __le16_to_cpu(*((u16 *) &id[55<<1]));
+ d->geo.sectors = __le16_to_cpu(*((u16 *) &id[56<<1]));
+ }
+ d->ssize = ssize;
+ d->geo.start = 0;
+ if (d->gd != NULL) {
+ d->gd->capacity = ssize;
+ d->flags |= DEVFL_UP;
+ return;
+ }
+ if (d->flags & DEVFL_WORKON) {
+ printk(KERN_INFO "aoe: ataid_complete: can't schedule work, it's already on! "
+ "(This really shouldn't happen).\n");
+ return;
+ }
+ INIT_WORK(&d->work, aoeblk_gdalloc, d);
+ schedule_work(&d->work);
+ d->flags |= DEVFL_WORKON;
+}
+
+static void
+calc_rttavg(struct aoedev *d, int rtt)
+{
+ register long n;
+
+ n = rtt;
+ if (n < MINTIMER)
+ n = MINTIMER;
+ else if (n > MAXTIMER)
+ n = MAXTIMER;
+
+ /* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
+ n -= d->rttavg;
+ d->rttavg += n >> 2;
+}
+
+void
+aoecmd_ata_rsp(struct sk_buff *skb)
+{
+ struct aoedev *d;
+ struct aoe_hdr *hin;
+ struct aoe_atahdr *ahin, *ahout;
+ struct frame *f;
+ struct buf *buf;
+ struct sk_buff *sl;
+ register long n;
+ ulong flags;
+ char ebuf[128];
+
+ hin = (struct aoe_hdr *) skb->mac.raw;
+ d = aoedev_bymac(hin->src);
+ if (d == NULL) {
+ snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
+ "for unknown device %d.%d\n",
+ __be16_to_cpu(*((u16 *) hin->major)),
+ hin->minor);
+ aoechr_error(ebuf);
+ return;
+ }
+
+ spin_lock_irqsave(&d->lock, flags);
+
+ f = getframe(d, __be32_to_cpu(*((u32 *) hin->tag)));
+ if (f == NULL) {
+ spin_unlock_irqrestore(&d->lock, flags);
+ snprintf(ebuf, sizeof ebuf,
+ "%15s e%d.%d tag=%08x@%08lx\n",
+ "unexpected rsp",
+ __be16_to_cpu(*((u16 *) hin->major)),
+ hin->minor,
+ __be32_to_cpu(*((u32 *) hin->tag)),
+ jiffies);
+ aoechr_error(ebuf);
+ return;
+ }
+
+ calc_rttavg(d, tsince(f->tag));
+
+ ahin = (struct aoe_atahdr *) (hin+1);
+ ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
+ buf = f->buf;
+
+ if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
+ printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
+ "stat=%2.2Xh\n", ahout->cmdstat, ahin->cmdstat);
+ if (buf)
+ buf->flags |= BUFFL_FAIL;
+ } else {
+ switch (ahout->cmdstat) {
+ case WIN_READ:
+ case WIN_READ_EXT:
+ n = ahout->scnt << 9;
+ if (skb->len - sizeof *hin - sizeof *ahin < n) {
+ printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
+ "ata data size in read. skb->len=%d\n",
+ skb->len);
+ /* fail frame f? just returning will rexmit. */
+ spin_unlock_irqrestore(&d->lock, flags);
+ return;
+ }
+ memcpy(f->bufaddr, ahin+1, n);
+ case WIN_WRITE:
+ case WIN_WRITE_EXT:
+ break;
+ case WIN_IDENTIFY:
+ if (skb->len - sizeof *hin - sizeof *ahin < 512) {
+ printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
+ "in ataid. skb->len=%d\n", skb->len);
+ spin_unlock_irqrestore(&d->lock, flags);
+ return;
+ }
+ ataid_complete(d, (char *) (ahin+1));
+ /* d->flags |= DEVFL_WC_UPDATE; */
+ break;
+ default:
+ printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
+ "outbound ata command %2.2Xh for %d.%d\n",
+ ahout->cmdstat,
+ __be16_to_cpu(*((u16 *) hin->major)),
+ hin->minor);
+ }
+ }
+
+ if (buf) {
+ buf->nframesout -= 1;
+ if (buf->nframesout == 0 && buf->resid == 0) {
+ n = !(buf->flags & BUFFL_FAIL);
+ bio_endio(buf->bio, buf->bio->bi_size, 0);
+ mempool_free(buf, d->bufpool);
+ }
+ }
+
+ f->buf = NULL;
+ f->tag = FREETAG;
+
+ aoecmd_work(d);
+
+ sl = d->skblist;
+ d->skblist = NULL;
+
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ aoenet_xmit(sl);
+}
+
+void
+aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
+{
+ struct aoe_hdr *h;
+ struct aoe_cfghdr *ch;
+ struct sk_buff *skb, *sl;
+ struct net_device *ifp;
+ u16 aoe_type = __constant_cpu_to_be16(ETH_P_AOE);
+ u16 net_aoemajor = __cpu_to_be16(aoemajor);
+
+ sl = NULL;
+
+ read_lock(&dev_base_lock);
+ for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
+ dev_hold(ifp);
+ if (!is_aoe_netif(ifp))
+ continue;
+
+ skb = new_skb(ifp, sizeof *h + sizeof *ch);
+ if (skb == NULL) {
+ printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
+ continue;
+ }
+ h = (struct aoe_hdr *) skb->mac.raw;
+ memset(h, 0, sizeof *h + sizeof *ch);
+
+ memset(h->dst, 0xff, sizeof h->dst);
+ memcpy(h->src, ifp->dev_addr, sizeof h->src);
+ memcpy(h->type, &aoe_type, sizeof aoe_type);
+ h->verfl = AOE_HVER;
+ memcpy(h->major, &net_aoemajor, sizeof net_aoemajor);
+ h->minor = aoeminor;
+ h->cmd = AOECMD_CFG;
+
+ skb->next = sl;
+ sl = skb;
+ }
+ read_unlock(&dev_base_lock);
+
+ aoenet_xmit(sl);
+}
+
+/*
+ * Since we only call this in one place (and it only prepares one frame)
+ * we just return the skb. Usually we'd chain it up to the d->skblist.
+ */
+static struct sk_buff *
+aoecmd_ata_id(struct aoedev *d)
+{
+ struct aoe_hdr *h;
+ struct aoe_atahdr *ah;
+ struct frame *f;
+ struct sk_buff *skb;
+
+ f = getframe(d, FREETAG);
+ if (f == NULL) {
+ printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame. "
+ "This shouldn't happen.\n");
+ return NULL;
+ }
+
+ /* initialize the headers & frame */
+ h = (struct aoe_hdr *) f->data;
+ ah = (struct aoe_atahdr *) (h+1);
+ f->ndata = sizeof *h + sizeof *ah;
+ memset(h, 0, f->ndata);
+ f->tag = aoehdr_atainit(d, h);
+ f->waited = 0;
+ f->writedatalen = 0;
+
+ /* this message initializes the device, so we reset the rttavg */
+ d->rttavg = MAXTIMER;
+
+ /* set up ata header */
+ ah->scnt = 1;
+ ah->cmdstat = WIN_IDENTIFY;
+ ah->lba3 = 0xa0;
+
+ skb = skb_prepare(d, f);
+
+ /* we now want to start the rexmit tracking */
+ d->flags &= ~DEVFL_TKILL;
+ d->timer.data = (ulong) d;
+ d->timer.function = rexmit_timer;
+ d->timer.expires = jiffies + TIMERTICK;
+ add_timer(&d->timer);
+
+ return skb;
+}
+
+void
+aoecmd_cfg_rsp(struct sk_buff *skb)
+{
+ struct aoedev *d;
+ struct aoe_hdr *h;
+ struct aoe_cfghdr *ch;
+ ulong flags, bufcnt, sysminor, aoemajor;
+ struct sk_buff *sl;
+ enum { MAXFRAMES = 8, MAXSYSMINOR = 255 };
+
+ h = (struct aoe_hdr *) skb->mac.raw;
+ ch = (struct aoe_cfghdr *) (h+1);
+
+ /*
+ * Enough people have their dip switches set backwards to
+ * warrant a loud message for this special case.
+ */
+ aoemajor = __be16_to_cpu(*((u16 *) h->major));
+ if (aoemajor == 0xfff) {
+ printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
+ "address is all ones. Check shelf dip switches\n");
+ return;
+ }
+
+ sysminor = SYSMINOR(aoemajor, h->minor);
+ if (sysminor > MAXSYSMINOR) {
+ printk(KERN_INFO "aoe: aoecmd_cfg_rsp: sysminor %ld too "
+ "large\n", sysminor);
+ return;
+ }
+
+ bufcnt = __be16_to_cpu(*((u16 *) ch->bufcnt));
+ if (bufcnt > MAXFRAMES) /* keep it reasonable */
+ bufcnt = MAXFRAMES;
+
+ d = aoedev_set(sysminor, h->src, skb->dev, bufcnt);
+ if (d == NULL) {
+ printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device set failure\n");
+ return;
+ }
+
+ spin_lock_irqsave(&d->lock, flags);
+
+ if (d->flags & (DEVFL_UP | DEVFL_CLOSEWAIT)) {
+ spin_unlock_irqrestore(&d->lock, flags);
+ return;
+ }
+
+ d->fw_ver = __be16_to_cpu(*((u16 *) ch->fwver));
+
+ /* we get here only if the device is new */
+ sl = aoecmd_ata_id(d);
+
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ aoenet_xmit(sl);
+}
+
diff -Nru a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoedev.c 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,194 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoedev.c
+ * AoE device utility functions; maintains device list.
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+static struct aoedev *devlist;
+static spinlock_t devlist_lock;
+static kmem_cache_t *buf_pool_cache;
+
+struct aoedev *
+aoedev_bymac(unsigned char *macaddr)
+{
+ struct aoedev *d;
+ ulong flags;
+
+ spin_lock_irqsave(&devlist_lock, flags);
+
+ for (d=devlist; d; d=d->next)
+ if (!memcmp(d->addr, macaddr, 6))
+ break;
+
+ spin_unlock_irqrestore(&devlist_lock, flags);
+ return d;
+}
+
+/* called with devlist lock held */
+static struct aoedev *
+aoedev_newdev(ulong nframes)
+{
+ struct aoedev *d;
+ struct frame *f, *e;
+
+ d = kcalloc(1, sizeof *d, GFP_ATOMIC);
+ if (d == NULL)
+ return NULL;
+ f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
+ if (f == NULL) {
+ kfree(d);
+ return NULL;
+ }
+
+ d->nframes = nframes;
+ d->frames = f;
+ e = f + nframes;
+ for (; f<e; f++)
+ f->tag = FREETAG;
+
+ spin_lock_init(&d->lock);
+ init_timer(&d->timer);
+ d->bufpool = mempool_create(MIN_BUFS,
+ mempool_alloc_slab, mempool_free_slab,
+ buf_pool_cache);
+ INIT_LIST_HEAD(&d->bufq);
+ d->next = devlist;
+ devlist = d;
+
+ return d;
+}
+
+void
+aoedev_downdev(struct aoedev *d)
+{
+ struct frame *f, *e;
+ struct buf *buf;
+ struct bio *bio;
+
+ d->flags |= DEVFL_TKILL;
+ del_timer(&d->timer);
+
+ f = d->frames;
+ e = f + d->nframes;
+ for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
+ if (f->tag == FREETAG || f->buf == NULL)
+ continue;
+ buf = f->buf;
+ bio = buf->bio;
+ if (--buf->nframesout == 0) {
+ mempool_free(buf, d->bufpool);
+ bio_endio(bio, bio->bi_size, -EIO);
+ }
+ }
+ d->inprocess = NULL;
+
+ while (!list_empty(&d->bufq)) {
+ buf = container_of(d->bufq.next, struct buf, bufs);
+ list_del(d->bufq.next);
+ bio = buf->bio;
+ mempool_free(buf, d->bufpool);
+ bio_endio(bio, bio->bi_size, -EIO);
+ }
+
+ if (d->gd) {
+ struct block_device *bdev = bdget_disk(d->gd, 0);
+ if (bdev) {
+ if (bdev->bd_openers)
+ d->flags |= DEVFL_CLOSEWAIT;
+ bdput(bdev);
+ }
+ d->gd->capacity = 0;
+ }
+
+ d->flags &= ~DEVFL_UP;
+}
+
+struct aoedev *
+aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt)
+{
+ struct aoedev *d;
+ ulong flags;
+
+ spin_lock_irqsave(&devlist_lock, flags);
+
+ for (d=devlist; d; d=d->next)
+ if (d->sysminor == sysminor
+ || memcmp(d->addr, addr, sizeof d->addr) == 0)
+ break;
+
+ if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
+ spin_unlock_irqrestore(&devlist_lock, flags);
+ printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
+ return NULL;
+ }
+
+ spin_unlock_irqrestore(&devlist_lock, flags);
+ spin_lock_irqsave(&d->lock, flags);
+
+ d->ifp = ifp;
+
+ if (d->sysminor != sysminor
+ || memcmp(d->addr, addr, sizeof d->addr)
+ || (d->flags & DEVFL_UP) == 0) {
+ aoedev_downdev(d); /* flushes outstanding frames */
+ memcpy(d->addr, addr, sizeof d->addr);
+ d->sysminor = sysminor;
+ d->aoemajor = AOEMAJOR(sysminor);
+ d->aoeminor = AOEMINOR(sysminor);
+ }
+
+ spin_unlock_irqrestore(&d->lock, flags);
+ return d;
+}
+
+static void
+aoedev_freedev(struct aoedev *d)
+{
+ if (d->gd) {
+ aoedisk_rm_sysfs(d);
+ del_gendisk(d->gd);
+ put_disk(d->gd);
+ }
+ kfree(d->frames);
+ mempool_destroy(d->bufpool);
+ kfree(d);
+}
+
+void __exit
+aoedev_exit(void)
+{
+ struct aoedev *d;
+ ulong flags;
+
+ flush_scheduled_work();
+
+ while ((d = devlist)) {
+ devlist = d->next;
+
+ spin_lock_irqsave(&d->lock, flags);
+ aoedev_downdev(d);
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ del_timer_sync(&d->timer);
+ aoedev_freedev(d);
+ }
+ kmem_cache_destroy(buf_pool_cache);
+}
+
+int __init
+aoedev_init(void)
+{
+ buf_pool_cache = kmem_cache_create("aoe_bufs",
+ sizeof(struct buf),
+ 0, 0, NULL, NULL);
+ if (buf_pool_cache == NULL)
+ return -ENOMEM;
+ spin_lock_init(&devlist_lock);
+ return 0;
+}
+
diff -Nru a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoemain.c 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,93 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoemain.c
+ * Module initialization routines, discover timer
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include "aoe.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sam Hopkins <[email protected]>");
+MODULE_DESCRIPTION("AoE block/char driver for 2.6.[0-9]+");
+MODULE_VERSION(VERSION);
+
+enum { TINIT, TRUN, TKILL };
+
+static void
+discover_timer(ulong vp)
+{
+ static struct timer_list t;
+ static volatile ulong die;
+ static spinlock_t lock;
+ ulong flags;
+ enum { DTIMERTICK = HZ * 60 }; /* one minute */
+
+ switch (vp) {
+ case TINIT:
+ init_timer(&t);
+ spin_lock_init(&lock);
+ t.data = TRUN;
+ t.function = discover_timer;
+ die = 0;
+ case TRUN:
+ spin_lock_irqsave(&lock, flags);
+ if (!die) {
+ t.expires = jiffies + DTIMERTICK;
+ add_timer(&t);
+ }
+ spin_unlock_irqrestore(&lock, flags);
+
+ aoecmd_cfg(0xffff, 0xff);
+ return;
+ case TKILL:
+ spin_lock_irqsave(&lock, flags);
+ die = 1;
+ spin_unlock_irqrestore(&lock, flags);
+
+ del_timer_sync(&t);
+ default:
+ return;
+ }
+}
+
+static void __exit
+aoe_exit(void)
+{
+ discover_timer(TKILL);
+
+ aoenet_exit();
+ aoeblk_exit();
+ aoechr_exit();
+ aoedev_exit();
+}
+
+static int __init
+aoe_init(void)
+{
+ int n, (**p)(void);
+ int (*fns[])(void) = {
+ aoedev_init, aoechr_init, aoeblk_init, aoenet_init, NULL
+ };
+
+ for (p=fns; *p != NULL; p++) {
+ n = (*p)();
+ if (n) {
+ aoe_exit();
+ printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
+ return n;
+ }
+ }
+ printk(KERN_INFO
+ "aoe: aoe_init: AoE v2.6-%s initialised.\n",
+ VERSION);
+
+ discover_timer(TINIT);
+ return 0;
+}
+
+module_init(aoe_init);
+module_exit(aoe_exit);
+
diff -Nru a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoenet.c 2005-01-07 15:45:50 -08:00
@@ -0,0 +1,173 @@
+/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoenet.c
+ * Ethernet portion of AoE driver
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+#define NECODES 5
+
+static char *aoe_errlist[] =
+{
+ "no such error",
+ "unrecognized command code",
+ "bad argument parameter",
+ "device unavailable",
+ "config string present",
+ "unsupported version"
+};
+
+enum {
+ IFLISTSZ = 1024,
+};
+
+static char aoe_iflist[IFLISTSZ];
+
+int
+is_aoe_netif(struct net_device *ifp)
+{
+ register char *p, *q;
+ register int len;
+
+ if (aoe_iflist[0] == '\0')
+ return 1;
+
+ for (p = aoe_iflist; *p; p = q + strspn(q, WHITESPACE)) {
+ q = p + strcspn(p, WHITESPACE);
+ if (q != p)
+ len = q - p;
+ else
+ len = strlen(p); /* last token in aoe_iflist */
+
+ if (strlen(ifp->name) == len && !strncmp(ifp->name, p, len))
+ return 1;
+ if (q == p)
+ break;
+ }
+
+ return 0;
+}
+
+int
+set_aoe_iflist(char *str)
+{
+ int len = strlen(str);
+
+ if (len >= IFLISTSZ)
+ return -EINVAL;
+
+ strcpy(aoe_iflist, str);
+ return 0;
+}
+
+u64
+mac_addr(char addr[6])
+{
+ u64 n = 0;
+ char *p = (char *) &n;
+
+ memcpy(p + 2, addr, 6); /* (sizeof addr != 6) */
+
+ return __be64_to_cpu(n);
+}
+
+static struct sk_buff *
+skb_check(struct sk_buff *skb)
+{
+ if (skb_is_nonlinear(skb))
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)))
+ if (skb_linearize(skb, GFP_ATOMIC) < 0) {
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+ return skb;
+}
+
+void
+aoenet_xmit(struct sk_buff *sl)
+{
+ struct sk_buff *skb;
+
+ while ((skb = sl)) {
+ sl = sl->next;
+ skb->next = skb->prev = NULL;
+ dev_queue_xmit(skb);
+ }
+}
+
+/*
+ * (1) i have no idea if this is redundant, but i can't figure why
+ * the ifp is passed in if it is.
+ *
+ * (2) len doesn't include the header by default. I want this.
+ */
+static int
+aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
+{
+ struct aoe_hdr *h;
+ ulong n;
+
+ skb = skb_check(skb);
+ if (!skb)
+ return 0;
+
+ skb->dev = ifp; /* (1) */
+
+ if (!is_aoe_netif(ifp))
+ goto exit;
+
+ skb->len += ETH_HLEN; /* (2) */
+
+ h = (struct aoe_hdr *) skb->mac.raw;
+ n = __be32_to_cpu(*((u32 *) h->tag));
+ if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
+ goto exit;
+
+ if (h->verfl & AOEFL_ERR) {
+ n = h->err;
+ if (n > NECODES)
+ n = 0;
+ printk(KERN_CRIT "aoe: aoenet_rcv: error packet from %d.%d; "
+ "ecode=%d '%s'\n",
+ __be16_to_cpu(*((u16 *) h->major)), h->minor,
+ h->err, aoe_errlist[n]);
+ goto exit;
+ }
+
+ switch (h->cmd) {
+ case AOECMD_ATA:
+ aoecmd_ata_rsp(skb);
+ break;
+ case AOECMD_CFG:
+ aoecmd_cfg_rsp(skb);
+ break;
+ default:
+ printk(KERN_INFO "aoe: aoenet_rcv: unknown cmd %d\n", h->cmd);
+ }
+exit:
+ dev_kfree_skb(skb);
+ return 0;
+}
+
+static struct packet_type aoe_pt = {
+ .type = __constant_htons(ETH_P_AOE),
+ .func = aoenet_rcv,
+};
+
+int __init
+aoenet_init(void)
+{
+ dev_add_pack(&aoe_pt);
+ return 0;
+}
+
+void __exit
+aoenet_exit(void)
+{
+ dev_remove_pack(&aoe_pt);
+}
+
ChangeSet 1.1938.444.5, 2004/12/15 11:15:47-08:00, [email protected]
[PATCH] misc: remove miscdevice.h from pci hotplug drivers as they do not need it.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/pci/hotplug/pciehp_core.c | 1 -
drivers/pci/hotplug/shpchp_core.c | 1 -
2 files changed, 2 deletions(-)
diff -Nru a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
--- a/drivers/pci/hotplug/pciehp_core.c 2005-01-07 15:51:36 -08:00
+++ b/drivers/pci/hotplug/pciehp_core.c 2005-01-07 15:51:36 -08:00
@@ -33,7 +33,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
diff -Nru a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
--- a/drivers/pci/hotplug/shpchp_core.c 2005-01-07 15:51:36 -08:00
+++ b/drivers/pci/hotplug/shpchp_core.c 2005-01-07 15:51:36 -08:00
@@ -33,7 +33,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
ChangeSet 1.1938.444.23, 2004/12/21 10:50:37-08:00, [email protected]
[PATCH] rename ETH_P_AOE
Rename old ETH_P_EDP2 ("EtherDrive Protocol 2") to ETH_P_AOE (ATA over
Ethernet).
Signed-off-by: Ed L. Cashin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/block/aoe/aoe.h | 1 -
include/linux/if_ether.h | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff -Nru a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
--- a/drivers/block/aoe/aoe.h 2005-01-07 15:41:09 -08:00
+++ b/drivers/block/aoe/aoe.h 2005-01-07 15:41:09 -08:00
@@ -26,7 +26,6 @@
AOECCMD_FSET,
AOE_HVER = 0x10,
- ETH_P_AOE = 0x88a2,
};
struct aoe_hdr {
diff -Nru a/include/linux/if_ether.h b/include/linux/if_ether.h
--- a/include/linux/if_ether.h 2005-01-07 15:41:09 -08:00
+++ b/include/linux/if_ether.h 2005-01-07 15:41:09 -08:00
@@ -69,7 +69,7 @@
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
* over Ethernet
*/
-#define ETH_P_EDP2 0x88A2 /* Coraid EDP2 */
+#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
/*
* Non DIX types. Won't clash for 1500 types.
ChangeSet 1.1938.444.20, 2004/12/21 10:36:35-08:00, [email protected]
[PATCH] module sysfs: sections attr reimplemented using attr group
Reimplement section attributes using attribute group. This
makes more sense, for, while they reside in a separate
subdirectory, they belong to the ownig module and their
lifetime exactly equals the lifetime of the owning module,
and it's simpler.
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/module.h | 8 ++---
kernel/module.c | 75 ++++++++++++++++++++++---------------------------
2 files changed, 39 insertions(+), 44 deletions(-)
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h 2005-01-07 15:41:32 -08:00
+++ b/include/linux/module.h 2005-01-07 15:41:32 -08:00
@@ -227,14 +227,14 @@
#define MODULE_SECT_NAME_LEN 32
struct module_sect_attr
{
- struct attribute attr;
+ struct module_attribute mattr;
char name[MODULE_SECT_NAME_LEN];
unsigned long address;
};
-struct module_sections
+struct module_sect_attrs
{
- struct kobject kobj;
+ struct attribute_group grp;
struct module_sect_attr attrs[0];
};
@@ -313,7 +313,7 @@
char *strtab;
/* Section attributes */
- struct module_sections *sect_attrs;
+ struct module_sect_attrs *sect_attrs;
#endif
/* Per-cpu data. */
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c 2005-01-07 15:41:32 -08:00
+++ b/kernel/module.c 2005-01-07 15:41:32 -08:00
@@ -937,76 +937,71 @@
* J. Corbet <[email protected]>
*/
#ifdef CONFIG_KALLSYMS
-static void module_sect_attrs_release(struct kobject *kobj)
-{
- kfree(container_of(kobj, struct module_sections, kobj));
-}
-
-static ssize_t module_sect_show(struct kobject *kobj, struct attribute *attr,
- char *buf)
+static ssize_t module_sect_show(struct module_attribute *mattr,
+ struct module *mod, char *buf)
{
struct module_sect_attr *sattr =
- container_of(attr, struct module_sect_attr, attr);
+ container_of(mattr, struct module_sect_attr, mattr);
return sprintf(buf, "0x%lx\n", sattr->address);
}
-static struct sysfs_ops module_sect_ops = {
- .show = module_sect_show,
-};
-
-static struct kobj_type module_sect_ktype = {
- .sysfs_ops = &module_sect_ops,
- .release = module_sect_attrs_release,
-};
-
static void add_sect_attrs(struct module *mod, unsigned int nsect,
char *secstrings, Elf_Shdr *sechdrs)
{
- unsigned int nloaded = 0, i;
+ unsigned int nloaded = 0, i, size[2];
+ struct module_sect_attrs *sect_attrs;
struct module_sect_attr *sattr;
+ struct attribute **gattr;
/* Count loaded sections and allocate structures */
for (i = 0; i < nsect; i++)
if (sechdrs[i].sh_flags & SHF_ALLOC)
nloaded++;
- mod->sect_attrs = kmalloc(sizeof(struct module_sections) +
- nloaded*sizeof(mod->sect_attrs->attrs[0]), GFP_KERNEL);
- if (! mod->sect_attrs)
+ size[0] = ALIGN(sizeof(*sect_attrs)
+ + nloaded * sizeof(sect_attrs->attrs[0]),
+ sizeof(sect_attrs->grp.attrs[0]));
+ size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
+ if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL)))
return;
- /* sections entry setup */
- memset(mod->sect_attrs, 0, sizeof(struct module_sections));
- if (kobject_set_name(&mod->sect_attrs->kobj, "sections"))
- goto out;
- mod->sect_attrs->kobj.parent = &mod->mkobj.kobj;
- mod->sect_attrs->kobj.ktype = &module_sect_ktype;
- if (kobject_register(&mod->sect_attrs->kobj))
- goto out;
+ /* Setup section attributes. */
+ sect_attrs->grp.name = "sections";
+ sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
- /* And the section attributes. */
- sattr = &mod->sect_attrs->attrs[0];
+ sattr = §_attrs->attrs[0];
+ gattr = §_attrs->grp.attrs[0];
for (i = 0; i < nsect; i++) {
if (! (sechdrs[i].sh_flags & SHF_ALLOC))
continue;
sattr->address = sechdrs[i].sh_addr;
strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
- MODULE_SECT_NAME_LEN);
- sattr->attr.name = sattr->name;
- sattr->attr.owner = mod;
- sattr->attr.mode = S_IRUGO;
- (void) sysfs_create_file(&mod->sect_attrs->kobj, &sattr->attr);
- sattr++;
+ MODULE_SECT_NAME_LEN);
+ sattr->mattr.show = module_sect_show;
+ sattr->mattr.store = NULL;
+ sattr->mattr.attr.name = sattr->name;
+ sattr->mattr.attr.owner = mod;
+ sattr->mattr.attr.mode = S_IRUGO;
+ *(gattr++) = &(sattr++)->mattr.attr;
}
+ *gattr = NULL;
+
+ if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp))
+ goto out;
+
+ mod->sect_attrs = sect_attrs;
return;
out:
- kfree(mod->sect_attrs);
- mod->sect_attrs = NULL;
+ kfree(sect_attrs);
}
static void remove_sect_attrs(struct module *mod)
{
if (mod->sect_attrs) {
- kobject_unregister(&mod->sect_attrs->kobj);
+ sysfs_remove_group(&mod->mkobj.kobj,
+ &mod->sect_attrs->grp);
+ /* We are positive that no one is using any sect attrs
+ * at this point. Deallocate immediately. */
+ kfree(mod->sect_attrs);
mod->sect_attrs = NULL;
}
}
ChangeSet 1.1938.444.2, 2004/12/15 10:49:05-08:00, [email protected]
[PATCH] misc: remove device.h #include from miscdevice.h
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/miscdevice.h | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
--- a/include/linux/miscdevice.h 2005-01-07 15:52:00 -08:00
+++ b/include/linux/miscdevice.h 2005-01-07 15:52:00 -08:00
@@ -2,7 +2,6 @@
#define _LINUX_MISCDEVICE_H
#include <linux/module.h>
#include <linux/major.h>
-#include <linux/device.h>
#define PSMOUSE_MINOR 1
#define MS_BUSMOUSE_MINOR 2
@@ -32,6 +31,7 @@
#define HPET_MINOR 228
struct device;
+struct class_device;
struct miscdevice {
int minor;
ChangeSet 1.1938.444.29, 2004/12/21 22:40:34-08:00, [email protected]
sysfs: export the /sys/kernel subsystem for people to use.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/kobject.h | 2 ++
kernel/ksysfs.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h 2005-01-07 15:40:24 -08:00
+++ b/include/linux/kobject.h 2005-01-07 15:40:24 -08:00
@@ -167,6 +167,8 @@
} \
}
+/* The global /sys/kernel/ subsystem for people to chain off of */
+extern struct subsystem kernel_subsys;
/**
* Helpers for setting the kset of registered objects.
diff -Nru a/kernel/ksysfs.c b/kernel/ksysfs.c
--- a/kernel/ksysfs.c 2005-01-07 15:40:24 -08:00
+++ b/kernel/ksysfs.c 2005-01-07 15:40:24 -08:00
@@ -30,7 +30,8 @@
KERNEL_ATTR_RO(hotplug_seqnum);
#endif
-static decl_subsys(kernel, NULL, NULL);
+decl_subsys(kernel, NULL, NULL);
+EXPORT_SYMBOL_GPL(kernel_subsys);
static struct attribute * kernel_attrs[] = {
#ifdef CONFIG_HOTPLUG
ChangeSet 1.1938.446.7, 2004/12/15 14:47:29-08:00, [email protected]
USB: delete the tiglusb driver as it's not needed
You can use a userspace program and libusb instead. The author asked for
this driver to be removed because of this.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/misc/tiglusb.c | 592 ---------------------------------------------
drivers/usb/misc/tiglusb.h | 43 ---
drivers/usb/Makefile | 1
drivers/usb/misc/Kconfig | 20 -
drivers/usb/misc/Makefile | 1
5 files changed, 657 deletions(-)
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile 2005-01-07 15:50:39 -08:00
+++ b/drivers/usb/Makefile 2005-01-07 15:50:39 -08:00
@@ -65,7 +65,6 @@
obj-$(CONFIG_USB_LEGOTOWER) += misc/
obj-$(CONFIG_USB_RIO500) += misc/
obj-$(CONFIG_USB_TEST) += misc/
-obj-$(CONFIG_USB_TIGL) += misc/
obj-$(CONFIG_USB_USS720) += misc/
obj-$(CONFIG_USB_PHIDGETSERVO) += misc/
diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
--- a/drivers/usb/misc/Kconfig 2005-01-07 15:50:39 -08:00
+++ b/drivers/usb/misc/Kconfig 2005-01-07 15:50:39 -08:00
@@ -32,26 +32,6 @@
To compile this driver as a module, choose M here: the
module will be called emi26.
-config USB_TIGL
- tristate "Texas Instruments Graph Link USB (aka SilverLink) cable support"
- depends on USB
- ---help---
- If you own a Texas Instruments graphing calculator and use a
- TI-GRAPH LINK USB cable (aka SilverLink), then you might be
- interested in this driver.
-
- If you enable this driver, you will be able to communicate with
- your calculator through a set of device nodes under /dev.
-
- To compile this driver as a module, choose M here: the
- module will be called tiglusb.
-
- If you don't know what the SilverLink cable is or what a Texas
- Instruments graphing calculator is, then you probably don't need this
- driver.
-
- If unsure, say N.
-
config USB_AUERSWALD
tristate "USB Auerswald ISDN support (EXPERIMENTAL)"
depends on USB && EXPERIMENTAL
diff -Nru a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
--- a/drivers/usb/misc/Makefile 2005-01-07 15:50:39 -08:00
+++ b/drivers/usb/misc/Makefile 2005-01-07 15:50:39 -08:00
@@ -14,5 +14,4 @@
obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_TEST) += usbtest.o
-obj-$(CONFIG_USB_TIGL) += tiglusb.o
obj-$(CONFIG_USB_USS720) += uss720.o
diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
--- a/drivers/usb/misc/tiglusb.c 2005-01-07 15:50:39 -08:00
+++ /dev/null Wed Dec 31 16:00:00 196900
@@ -1,592 +0,0 @@
-/* Hey EMACS -*- linux-c -*-
- *
- * tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
- * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
- *
- * Copyright (C) 2001-2004:
- * Romain Lievin <[email protected]>
- * Julien BLACHE <[email protected]>
- * under the terms of the GNU General Public License.
- *
- * Based on dabusb.c, printer.c & scanner.c
- *
- * Please see the file: Documentation/usb/silverlink.txt
- * and the website at: http://lpg.ticalc.org/prj_usb/
- * for more info.
- *
- * History:
- * 1.0x, Romain & Julien: initial submit.
- * 1.03, Greg Kroah: modifications.
- * 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
- * 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero).
- * 1.06, Romain: synched with 2.5, version/firmware changed (confusing).
- * 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument);
- * timeout argument checked in ioctl + clean-up.
- * 1.08, Romain: added support of USB port embedded on some TI's handhelds.
- */
-
-#include <linux/module.h>
-#include <linux/socket.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/usb.h>
-#include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/device.h>
-
-#include <linux/ticable.h>
-#include "tiglusb.h"
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "1.08"
-#define DRIVER_AUTHOR "Romain Lievin <[email protected]> & Julien Blache <[email protected]>"
-#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
-#define DRIVER_LICENSE "GPL"
-
-/* ----- global variables --------------------------------------------- */
-
-static tiglusb_t tiglusb[MAXTIGL];
-static int timeout = TIMAXTIME; /* timeout in tenth of seconds */
-static struct class_simple *tiglusb_class;
-
-/*---------- misc functions ------------------------------------------- */
-
-/*
- * Re-initialize device
- */
-static inline int
-clear_device (struct usb_device *dev)
-{
- if (usb_reset_configuration (dev) < 0) {
- err ("clear_device failed");
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Clear input & output pipes (endpoints)
- */
-static inline int
-clear_pipes (struct usb_device *dev)
-{
- unsigned int pipe;
-
- pipe = usb_sndbulkpipe (dev, 2);
- if (usb_clear_halt (dev, pipe)) {
- err ("clear_pipe (w), request failed");
- return -1;
- }
-
- pipe = usb_rcvbulkpipe (dev, 1);
- if (usb_clear_halt (dev, pipe)) {
- err ("clear_pipe (r), request failed");
- return -1;
- }
-
- return 0;
-}
-
-/* ----- file operations functions--------------------------------------- */
-
-static int
-tiglusb_open (struct inode *inode, struct file *filp)
-{
- int devnum = iminor(inode);
- ptiglusb_t s;
-
- if (devnum < TIUSB_MINOR || devnum >= (TIUSB_MINOR + MAXTIGL))
- return -EIO;
-
- s = &tiglusb[devnum - TIUSB_MINOR];
-
- if (down_interruptible (&s->mutex)) {
- return -ERESTARTSYS;
- }
-
- while (!s->dev || s->opened) {
- up (&s->mutex);
-
- if (filp->f_flags & O_NONBLOCK) {
- return -EBUSY;
- }
-
- msleep_interruptible(500);
-
- if (signal_pending (current)) {
- return -EAGAIN;
- }
-
- if (down_interruptible (&s->mutex)) {
- return -ERESTARTSYS;
- }
- }
-
- s->opened = 1;
- up (&s->mutex);
-
- filp->f_pos = 0;
- filp->private_data = s;
-
- return nonseekable_open(inode, filp);
-}
-
-static int
-tiglusb_release (struct inode *inode, struct file *filp)
-{
- ptiglusb_t s = (ptiglusb_t) filp->private_data;
-
- if (down_interruptible (&s->mutex)) {
- return -ERESTARTSYS;
- }
-
- s->state = _stopped;
- up (&s->mutex);
-
- if (!s->remove_pending)
- clear_device (s->dev);
- else
- wake_up (&s->remove_ok);
-
- s->opened = 0;
-
- return 0;
-}
-
-static ssize_t
-tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
-{
- ptiglusb_t s = (ptiglusb_t) filp->private_data;
- ssize_t ret = 0;
- int bytes_to_read = 0;
- int bytes_read = 0;
- int result = 0;
- char *buffer;
- unsigned int pipe;
-
- if (*f_pos)
- return -ESPIPE;
-
- if (s->remove_pending)
- return -EIO;
-
- if (!s->dev)
- return -EIO;
-
- buffer = kmalloc (s->max_ps, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- bytes_to_read = (count >= s->max_ps) ? s->max_ps : count;
-
- pipe = usb_rcvbulkpipe (s->dev, 1);
- result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read,
- &bytes_read, (HZ * timeout) / 10);
- if (result == -ETIMEDOUT) { /* NAK */
- if (!bytes_read)
- dbg ("quirk !");
- warn ("tiglusb_read, NAK received.");
- ret = result;
- goto out;
- } else if (result == -EPIPE) { /* STALL -- shouldn't happen */
- warn ("clear_halt request to remove STALL condition.");
- if (usb_clear_halt (s->dev, pipe))
- err ("clear_halt, request failed");
- clear_device (s->dev);
- ret = result;
- goto out;
- } else if (result < 0) { /* We should not get any I/O errors */
- err ("funky result: %d. Please notify maintainer.", result);
- ret = -EIO;
- goto out;
- }
-
- if (copy_to_user (buf, buffer, bytes_read)) {
- ret = -EFAULT;
- }
-
- out:
- kfree(buffer);
- return ret ? ret : bytes_read;
-}
-
-static ssize_t
-tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * f_pos)
-{
- ptiglusb_t s = (ptiglusb_t) filp->private_data;
- ssize_t ret = 0;
- int bytes_to_write = 0;
- int bytes_written = 0;
- int result = 0;
- char *buffer;
- unsigned int pipe;
-
- if (*f_pos)
- return -ESPIPE;
-
- if (s->remove_pending)
- return -EIO;
-
- if (!s->dev)
- return -EIO;
-
- buffer = kmalloc (s->max_ps, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- bytes_to_write = (count >= s->max_ps) ? s->max_ps : count;
- if (copy_from_user (buffer, buf, bytes_to_write)) {
- ret = -EFAULT;
- goto out;
- }
-
- pipe = usb_sndbulkpipe (s->dev, 2);
- result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_write,
- &bytes_written, (HZ * timeout) / 10);
-
- if (result == -ETIMEDOUT) { /* NAK */
- warn ("tiglusb_write, NAK received.");
- ret = result;
- goto out;
- } else if (result == -EPIPE) { /* STALL -- shouldn't happen */
- warn ("clear_halt request to remove STALL condition.");
- if (usb_clear_halt (s->dev, pipe))
- err ("clear_halt, request failed");
- clear_device (s->dev);
- ret = result;
- goto out;
- } else if (result < 0) { /* We should not get any I/O errors */
- warn ("funky result: %d. Please notify maintainer.", result);
- ret = -EIO;
- goto out;
- }
-
- if (bytes_written != bytes_to_write) {
- ret = -EIO;
- }
-
- out:
- kfree(buffer);
- return ret ? ret : bytes_written;
-}
-
-static int
-tiglusb_ioctl (struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- ptiglusb_t s = (ptiglusb_t) filp->private_data;
- int ret = 0;
-
- if (s->remove_pending)
- return -EIO;
-
- if (down_interruptible (&s->mutex)) {
- return -ERESTARTSYS;
- }
-
- if (!s->dev) {
- up (&s->mutex);
- return -EIO;
- }
-
- switch (cmd) {
- case IOCTL_TIUSB_TIMEOUT:
- if (arg > 0)
- timeout = arg;
- else
- ret = -EINVAL;
- break;
- case IOCTL_TIUSB_RESET_DEVICE:
- if (clear_device (s->dev))
- ret = -EIO;
- break;
- case IOCTL_TIUSB_RESET_PIPES:
- if (clear_pipes (s->dev))
- ret = -EIO;
- break;
- case IOCTL_TIUSB_GET_MAXPS:
- if (copy_to_user((int __user *) arg, &s->max_ps, sizeof(int)))
- return -EFAULT;
- break;
- case IOCTL_TIUSB_GET_DEVID:
- if (copy_to_user((int __user *) arg, &s->dev->descriptor.idProduct,
- sizeof(int)))
- return -EFAULT;
- break;
- default:
- ret = -ENOTTY;
- break;
- }
-
- up (&s->mutex);
-
- return ret;
-}
-
-/* ----- kernel module registering ------------------------------------ */
-
-static struct file_operations tiglusb_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = tiglusb_read,
- .write = tiglusb_write,
- .ioctl = tiglusb_ioctl,
- .open = tiglusb_open,
- .release = tiglusb_release,
-};
-
-/* --- initialisation code ------------------------------------- */
-
-static int
-tiglusb_probe (struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- int minor = -1;
- int i, err = 0;
- ptiglusb_t s;
- struct usb_host_config *conf;
- struct usb_host_interface *ifdata = NULL;
- int max_ps;
-
- dbg ("probing vendor id 0x%x, device id 0x%x",
- dev->descriptor.idVendor, dev->descriptor.idProduct);
-
- /*
- * We don't handle multiple configurations. As of version 0x0103 of
- * the TIGL hardware, there's only 1 configuration.
- */
-
- if (dev->descriptor.bNumConfigurations != 1) {
- err = -ENODEV;
- goto out;
- }
-
- if (dev->descriptor.idVendor != 0x451) {
- err = -ENODEV;
- goto out;
- }
-
- if ((dev->descriptor.idProduct != 0xe001) &&
- (dev->descriptor.idProduct != 0xe004) &&
- (dev->descriptor.idProduct != 0xe008)) {
- err = -ENODEV;
- goto out;
- }
-
- /*
- * TI introduced some new handhelds with embedded USB port.
- * Port advertises same config as SilverLink cable but with a
- * different maximum packet size (64 rather than 32).
- */
-
- conf = dev->actconfig;
- ifdata = conf->interface[0]->cur_altsetting;
- max_ps = ifdata->endpoint[0].desc.wMaxPacketSize;
-
- info("max packet size of %d/%d bytes\n",
- ifdata->endpoint[0].desc.wMaxPacketSize,
- ifdata->endpoint[1].desc.wMaxPacketSize);
-
- /*
- * Find a tiglusb struct
- */
- for (i = 0; i < MAXTIGL; i++) {
- ptiglusb_t s = &tiglusb[i];
- if (!s->dev) {
- minor = i;
- break;
- }
- }
-
- if (minor == -1) {
- err = -ENODEV;
- goto out;
- }
-
- s = &tiglusb[minor];
-
- down (&s->mutex);
- s->remove_pending = 0;
- s->dev = dev;
- s->max_ps = max_ps;
- up (&s->mutex);
- dbg ("bound to interface");
-
- class_simple_device_add(tiglusb_class, MKDEV(TIUSB_MAJOR, TIUSB_MINOR + s->minor),
- NULL, "usb%d", s->minor);
- err = devfs_mk_cdev(MKDEV(TIUSB_MAJOR, TIUSB_MINOR) + s->minor,
- S_IFCHR | S_IRUGO | S_IWUGO,
- "ticables/usb/%d", s->minor);
-
- if (err)
- goto out_class;
-
- /* Display firmware version */
- info ("firmware revision %i.%02x",
- dev->descriptor.bcdDevice >> 8,
- dev->descriptor.bcdDevice & 0xff);
-
- usb_set_intfdata (intf, s);
- err = 0;
- goto out;
-
-out_class:
- class_simple_device_remove(MKDEV(TIUSB_MAJOR, TIUSB_MINOR + s->minor));
-out:
- return err;
-}
-
-static void
-tiglusb_disconnect (struct usb_interface *intf)
-{
- wait_queue_t __wait;
- ptiglusb_t s = usb_get_intfdata (intf);
-
- init_waitqueue_entry(&__wait, current);
-
-
- usb_set_intfdata (intf, NULL);
- if (!s || !s->dev) {
- info ("bogus disconnect");
- return;
- }
-
- s->remove_pending = 1;
- wake_up (&s->wait);
- add_wait_queue(&s->wait, &__wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (s->state == _started)
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&s->wait, &__wait);
- down (&s->mutex);
- s->dev = NULL;
- s->opened = 0;
-
- class_simple_device_remove(MKDEV(TIUSB_MAJOR, TIUSB_MINOR + s->minor));
- devfs_remove("ticables/usb/%d", s->minor);
-
- info ("device %d removed", s->minor);
-
- up (&s->mutex);
-}
-
-static struct usb_device_id tiglusb_ids[] = {
- {USB_DEVICE (0x0451, 0xe001)},
- {}
-};
-
-MODULE_DEVICE_TABLE (usb, tiglusb_ids);
-
-static struct usb_driver tiglusb_driver = {
- .owner = THIS_MODULE,
- .name = "tiglusb",
- .probe = tiglusb_probe,
- .disconnect = tiglusb_disconnect,
- .id_table = tiglusb_ids,
-};
-
-/* --- initialisation code ------------------------------------- */
-
-#ifndef MODULE
-/*
- * You can use 'tiusb=timeout' to set timeout.
- */
-static int __init
-tiglusb_setup (char *str)
-{
- int ints[2];
-
- str = get_options (str, ARRAY_SIZE (ints), ints);
-
- if (ints[0] > 0) {
- if (ints[1] > 0)
- timeout = ints[1];
- else
- info ("tiglusb: wrong timeout value (0), using default value.");
- }
-
- return 1;
-}
-#endif
-
-static int __init
-tiglusb_init (void)
-{
- unsigned u;
- int result, err = 0;
-
- /* initialize struct */
- for (u = 0; u < MAXTIGL; u++) {
- ptiglusb_t s = &tiglusb[u];
- memset (s, 0, sizeof (tiglusb_t));
- init_MUTEX (&s->mutex);
- s->dev = NULL;
- s->minor = u;
- s->opened = 0;
- init_waitqueue_head (&s->wait);
- init_waitqueue_head (&s->remove_ok);
- }
-
- /* register device */
- if (register_chrdev (TIUSB_MAJOR, "tiglusb", &tiglusb_fops)) {
- err ("unable to get major %d", TIUSB_MAJOR);
- err = -EIO;
- goto out;
- }
-
- /* Use devfs, tree: /dev/ticables/usb/[0..3] */
- devfs_mk_dir ("ticables/usb");
-
- tiglusb_class = class_simple_create(THIS_MODULE, "tiglusb");
- if (IS_ERR(tiglusb_class)) {
- err = PTR_ERR(tiglusb_class);
- goto out_chrdev;
- }
- /* register USB module */
- result = usb_register (&tiglusb_driver);
- if (result < 0) {
- err = -1;
- goto out_chrdev;
- }
-
- info (DRIVER_DESC ", version " DRIVER_VERSION);
-
- err = 0;
- goto out;
-
-out_chrdev:
- unregister_chrdev (TIUSB_MAJOR, "tiglusb");
-out:
- return err;
-}
-
-static void __exit
-tiglusb_cleanup (void)
-{
- usb_deregister (&tiglusb_driver);
- class_simple_destroy(tiglusb_class);
- devfs_remove("ticables/usb");
- unregister_chrdev (TIUSB_MAJOR, "tiglusb");
-}
-
-/* --------------------------------------------------------------------- */
-
-__setup ("tiusb=", tiglusb_setup);
-module_init (tiglusb_init);
-module_exit (tiglusb_cleanup);
-
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE (DRIVER_LICENSE);
-
-module_param(timeout, int, 0);
-MODULE_PARM_DESC (timeout, "Timeout in tenths of seconds (default=1.5 seconds)");
-
-/* --------------------------------------------------------------------- */
diff -Nru a/drivers/usb/misc/tiglusb.h b/drivers/usb/misc/tiglusb.h
--- a/drivers/usb/misc/tiglusb.h 2005-01-07 15:50:39 -08:00
+++ /dev/null Wed Dec 31 16:00:00 196900
@@ -1,43 +0,0 @@
-/* Hey EMACS -*- linux-c -*-
- *
- * tiglusb - low level driver for SilverLink cable
- *
- * Copyright (C) 2000-2002, Romain Lievin <[email protected]>
- * under the terms of the GNU General Public License.
- *
- * Redistribution of this file is permitted under the terms of the GNU
- * Public License (GPL)
- */
-
-#ifndef _TIGLUSB_H
-#define _TIGLUSB_H
-
-/*
- * Max. number of devices supported
- */
-#define MAXTIGL 16
-
-/*
- * The driver context...
- */
-
-typedef enum { _stopped=0, _started } driver_state_t;
-
-typedef struct
-{
- struct usb_device *dev; /* USB device handle */
- struct semaphore mutex; /* locks this struct */
-
- wait_queue_head_t wait; /* for timed waits */
- wait_queue_head_t remove_ok;
-
- int minor; /* which minor dev #? */
-
- driver_state_t state; /* started/stopped */
- int opened; /* tru if open */
- int remove_pending;
-
- int max_ps; /* max packet size */
-} tiglusb_t, *ptiglusb_t;
-
-#endif
ChangeSet 1.1938.444.22, 2004/12/21 10:37:07-08:00, [email protected]
[PATCH] sysfs: add mmap support to struct bin_attribute files
This patch adds an mmap method and some more error checking to struct
bin_attribute--good for things like exporting PCI resources directly. I
wasn't sure about the return values for the case where an attribute is
missing a given method, and it looks like mm.h can't be included in sysfs.h,
so I had to forward declare struct vm_area_struct. Other than that, it works
fine for my test cases.
Signed-off-by: Jesse Barnes <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
fs/sysfs/bin.c | 27 +++++++++++++++++++++++++--
include/linux/sysfs.h | 6 ++++++
2 files changed, 31 insertions(+), 2 deletions(-)
diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c
--- a/fs/sysfs/bin.c 2005-01-07 15:41:17 -08:00
+++ b/fs/sysfs/bin.c 2005-01-07 15:41:17 -08:00
@@ -1,5 +1,9 @@
/*
* bin.c - binary file operations for sysfs.
+ *
+ * Copyright (c) 2003 Patrick Mochel
+ * Copyright (c) 2003 Matthew Wilcox
+ * Copyright (c) 2004 Silicon Graphics, Inc.
*/
#undef DEBUG
@@ -20,6 +24,9 @@
struct bin_attribute * attr = to_bin_attr(dentry);
struct kobject * kobj = to_kobj(dentry->d_parent);
+ if (!attr->read)
+ return -EINVAL;
+
return attr->read(kobj, buffer, off, count);
}
@@ -63,6 +70,9 @@
struct bin_attribute *attr = to_bin_attr(dentry);
struct kobject *kobj = to_kobj(dentry->d_parent);
+ if (!attr->write)
+ return -EINVAL;
+
return attr->write(kobj, buffer, offset, count);
}
@@ -92,6 +102,18 @@
return count;
}
+static int mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct dentry *dentry = file->f_dentry;
+ struct bin_attribute *attr = to_bin_attr(dentry);
+ struct kobject *kobj = to_kobj(dentry->d_parent);
+
+ if (!attr->mmap)
+ return -EINVAL;
+
+ return attr->mmap(kobj, attr, vma);
+}
+
static int open(struct inode * inode, struct file * file)
{
struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
@@ -107,9 +129,9 @@
goto Done;
error = -EACCES;
- if ((file->f_mode & FMODE_WRITE) && !attr->write)
+ if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
goto Error;
- if ((file->f_mode & FMODE_READ) && !attr->read)
+ if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
goto Error;
error = -ENOMEM;
@@ -144,6 +166,7 @@
struct file_operations bin_fops = {
.read = read,
.write = write,
+ .mmap = mmap,
.llseek = generic_file_llseek,
.open = open,
.release = release,
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h 2005-01-07 15:41:17 -08:00
+++ b/include/linux/sysfs.h 2005-01-07 15:41:17 -08:00
@@ -2,6 +2,7 @@
* sysfs.h - definitions for the device driver filesystem
*
* Copyright (c) 2001,2002 Patrick Mochel
+ * Copyright (c) 2004 Silicon Graphics, Inc.
*
* Please see Documentation/filesystems/sysfs.txt for more information.
*/
@@ -47,11 +48,16 @@
#define attr_name(_attr) (_attr).attr.name
+struct vm_area_struct;
+
struct bin_attribute {
struct attribute attr;
size_t size;
+ void *private;
ssize_t (*read)(struct kobject *, char *, loff_t, size_t);
ssize_t (*write)(struct kobject *, char *, loff_t, size_t);
+ int (*mmap)(struct kobject *, struct bin_attribute *attr,
+ struct vm_area_struct *vma);
};
struct sysfs_ops {
ChangeSet 1.1938.444.18, 2004/12/21 10:36:03-08:00, [email protected]
[PATCH] module sysfs: make module.mkobj inline
Make module.mkobj inline. As this is simpler and what's
usually done with kobjs when it's representing an entity.
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/module.h | 2 +-
kernel/module.c | 35 +++++++++++------------------------
kernel/params.c | 12 ++++--------
3 files changed, 16 insertions(+), 33 deletions(-)
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h 2005-01-07 15:41:47 -08:00
+++ b/include/linux/module.h 2005-01-07 15:41:47 -08:00
@@ -250,7 +250,7 @@
char name[MODULE_NAME_LEN];
/* Sysfs stuff. */
- struct module_kobject *mkobj;
+ struct module_kobject mkobj;
struct param_kobject *params_kobject;
/* Exported symbols */
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c 2005-01-07 15:41:47 -08:00
+++ b/kernel/module.c 2005-01-07 15:41:47 -08:00
@@ -964,9 +964,6 @@
unsigned int nloaded = 0, i;
struct module_sect_attr *sattr;
- if (!mod->mkobj)
- return;
-
/* Count loaded sections and allocate structures */
for (i = 0; i < nsect; i++)
if (sechdrs[i].sh_flags & SHF_ALLOC)
@@ -980,7 +977,7 @@
memset(mod->sect_attrs, 0, sizeof(struct module_sections));
if (kobject_set_name(&mod->sect_attrs->kobj, "sections"))
goto out;
- mod->sect_attrs->kobj.parent = &mod->mkobj->kobj;
+ mod->sect_attrs->kobj.parent = &mod->mkobj.kobj;
mod->sect_attrs->kobj.ktype = &module_sect_ktype;
if (kobject_register(&mod->sect_attrs->kobj))
goto out;
@@ -1029,11 +1026,11 @@
#ifdef CONFIG_MODULE_UNLOAD
static inline int module_add_refcnt_attr(struct module *mod)
{
- return sysfs_create_file(&mod->mkobj->kobj, &refcnt.attr);
+ return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr);
}
static void module_remove_refcnt_attr(struct module *mod)
{
- return sysfs_remove_file(&mod->mkobj->kobj, &refcnt.attr);
+ return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr);
}
#else
static inline int module_add_refcnt_attr(struct module *mod)
@@ -1052,17 +1049,13 @@
{
int err;
- mod->mkobj = kmalloc(sizeof(struct module_kobject), GFP_KERNEL);
- if (!mod->mkobj)
- return -ENOMEM;
-
- memset(&mod->mkobj->kobj, 0, sizeof(mod->mkobj->kobj));
- err = kobject_set_name(&mod->mkobj->kobj, "%s", mod->name);
+ memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
+ err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
if (err)
goto out;
- kobj_set_kset_s(mod->mkobj, module_subsys);
- mod->mkobj->mod = mod;
- err = kobject_register(&mod->mkobj->kobj);
+ kobj_set_kset_s(&mod->mkobj, module_subsys);
+ mod->mkobj.mod = mod;
+ err = kobject_register(&mod->mkobj.kobj);
if (err)
goto out;
@@ -1077,11 +1070,8 @@
return 0;
out_unreg:
- /* Calls module_kobj_release */
- kobject_unregister(&mod->mkobj->kobj);
- return err;
+ kobject_unregister(&mod->mkobj.kobj);
out:
- kfree(mod->mkobj);
return err;
}
@@ -1090,8 +1080,7 @@
module_remove_refcnt_attr(mod);
module_param_sysfs_remove(mod);
- /* Calls module_kobj_release */
- kobject_unregister(&mod->mkobj->kobj);
+ kobject_unregister(&mod->mkobj.kobj);
}
/* Free a module, remove from lists, etc (must hold module mutex). */
@@ -2089,11 +2078,9 @@
{
if (!mod || !drv)
return;
- if (!mod->mkobj)
- return;
/* Don't check return code; this call is idempotent */
- sysfs_create_link(&drv->kobj, &mod->mkobj->kobj, "module");
+ sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module");
}
EXPORT_SYMBOL(module_add_driver);
diff -Nru a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c 2005-01-07 15:41:47 -08:00
+++ b/kernel/params.c 2005-01-07 15:41:47 -08:00
@@ -567,7 +567,7 @@
{
struct param_kobject *pk;
- pk = param_sysfs_setup(mod->mkobj, kparam, num_params, 0);
+ pk = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0);
if (IS_ERR(pk))
return PTR_ERR(pk);
@@ -610,8 +610,10 @@
kobject_register(&mk->kobj);
/* no need to keep the kobject if no parameter is exported */
- if (!param_sysfs_setup(mk, kparam, num_params, name_skip))
+ if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
kobject_unregister(&mk->kobj);
+ kfree(mk);
+ }
}
/*
@@ -710,14 +712,8 @@
};
#endif
-static void module_kobj_release(struct kobject *kobj)
-{
- kfree(container_of(kobj, struct module_kobject, kobj));
-}
-
static struct kobj_type module_ktype = {
.sysfs_ops = &module_sysfs_ops,
- .release = &module_kobj_release,
};
decl_subsys(module, &module_ktype, NULL);
ChangeSet 1.1938.444.8, 2004/12/17 14:11:24-08:00, [email protected]
[PATCH] Driver Core: Add platform_get_resource_byname & platform_get_resource_byirq
Adds the ability to find a resource or irq on a platform device by its
resource name. This patch also tweaks how resource names get set.
Before, resources names were set to pdev->dev.bus_id, now that only
happens if the resource name has not been previous set.
All of this allows us to find a resource without assuming what order the
resources are in.
Signed-off-by: Kumar Gala <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/base/platform.c | 40 +++++++++++++++++++++++++++++++++++++++-
include/linux/device.h | 2 ++
2 files changed, 41 insertions(+), 1 deletion(-)
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c 2005-01-07 15:46:02 -08:00
+++ b/drivers/base/platform.c 2005-01-07 15:46:02 -08:00
@@ -58,6 +58,41 @@
}
/**
+ * platform_get_resource_byname - get a resource for a device by name
+ * @dev: platform device
+ * @type: resource type
+ * @name: resource name
+ */
+struct resource *
+platform_get_resource_byname(struct platform_device *dev, unsigned int type,
+ char *name)
+{
+ int i;
+
+ for (i = 0; i < dev->num_resources; i++) {
+ struct resource *r = &dev->resource[i];
+
+ if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
+ IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
+ if (!strcmp(r->name, name))
+ return r;
+ }
+ return NULL;
+}
+
+/**
+ * platform_get_irq - get an IRQ for a device
+ * @dev: platform device
+ * @name: IRQ name
+ */
+int platform_get_irq_byname(struct platform_device *dev, char *name)
+{
+ struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
+
+ return r ? r->start : 0;
+}
+
+/**
* platform_add_devices - add a numbers of platform devices
* @devs: array of platform devices to add
* @num: number of platform devices in array
@@ -103,7 +138,8 @@
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
- r->name = pdev->dev.bus_id;
+ if (r->name == NULL)
+ r->name = pdev->dev.bus_id;
p = NULL;
if (r->flags & IORESOURCE_MEM)
@@ -308,3 +344,5 @@
EXPORT_SYMBOL_GPL(platform_device_unregister);
EXPORT_SYMBOL_GPL(platform_get_irq);
EXPORT_SYMBOL_GPL(platform_get_resource);
+EXPORT_SYMBOL_GPL(platform_get_irq_byname);
+EXPORT_SYMBOL_GPL(platform_get_resource_byname);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2005-01-07 15:46:02 -08:00
+++ b/include/linux/device.h 2005-01-07 15:46:02 -08:00
@@ -382,6 +382,8 @@
extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
extern int platform_get_irq(struct platform_device *, unsigned int);
+extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
+extern int platform_get_irq_byname(struct platform_device *, char *);
extern int platform_add_devices(struct platform_device **, int);
extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
ChangeSet 1.1938.444.14, 2004/12/20 16:17:10-08:00, [email protected]
USB: change wTotalLength field in struct usb_config_descriptor to be __le16
Another step in the quest to get all USB data structures to be native
endian.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
arch/mips/au1000/common/usbdev.c | 4 ++--
drivers/usb/class/audio.c | 2 +-
drivers/usb/class/usb-midi.c | 4 ++--
drivers/usb/core/config.c | 2 +-
drivers/usb/core/devio.c | 2 +-
drivers/usb/core/hcd.c | 4 ++--
drivers/usb/core/hub.c | 8 ++++----
drivers/usb/core/inode.c | 2 +-
drivers/usb/host/hc_crisv10.c | 2 +-
drivers/usb/misc/usbtest.c | 5 ++---
include/linux/usb_ch9.h | 2 +-
sound/usb/usbaudio.c | 7 ++++---
sound/usb/usbmidi.c | 2 +-
13 files changed, 23 insertions(+), 23 deletions(-)
diff -Nru a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
--- a/arch/mips/au1000/common/usbdev.c 2005-01-07 15:42:19 -08:00
+++ b/arch/mips/au1000/common/usbdev.c 2005-01-07 15:42:19 -08:00
@@ -766,7 +766,7 @@
dev->conf_desc),
0);
} else {
- int len = dev->conf_desc->wTotalLength;
+ int len = le16_to_cpu(dev->conf_desc->wTotalLength);
dbg("sending whole config desc,"
" size=%d, our size=%d", desc_len, len);
desc_len = desc_len > len ? len : desc_len;
@@ -1407,7 +1407,7 @@
/*
* initialize the full config descriptor
*/
- usbdev.full_conf_desc = fcd = kmalloc(config_desc->wTotalLength,
+ usbdev.full_conf_desc = fcd = kmalloc(le16_to_cpu(config_desc->wTotalLength),
ALLOC_FLAGS);
if (!fcd) {
err("failed to alloc full config descriptor");
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/class/audio.c 2005-01-07 15:42:19 -08:00
@@ -3801,7 +3801,7 @@
* find which configuration number is active
*/
buffer = dev->rawdescriptors[dev->actconfig - dev->config];
- buflen = dev->actconfig->desc.wTotalLength;
+ buflen = le16_to_cpu(dev->actconfig->desc.wTotalLength);
s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->desc.bInterfaceNumber);
if (s) {
usb_set_intfdata (intf, s);
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/class/usb-midi.c 2005-01-07 15:42:19 -08:00
@@ -1804,7 +1804,7 @@
i = d->actconfig - d->config;
buffer = d->rawdescriptors[i];
- bufSize = d->actconfig->desc.wTotalLength;
+ bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength);
u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 1);
if ( u == NULL ) {
@@ -1892,7 +1892,7 @@
i = d->actconfig - d->config;
buffer = d->rawdescriptors[i];
- bufSize = d->actconfig->desc.wTotalLength;
+ bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength);
u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 0);
if ( u == NULL ) {
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- a/drivers/usb/core/config.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/core/config.c 2005-01-07 15:42:19 -08:00
@@ -320,7 +320,7 @@
} /* for ((buffer2 = buffer, size2 = size); ...) */
size = buffer2 - buffer;
- config->desc.wTotalLength = buffer2 - buffer0;
+ config->desc.wTotalLength = cpu_to_le16(buffer2 - buffer0);
if (n != nintf)
dev_warn(ddev, "config %d has %d interface%s, different from "
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/core/devio.c 2005-01-07 15:42:19 -08:00
@@ -148,7 +148,7 @@
/* The descriptor may claim to be longer than it
* really is. Here is the actual allocated length. */
unsigned alloclen =
- dev->config[i].desc.wTotalLength;
+ le16_to_cpu(dev->config[i].desc.wTotalLength);
len = length - (*ppos - pos);
if (len > nbytes)
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:42:19 -08:00
@@ -170,7 +170,7 @@
/* one configuration */
0x09, /* __u8 bLength; */
0x02, /* __u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* __u16 wTotalLength; */
+ 0x19, 0x00, /* __le16 wTotalLength; */
0x01, /* __u8 bNumInterfaces; (1) */
0x01, /* __u8 bConfigurationValue; */
0x00, /* __u8 iConfiguration; */
@@ -217,7 +217,7 @@
/* one configuration */
0x09, /* __u8 bLength; */
0x02, /* __u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* __u16 wTotalLength; */
+ 0x19, 0x00, /* __le16 wTotalLength; */
0x01, /* __u8 bNumInterfaces; (1) */
0x01, /* __u8 bConfigurationValue; */
0x00, /* __u8 iConfiguration; */
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:42:19 -08:00
@@ -1189,7 +1189,7 @@
/* descriptor may appear anywhere in config */
if (__usb_get_extra_descriptor (udev->rawdescriptors[0],
- udev->config[0].desc.wTotalLength,
+ le16_to_cpu(udev->config[0].desc.wTotalLength),
USB_DT_OTG, (void **) &desc) == 0) {
if (desc->bmAttributes & USB_OTG_HNP) {
unsigned port1;
@@ -2828,8 +2828,8 @@
struct usb_config_descriptor *buf;
for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
- if (len < udev->config[index].desc.wTotalLength)
- len = udev->config[index].desc.wTotalLength;
+ if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
+ len = le16_to_cpu(udev->config[index].desc.wTotalLength);
}
buf = kmalloc (len, SLAB_KERNEL);
if (buf == 0) {
@@ -2839,7 +2839,7 @@
}
for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
int length;
- int old_length = udev->config[index].desc.wTotalLength;
+ int old_length = le16_to_cpu(udev->config[index].desc.wTotalLength);
length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf,
old_length);
diff -Nru a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
--- a/drivers/usb/core/inode.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/core/inode.c 2005-01-07 15:42:19 -08:00
@@ -695,7 +695,7 @@
for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) {
struct usb_config_descriptor *config =
(struct usb_config_descriptor *)dev->rawdescriptors[i];
- i_size += le16_to_cpu ((__force __le16)config->wTotalLength);
+ i_size += le16_to_cpu(config->wTotalLength);
}
if (dev->usbfs_dentry->d_inode)
dev->usbfs_dentry->d_inode->i_size = i_size;
diff -Nru a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
--- a/drivers/usb/host/hc_crisv10.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/host/hc_crisv10.c 2005-01-07 15:42:19 -08:00
@@ -136,7 +136,7 @@
{
0x09, /* __u8 bLength; */
0x02, /* __u8 bDescriptorType; Configuration */
- 0x19, /* __u16 wTotalLength; */
+ 0x19, /* __le16 wTotalLength; */
0x00,
0x01, /* __u8 bNumInterfaces; */
0x01, /* __u8 bConfigurationValue; */
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c 2005-01-07 15:42:19 -08:00
+++ b/drivers/usb/misc/usbtest.c 2005-01-07 15:42:19 -08:00
@@ -527,10 +527,9 @@
return 0;
}
- le16_to_cpus (&config->wTotalLength);
- if (config->wTotalLength == len) /* read it all */
+ if (le16_to_cpu(config->wTotalLength) == len) /* read it all */
return 1;
- if (config->wTotalLength >= TBUF_SIZE) /* max partial read */
+ if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE) /* max partial read */
return 1;
dbg ("bogus config descriptor read size");
return 0;
diff -Nru a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
--- a/include/linux/usb_ch9.h 2005-01-07 15:42:19 -08:00
+++ b/include/linux/usb_ch9.h 2005-01-07 15:42:19 -08:00
@@ -208,7 +208,7 @@
__u8 bLength;
__u8 bDescriptorType;
- __u16 wTotalLength;
+ __le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c 2005-01-07 15:42:19 -08:00
+++ b/sound/usb/usbaudio.c 2005-01-07 15:42:19 -08:00
@@ -2933,8 +2933,8 @@
struct usb_host_config *config = dev->actconfig;
int err;
- if (get_cfg_desc(config)->wTotalLength == EXTIGY_FIRMWARE_SIZE_OLD ||
- get_cfg_desc(config)->wTotalLength == EXTIGY_FIRMWARE_SIZE_NEW) {
+ if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
+ le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
snd_printdd("sending Extigy boot sequence...\n");
/* Send message to force it to reconnect with full interface. */
err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
@@ -2946,7 +2946,8 @@
if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
err = usb_reset_configuration(dev);
if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
- snd_printdd("extigy_boot: new boot length = %d\n", get_cfg_desc(config)->wTotalLength);
+ snd_printdd("extigy_boot: new boot length = %d\n",
+ le16_to_cpu(get_cfg_desc(config)->wTotalLength));
return -ENODEV; /* quit this anyway */
}
return 0;
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c 2005-01-07 15:42:19 -08:00
+++ b/sound/usb/usbmidi.c 2005-01-07 15:42:19 -08:00
@@ -59,7 +59,7 @@
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bcdMSC[2];
- __u16 wTotalLength;
+ __le16 wTotalLength;
} __attribute__ ((packed));
struct usb_ms_endpoint_descriptor {
ChangeSet 1.1938.444.27, 2004/12/21 12:12:05-08:00, [email protected]
[PATCH] PCI: export PCI resources in sysfs
This patch exports PCI resources to userspace in the corresponding sysfs
device directory. It depends on the platform HAVE_PCI_MMAP code, and is
#ifdef'd accordingly. I've also added documentation describing the sysfs PCI
device file layout.
Signed-off-by: Jesse Barnes <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/filesystems/sysfs-pci.txt | 64 ++++++++++++++++++++++
drivers/pci/pci-sysfs.c | 92 ++++++++++++++++++++++++++++++++
include/linux/pci.h | 1
3 files changed, 157 insertions(+)
diff -Nru a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/filesystems/sysfs-pci.txt 2005-01-07 15:40:39 -08:00
@@ -0,0 +1,64 @@
+Accessing PCI device resources through sysfs
+
+sysfs, usually mounted at /sys, provides access to PCI resources on platforms
+that support it. For example, a given bus might look like this:
+
+ pci0000:17
+ |-- 0000:17:00.0
+ | |-- class
+ | |-- config
+ | |-- detach_state
+ | |-- device
+ | |-- irq
+ | |-- local_cpus
+ | |-- resource
+ | |-- resource0
+ | |-- resource1
+ | |-- resource2
+ | |-- rom
+ | |-- subsystem_device
+ | |-- subsystem_vendor
+ | `-- vendor
+ `-- detach_state
+
+The topmost element describes the PCI domain and bus number. In this case,
+the domain number is 0000 and the bus number is 17 (both values are in hex).
+This bus contains a single function device in slot 0. The domain and bus
+numbers are reproduced for convenience. Under the device directory are several
+files, each with their own function.
+
+ file function
+ ---- --------
+ class PCI class (ascii, ro)
+ config PCI config space (binary, rw)
+ detach_state connection status (bool, rw)
+ device PCI device (ascii, ro)
+ irq IRQ number (ascii, ro)
+ local_cpus nearby CPU mask (cpumask, ro)
+ resource PCI resource host addresses (ascii, ro)
+ resource0..N PCI resource N, if present (binary, mmap)
+ rom PCI ROM resource, if present (binary, ro)
+ subsystem_device PCI subsystem device (ascii, ro)
+ subsystem_vendor PCI subsystem vendor (ascii, ro)
+ vendor PCI vendor (ascii, ro)
+
+ ro - read only file
+ rw - file is readable and writable
+ mmap - file is mmapable
+ ascii - file contains ascii text
+ binary - file contains binary data
+ cpumask - file contains a cpumask type
+
+The read only files are informational, writes to them will be ignored.
+Writable files can be used to perform actions on the device (e.g. changing
+config space, detaching a device). mmapable files are available via an
+mmap of the file at offset 0 and can be used to do actual device programming
+from userspace. Note that some platforms don't support mmapping of certain
+resources, so be sure to check the return value from any attempted mmap.
+
+Supporting PCI access on new platforms
+
+In order to support PCI resource mapping as described above, Linux platform
+code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function.
+Platforms are free to only support subsets of the mmap functionality, but
+useful return codes should be provided.
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c 2005-01-07 15:40:39 -08:00
+++ b/drivers/pci/pci-sysfs.c 2005-01-07 15:40:39 -08:00
@@ -20,6 +20,7 @@
#include <linux/pci.h>
#include <linux/stat.h>
#include <linux/topology.h>
+#include <linux/mm.h>
#include "pci.h"
@@ -178,6 +179,93 @@
return count;
}
+#ifdef HAVE_PCI_MMAP
+/**
+ * pci_mmap_resource - map a PCI resource into user memory space
+ * @kobj: kobject for mapping
+ * @attr: struct bin_attribute for the file being mapped
+ * @vma: struct vm_area_struct passed into the mmap
+ *
+ * Use the regular PCI mapping routines to map a PCI resource into userspace.
+ * FIXME: write combining? maybe automatic for prefetchable regions?
+ */
+static int
+pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
+ struct vm_area_struct *vma)
+{
+ struct pci_dev *pdev = to_pci_dev(container_of(kobj,
+ struct device, kobj));
+ struct resource *res = (struct resource *)attr->private;
+ enum pci_mmap_state mmap_type;
+
+ vma->vm_pgoff += res->start >> PAGE_SHIFT;
+ mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
+
+ return pci_mmap_page_range(pdev, vma, mmap_type, 0);
+}
+
+/**
+ * pci_create_resource_files - create resource files in sysfs for @dev
+ * @dev: dev in question
+ *
+ * Walk the resources in @dev creating files for each resource available.
+ */
+static void
+pci_create_resource_files(struct pci_dev *pdev)
+{
+ int i;
+
+ /* Expose the PCI resources from this device as files */
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+ struct bin_attribute *res_attr;
+
+ /* skip empty resources */
+ if (!pci_resource_len(pdev, i))
+ continue;
+
+ res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
+ if (res_attr) {
+ pdev->res_attr[i] = res_attr;
+ /* Allocated above after the res_attr struct */
+ res_attr->attr.name = (char *)(res_attr + 1);
+ sprintf(res_attr->attr.name, "resource%d", i);
+ res_attr->size = pci_resource_len(pdev, i);
+ res_attr->attr.mode = S_IRUSR | S_IWUSR;
+ res_attr->attr.owner = THIS_MODULE;
+ res_attr->mmap = pci_mmap_resource;
+ res_attr->private = &pdev->resource[i];
+ sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+ }
+ }
+}
+
+/**
+ * pci_remove_resource_files - cleanup resource files
+ * @dev: dev to cleanup
+ *
+ * If we created resource files for @dev, remove them from sysfs and
+ * free their resources.
+ */
+static void
+pci_remove_resource_files(struct pci_dev *pdev)
+{
+ int i;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+ struct bin_attribute *res_attr;
+
+ res_attr = pdev->res_attr[i];
+ if (res_attr) {
+ sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
+ kfree(res_attr);
+ }
+ }
+}
+#else /* !HAVE_PCI_MMAP */
+static inline void pci_create_resource_files(struct pci_dev *dev) { return; }
+static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
+#endif /* HAVE_PCI_MMAP */
+
/**
* pci_write_rom - used to enable access to the PCI ROM display
* @kobj: kernel object handle
@@ -269,6 +357,8 @@
else
sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+ pci_create_resource_files(pdev);
+
/* If the device has a ROM, try to expose it in sysfs. */
if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
struct bin_attribute *rom_attr;
@@ -303,6 +393,8 @@
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+ pci_remove_resource_files(pdev);
if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
if (pdev->rom_attr) {
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h 2005-01-07 15:40:39 -08:00
+++ b/include/linux/pci.h 2005-01-07 15:40:39 -08:00
@@ -539,6 +539,7 @@
u32 saved_config_space[16]; /* config space saved at suspend time */
struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
int rom_attr_enabled; /* has display of the rom attribute been enabled? */
+ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
#ifdef CONFIG_PCI_NAMES
#define PCI_NAME_SIZE 96
#define PCI_NAME_HALF __stringify(43) /* less than half to handle slop */
ChangeSet 1.1938.439.48, 2005/01/06 17:27:58-08:00, [email protected]
[PATCH] USB: fix serial gadget oops during enumeration
This prevents the serial gadget driver from oopsing during enumeration
when spinlocks are configured, and slab poisoning is active...
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/serial.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
--- a/drivers/usb/gadget/serial.c 2005-01-07 15:38:19 -08:00
+++ b/drivers/usb/gadget/serial.c 2005-01-07 15:38:19 -08:00
@@ -2322,11 +2322,11 @@
wake_up_interruptible(&port->port_tty->read_wait);
wake_up_interruptible(&port->port_tty->write_wait);
}
+ spin_unlock_irqrestore(&port->port_lock, flags);
} else {
kfree(port);
}
- spin_unlock_irqrestore(&port->port_lock, flags);
}
}
}
ChangeSet 1.1938.439.49, 2005/01/06 17:28:25-08:00, [email protected]
[PATCH] Driver Core: handle bridged platform bus segments
During setup to access platform bus segments through bridges, the current
platform_device_register() ignores the resource parent specified by the
bridge. That means it'll always detect a (false) resource conflict with
the bridge, and fail the resource reservation step.
This patch makes that code use the specified parent resource, defaulting
to "iomem_resource" or "ioport_resource" only for a NULL parent (that is,
for devices that aren't accessed through a bridge).
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/base/platform.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c 2005-01-07 15:38:05 -08:00
+++ b/drivers/base/platform.c 2005-01-07 15:38:05 -08:00
@@ -141,11 +141,13 @@
if (r->name == NULL)
r->name = pdev->dev.bus_id;
- p = NULL;
- if (r->flags & IORESOURCE_MEM)
- p = &iomem_resource;
- else if (r->flags & IORESOURCE_IO)
- p = &ioport_resource;
+ p = r->parent;
+ if (!p) {
+ if (r->flags & IORESOURCE_MEM)
+ p = &iomem_resource;
+ else if (r->flags & IORESOURCE_IO)
+ p = &ioport_resource;
+ }
if (p && request_resource(p, r)) {
printk(KERN_ERR
ChangeSet 1.1938.444.28, 2004/12/21 16:51:39-08:00, [email protected]
[PATCH] driver core: allow struct bin_attributes in class devices
This small patch adds routines to create and remove bin_attribute files
for class devices. One intended use is for binary files corresponding to
PCI busses, like bus legacy I/O ports or ISA memory.
Signed-off-by: Jesse Barnes <[email protected]>
drivers/base/class.c | 18 ++++++++++++++++++
include/linux/device.h | 5 ++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c 2005-01-07 15:40:31 -08:00
+++ b/drivers/base/class.c 2005-01-07 15:40:31 -08:00
@@ -179,6 +179,22 @@
sysfs_remove_file(&class_dev->kobj, &attr->attr);
}
+int class_device_create_bin_file(struct class_device *class_dev,
+ struct bin_attribute *attr)
+{
+ int error = -EINVAL;
+ if (class_dev)
+ error = sysfs_create_bin_file(&class_dev->kobj, attr);
+ return error;
+}
+
+void class_device_remove_bin_file(struct class_device *class_dev,
+ struct bin_attribute *attr)
+{
+ if (class_dev)
+ sysfs_remove_bin_file(&class_dev->kobj, attr);
+}
+
static int class_device_dev_link(struct class_device * class_dev)
{
if (class_dev->dev)
@@ -576,6 +592,8 @@
EXPORT_SYMBOL_GPL(class_device_put);
EXPORT_SYMBOL_GPL(class_device_create_file);
EXPORT_SYMBOL_GPL(class_device_remove_file);
+EXPORT_SYMBOL_GPL(class_device_create_bin_file);
+EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
EXPORT_SYMBOL_GPL(class_interface_register);
EXPORT_SYMBOL_GPL(class_interface_unregister);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2005-01-07 15:40:31 -08:00
+++ b/include/linux/device.h 2005-01-07 15:40:31 -08:00
@@ -228,7 +228,10 @@
const struct class_device_attribute *);
extern void class_device_remove_file(struct class_device *,
const struct class_device_attribute *);
-
+extern int class_device_create_bin_file(struct class_device *,
+ struct bin_attribute *);
+extern void class_device_remove_bin_file(struct class_device *,
+ struct bin_attribute *);
struct class_interface {
struct list_head node;
ChangeSet 1.1938.446.32, 2004/12/17 11:42:46-08:00, [email protected]
[PATCH] USB Storage: unusual_devs: prolific atapi controler
This adds an unusual devices entry for a Prolific ATAPI-6 conmtroller
that needs the FIX_CAPACITY flag.
Signed-off-by: Alex Butcher <[email protected]>
Signed-off-by: Phil Dibowitz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/storage/unusual_devs.h | 7 +++++++
1 files changed, 7 insertions(+)
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h 2005-01-07 15:46:26 -08:00
+++ b/drivers/usb/storage/unusual_devs.h 2005-01-07 15:46:26 -08:00
@@ -539,6 +539,13 @@
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/* Reported by Alex Butcher <[email protected]> */
+UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001,
+ "Prolific Technology Inc.",
+ "ATAPI-6 Bridge Controller",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
/* Submitted by Benny Sjostrand <[email protected]> */
UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
"Minolta",
ChangeSet 1.1938.446.33, 2004/12/17 11:45:25-08:00, [email protected]
[PATCH] USB: EHCI periodic schedule tree
This implements an interrupt schedule tree for EHCI; the bug's listed
in bugzilla (http://bugme.osdl.org/show_bug.cgi?id=3374) and affects
the ability to handle certain devices and configurations.
Now multiple interrupt transfers are supported per microframe. Scheduling
prevents overcommit for reserved bandwidth and, for full/low speed devices,
the relevant transaction translator's buffer. (TT-per-port hubs are already
initialized into the multi-TT mode.)
The interrupt transfer schedule is arranged in a sparse tree, just like OHCI.
A key difference is that OHCI implements a "best fit" scheduling policy,
while this implements "first fit" for EHCI. (There's no load balancing;
it's not really needed in most users' configurations.)
There's also logic here to handle "high bandwidth" transfers, guaranteed
streaming of from 8-24 KB of data per millisecond.
Also includes some related cleanups for descheduling interrupt transfers.
Those will probably be split into a separate patch.
Against 2.6.10-rc3-bk5 ... this hasn't recently been tested much, but the
main old bug seems to be gone so it shouldn't make too much trouble.
From: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-hcd.c | 19 +-
drivers/usb/host/ehci-q.c | 12 -
drivers/usb/host/ehci-sched.c | 354 ++++++++++++++++++++++++------------------
3 files changed, 227 insertions(+), 158 deletions(-)
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c 2005-01-07 15:46:14 -08:00
+++ b/drivers/usb/host/ehci-hcd.c 2005-01-07 15:46:14 -08:00
@@ -97,7 +97,7 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
-#define DRIVER_VERSION "26 Oct 2004"
+#define DRIVER_VERSION "10 Dec 2004"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
@@ -991,12 +991,18 @@
qh = (struct ehci_qh *) urb->hcpriv;
if (!qh)
break;
- if (qh->qh_state == QH_STATE_LINKED) {
- /* messy, can spin or block a microframe ... */
- intr_deschedule (ehci, qh, 1);
- /* qh_state == IDLE */
+ switch (qh->qh_state) {
+ case QH_STATE_LINKED:
+ intr_deschedule (ehci, qh);
+ /* FALL THROUGH */
+ case QH_STATE_IDLE:
+ qh_completions (ehci, qh, NULL);
+ break;
+ default:
+ ehci_dbg (ehci, "bogus qh %p state %d\n",
+ qh, qh->qh_state);
+ goto done;
}
- qh_completions (ehci, qh, NULL);
/* reschedule QH iff another request is queued */
if (!list_empty (&qh->qtd_list)
@@ -1023,6 +1029,7 @@
// completion irqs can wait up to 1024 msec,
break;
}
+done:
spin_unlock_irqrestore (&ehci->lock, flags);
return 0;
}
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c 2005-01-07 15:46:14 -08:00
+++ b/drivers/usb/host/ehci-q.c 2005-01-07 15:46:14 -08:00
@@ -268,8 +268,7 @@
static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
-static void intr_deschedule (struct ehci_hcd *ehci,
- struct ehci_qh *qh, int wait);
+static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
/*
@@ -428,7 +427,7 @@
* except maybe high bandwidth ...
*/
if (qh->period) {
- intr_deschedule (ehci, qh, 1);
+ intr_deschedule (ehci, qh);
(void) qh_schedule (ehci, qh);
} else
start_unlink_async (ehci, qh);
@@ -664,9 +663,12 @@
qh->c_usecs = 0;
qh->gap_uf = 0;
- /* FIXME handle HS periods of less than 1 frame. */
qh->period = urb->interval >> 3;
- if (qh->period < 1) {
+ if (qh->period == 0 && urb->interval != 1) {
+ /* NOTE interval 2 or 4 uframes could work.
+ * But interval 1 scheduling is simpler, and
+ * includes high bandwidth.
+ */
dbg ("intr period %d uframes, NYET!",
urb->interval);
goto done;
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c 2005-01-07 15:46:14 -08:00
+++ b/drivers/usb/host/ehci-sched.c 2005-01-07 15:46:14 -08:00
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2003 by David Brownell
+ * Copyright (c) 2001-2004 by David Brownell
* Copyright (c) 2003 Michal Sojka, for high-speed iso transfers
*
* This program is free software; you can redistribute it and/or modify it
@@ -59,39 +59,28 @@
}
}
-/* returns true after successful unlink */
/* caller must hold ehci->lock */
-static int periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
+static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
{
union ehci_shadow *prev_p = &ehci->pshadow [frame];
__le32 *hw_p = &ehci->periodic [frame];
union ehci_shadow here = *prev_p;
- union ehci_shadow *next_p;
/* find predecessor of "ptr"; hw and shadow lists are in sync */
while (here.ptr && here.ptr != ptr) {
prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p));
- hw_p = &here.qh->hw_next;
+ hw_p = here.hw_next;
here = *prev_p;
}
/* an interrupt entry (at list end) could have been shared */
- if (!here.ptr) {
- dbg ("entry %p no longer on frame [%d]", ptr, frame);
- return 0;
- }
- // vdbg ("periodic unlink %p from frame %d", ptr, frame);
+ if (!here.ptr)
+ return;
- /* update hardware list ... HC may still know the old structure, so
- * don't change hw_next until it'll have purged its cache
+ /* update shadow and hardware lists ... the old "next" pointers
+ * from ptr may still be in use, the caller updates them.
*/
- next_p = periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
- *hw_p = here.qh->hw_next;
-
- /* unlink from shadow list; HCD won't see old structure again */
- *prev_p = *next_p;
- next_p->ptr = NULL;
-
- return 1;
+ *prev_p = *periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
+ *hw_p = *here.hw_next;
}
/* how many of the uframe's 125 usecs are allocated? */
@@ -114,7 +103,8 @@
hw_p = &q->qh->hw_next;
q = &q->qh->qh_next;
break;
- case Q_TYPE_FSTN:
+ // case Q_TYPE_FSTN:
+ default:
/* for "save place" FSTNs, count the relevant INTR
* bandwidth from the previous frame
*/
@@ -149,13 +139,11 @@
hw_p = &q->sitd->hw_next;
q = &q->sitd->sitd_next;
break;
- default:
- BUG ();
}
}
#ifdef DEBUG
if (usecs > 100)
- err ("overallocated uframe %d, periodic is %d usecs",
+ ehci_err (ehci, "uframe %d sched overrun: %d usecs\n",
frame * 8 + uframe, usecs);
#endif
return usecs;
@@ -300,64 +288,143 @@
/*-------------------------------------------------------------------------*/
-// FIXME microframe periods not yet handled
+/* periodic schedule slots have iso tds (normal or split) first, then a
+ * sparse tree for active interrupt transfers.
+ *
+ * this just links in a qh; caller guarantees uframe masks are set right.
+ * no FSTN support (yet; ehci 0.96+)
+ */
+static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+ unsigned i;
+ unsigned period = qh->period;
-static void intr_deschedule (
- struct ehci_hcd *ehci,
- struct ehci_qh *qh,
- int wait
-) {
- int status;
- unsigned frame = qh->start;
+ dev_dbg (&qh->dev->dev,
+ "link qh%d-%04x/%p start %d [%d/%d us]\n",
+ period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+ qh, qh->start, qh->usecs, qh->c_usecs);
+
+ /* high bandwidth, or otherwise every microframe */
+ if (period == 0)
+ period = 1;
+
+ for (i = qh->start; i < ehci->periodic_size; i += period) {
+ union ehci_shadow *prev = &ehci->pshadow [i];
+ u32 *hw_p = &ehci->periodic [i];
+ union ehci_shadow here = *prev;
+ u32 type = 0;
- do {
- periodic_unlink (ehci, frame, qh);
- qh_put (qh);
- frame += qh->period;
- } while (frame < ehci->periodic_size);
+ /* skip the iso nodes at list head */
+ while (here.ptr) {
+ type = Q_NEXT_TYPE (*hw_p);
+ if (type == Q_TYPE_QH)
+ break;
+ prev = periodic_next_shadow (prev, type);
+ hw_p = &here.qh->hw_next;
+ here = *prev;
+ }
+
+ /* sorting each branch by period (slow-->fast)
+ * enables sharing interior tree nodes
+ */
+ while (here.ptr && qh != here.qh) {
+ if (qh->period > here.qh->period)
+ break;
+ prev = &here.qh->qh_next;
+ hw_p = &here.qh->hw_next;
+ here = *prev;
+ }
+ /* link in this qh, unless some earlier pass did that */
+ if (qh != here.qh) {
+ qh->qh_next = here;
+ if (here.qh)
+ qh->hw_next = *hw_p;
+ wmb ();
+ prev->qh = qh;
+ *hw_p = QH_NEXT (qh->qh_dma);
+ }
+ }
+ qh->qh_state = QH_STATE_LINKED;
+ qh_get (qh);
+
+ /* update per-qh bandwidth for usbfs */
+ hcd_to_bus (&ehci->hcd)->bandwidth_allocated += qh->period
+ ? ((qh->usecs + qh->c_usecs) / qh->period)
+ : (qh->usecs * 8);
+ /* maybe enable periodic schedule processing */
+ if (!ehci->periodic_sched++)
+ return enable_periodic (ehci);
+
+ return 0;
+}
+
+static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+ unsigned i;
+ unsigned period;
+
+ // FIXME:
+ // IF this isn't high speed
+ // and this qh is active in the current uframe
+ // (and overlay token SplitXstate is false?)
+ // THEN
+ // qh->hw_info1 |= __constant_cpu_to_le32 (1 << 7 /* "ignore" */);
+
+ /* high bandwidth, or otherwise part of every microframe */
+ if ((period = qh->period) == 0)
+ period = 1;
+
+ for (i = qh->start; i < ehci->periodic_size; i += period)
+ periodic_unlink (ehci, i, qh);
+
+ /* update per-qh bandwidth for usbfs */
+ hcd_to_bus (&ehci->hcd)->bandwidth_allocated -= qh->period
+ ? ((qh->usecs + qh->c_usecs) / qh->period)
+ : (qh->usecs * 8);
+
+ dev_dbg (&qh->dev->dev,
+ "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+ qh->period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+ qh, qh->start, qh->usecs, qh->c_usecs);
+
+ /* qh->qh_next still "live" to HC */
qh->qh_state = QH_STATE_UNLINK;
qh->qh_next.ptr = NULL;
- ehci->periodic_sched--;
+ qh_put (qh);
/* maybe turn off periodic schedule */
+ ehci->periodic_sched--;
if (!ehci->periodic_sched)
- status = disable_periodic (ehci);
- else {
- status = 0;
- ehci_vdbg (ehci, "periodic schedule still enabled\n");
- }
+ (void) disable_periodic (ehci);
+}
- /*
- * If the hc may be looking at this qh, then delay a uframe
- * (yeech!) to be sure it's done.
- * No other threads may be mucking with this qh.
+static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+ unsigned wait;
+
+ qh_unlink_periodic (ehci, qh);
+
+ /* simple/paranoid: always delay, expecting the HC needs to read
+ * qh->hw_next or finish a writeback after SPLIT/CSPLIT ... and
+ * expect khubd to clean up after any CSPLITs we won't issue.
+ * active high speed queues may need bigger delays...
*/
- if (((ehci_get_frame (&ehci->hcd) - frame) % qh->period) == 0) {
- if (wait) {
- udelay (125);
- qh->hw_next = EHCI_LIST_END;
- } else {
- /* we may not be IDLE yet, but if the qh is empty
- * the race is very short. then if qh also isn't
- * rescheduled soon, it won't matter. otherwise...
- */
- ehci_vdbg (ehci, "intr_deschedule...\n");
- }
- } else
- qh->hw_next = EHCI_LIST_END;
+ if (list_empty (&qh->qtd_list)
+ || (__constant_cpu_to_le32 (0x0ff << 8)
+ & qh->hw_info2) != 0)
+ wait = 2;
+ else
+ wait = 55; /* worst case: 3 * 1024 */
+ udelay (wait);
qh->qh_state = QH_STATE_IDLE;
-
- /* update per-qh bandwidth utilization (for usbfs) */
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated -=
- (qh->usecs + qh->c_usecs) / qh->period;
-
- ehci_dbg (ehci, "descheduled qh%d/%p frame=%d count=%d, urbs=%d\n",
- qh->period, qh, frame,
- atomic_read (&qh->kref.refcount), ehci->periodic_sched);
+ qh->hw_next = EHCI_LIST_END;
+ wmb ();
}
+/*-------------------------------------------------------------------------*/
+
static int check_period (
struct ehci_hcd *ehci,
unsigned frame,
@@ -365,6 +432,8 @@
unsigned period,
unsigned usecs
) {
+ int claimed;
+
/* complete split running into next frame?
* given FSTN support, we could sometimes check...
*/
@@ -377,22 +446,26 @@
*/
usecs = 100 - usecs;
- do {
- int claimed;
-
-// FIXME delete when intr_submit handles non-empty queues
-// this gives us a one intr/frame limit (vs N/uframe)
-// ... and also lets us avoid tracking split transactions
-// that might collide at a given TT/hub.
- if (ehci->pshadow [frame].ptr)
- return 0;
-
- claimed = periodic_usecs (ehci, frame, uframe);
- if (claimed > usecs)
- return 0;
+ /* we "know" 2 and 4 uframe intervals were rejected; so
+ * for period 0, check _every_ microframe in the schedule.
+ */
+ if (unlikely (period == 0)) {
+ do {
+ for (uframe = 0; uframe < 7; uframe++) {
+ claimed = periodic_usecs (ehci, frame, uframe);
+ if (claimed > usecs)
+ return 0;
+ }
+ } while ((frame += 1) < ehci->periodic_size);
-// FIXME update to handle sub-frame periods
- } while ((frame += period) < ehci->periodic_size);
+ /* just check the specified uframe, at that period */
+ } else {
+ do {
+ claimed = periodic_usecs (ehci, frame, uframe);
+ if (claimed > usecs)
+ return 0;
+ } while ((frame += period) < ehci->periodic_size);
+ }
// success!
return 1;
@@ -407,6 +480,10 @@
)
{
int retval = -ENOSPC;
+ u8 mask;
+
+ if (qh->c_usecs && uframe >= 6) /* FSTN territory? */
+ goto done;
if (!check_period (ehci, frame, uframe, qh->period, qh->usecs))
goto done;
@@ -416,33 +493,33 @@
goto done;
}
- /* This is a split transaction; check the bandwidth available for
- * the completion too. Check both worst and best case gaps: worst
- * case is SPLIT near uframe end, and CSPLIT near start ... best is
- * vice versa. Difference can be almost two uframe times, but we
- * reserve unnecessary bandwidth (waste it) this way. (Actually
- * even better cases exist, like immediate device NAK.)
- *
- * FIXME don't even bother unless we know this TT is idle in that
- * range of uframes ... for now, check_period() allows only one
- * interrupt transfer per frame, so needn't check "TT busy" status
- * when scheduling a split (QH, SITD, or FSTN).
- *
- * FIXME ehci 0.96 and above can use FSTNs
+ /* Make sure this tt's buffer is also available for CSPLITs.
+ * We pessimize a bit; probably the typical full speed case
+ * doesn't need the second CSPLIT.
+ *
+ * NOTE: both SPLIT and CSPLIT could be checked in just
+ * one smart pass...
*/
- if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
- qh->period, qh->c_usecs))
- goto done;
- if (!check_period (ehci, frame, uframe + qh->gap_uf,
- qh->period, qh->c_usecs))
- goto done;
+ mask = 0x03 << (uframe + qh->gap_uf);
+ *c_maskp = cpu_to_le32 (mask << 8);
- *c_maskp = cpu_to_le32 (0x03 << (8 + uframe + qh->gap_uf));
- retval = 0;
+ mask |= 1 << uframe;
+ if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
+ if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
+ qh->period, qh->c_usecs))
+ goto done;
+ if (!check_period (ehci, frame, uframe + qh->gap_uf,
+ qh->period, qh->c_usecs))
+ goto done;
+ retval = 0;
+ }
done:
return retval;
}
+/* "first fit" scheduling policy used the first time through,
+ * or when the previous schedule slot can't be re-used.
+ */
static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
int status;
@@ -469,56 +546,39 @@
* uframes have enough periodic bandwidth available.
*/
if (status) {
- frame = qh->period - 1;
- do {
- for (uframe = 0; uframe < 8; uframe++) {
- status = check_intr_schedule (ehci,
- frame, uframe, qh,
- &c_mask);
- if (status == 0)
- break;
- }
- } while (status && frame--);
+ /* "normal" case, uframing flexible except with splits */
+ if (qh->period) {
+ frame = qh->period - 1;
+ do {
+ for (uframe = 0; uframe < 8; uframe++) {
+ status = check_intr_schedule (ehci,
+ frame, uframe, qh,
+ &c_mask);
+ if (status == 0)
+ break;
+ }
+ } while (status && frame--);
+
+ /* qh->period == 0 means every uframe */
+ } else {
+ frame = 0;
+ status = check_intr_schedule (ehci, 0, 0, qh, &c_mask);
+ }
if (status)
goto done;
qh->start = frame;
/* reset S-frame and (maybe) C-frame masks */
- qh->hw_info2 &= ~__constant_cpu_to_le32(0xffff);
- qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask;
+ qh->hw_info2 &= __constant_cpu_to_le32 (~0xffff);
+ qh->hw_info2 |= qh->period
+ ? cpu_to_le32 (1 << uframe)
+ : __constant_cpu_to_le32 (0xff);
+ qh->hw_info2 |= c_mask;
} else
ehci_dbg (ehci, "reused qh %p schedule\n", qh);
/* stuff into the periodic schedule */
- qh->qh_state = QH_STATE_LINKED;
- ehci_dbg(ehci,
- "scheduled qh%d/%p usecs %d/%d starting %d.%d (gap %d)\n",
- qh->period, qh, qh->usecs, qh->c_usecs,
- frame, uframe, qh->gap_uf);
- do {
- if (unlikely (ehci->pshadow [frame].ptr != 0)) {
-
-// FIXME -- just link toward the end, before any qh with a shorter period,
-// AND accommodate it already having been linked here (after some other qh)
-// AS WELL AS updating the schedule checking logic
-
- BUG ();
- } else {
- ehci->pshadow [frame].qh = qh_get (qh);
- ehci->periodic [frame] =
- QH_NEXT (qh->qh_dma);
- }
- wmb ();
- frame += qh->period;
- } while (frame < ehci->periodic_size);
-
- /* update per-qh bandwidth for usbfs */
- hcd_to_bus (&ehci->hcd)->bandwidth_allocated +=
- (qh->usecs + qh->c_usecs) / qh->period;
-
- /* maybe enable periodic schedule processing */
- if (!ehci->periodic_sched++)
- status = enable_periodic (ehci);
+ status = qh_link_periodic (ehci, qh);
done:
return status;
}
@@ -780,7 +840,7 @@
/*-------------------------------------------------------------------------*/
-/* ehci_iso_sched ops can be shared, ITD-only, or SITD-only */
+/* ehci_iso_sched ops can be ITD-only or SITD-only */
static struct ehci_iso_sched *
iso_sched_alloc (unsigned packets, int mem_flags)
@@ -1843,7 +1903,7 @@
q = q.qh->qh_next;
modified = qh_completions (ehci, temp.qh, regs);
if (unlikely (list_empty (&temp.qh->qtd_list)))
- intr_deschedule (ehci, temp.qh, 0);
+ intr_deschedule (ehci, temp.qh);
qh_put (temp.qh);
break;
case Q_TYPE_FSTN:
ChangeSet 1.1938.446.20, 2004/12/15 16:34:41-08:00, [email protected]
[PATCH] USB: usbtest and usb_dev->epmaxpacket (8/15)
Makes usbtest stop referencing the udev->epmaxpacket[] arrays.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/misc/usbtest.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c 2005-01-07 15:48:59 -08:00
+++ b/drivers/usb/misc/usbtest.c 2005-01-07 15:48:59 -08:00
@@ -954,13 +954,13 @@
case 13: // short read, resembling case 10
req.wValue = cpu_to_le16 ((USB_DT_CONFIG << 8) | 0);
// last data packet "should" be DATA1, not DATA0
- len = 1024 - udev->epmaxpacketin [0];
+ len = 1024 - udev->descriptor.bMaxPacketSize0;
expected = -EREMOTEIO;
break;
case 14: // short read; try to fill the last packet
req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0);
// device descriptor size == 18 bytes
- len = udev->epmaxpacketin [0];
+ len = udev->descriptor.bMaxPacketSize0;
switch (len) {
case 8: len = 24; break;
case 16: len = 32; break;
ChangeSet 1.1938.446.16, 2004/12/15 16:33:06-08:00, [email protected]
[PATCH] USB: ALSA and usb_dev->ep[] (4/15)
Makes an ALSA audio driver stop referencing the udev->epmaxpacket[] arrays.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
sound/usb/usx2y/usbusx2yaudio.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff -Nru a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
--- a/sound/usb/usx2y/usbusx2yaudio.c 2005-01-07 15:49:29 -08:00
+++ b/sound/usb/usx2y/usbusx2yaudio.c 2005-01-07 15:49:29 -08:00
@@ -449,12 +449,16 @@
int i;
int is_playback = subs == subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
struct usb_device *dev = subs->usX2Y->chip.dev;
+ struct usb_host_endpoint *ep;
snd_assert(!subs->prepared, return 0);
if (is_playback) { /* allocate a temporary buffer for playback */
subs->datapipe = usb_sndisocpipe(dev, subs->endpoint);
- subs->maxpacksize = dev->epmaxpacketout[subs->endpoint];
+ ep = dev->ep_out[subs->endpoint];
+ if (!ep)
+ return -EINVAL;
+ subs->maxpacksize = ep->desc.wMaxPacketSize;
if (NULL == subs->tmpbuf) {
subs->tmpbuf = kcalloc(NRPACKS, subs->maxpacksize, GFP_KERNEL);
if (NULL == subs->tmpbuf) {
@@ -464,7 +468,10 @@
}
} else {
subs->datapipe = usb_rcvisocpipe(dev, subs->endpoint);
- subs->maxpacksize = dev->epmaxpacketin[subs->endpoint];
+ ep = dev->ep_in[subs->endpoint];
+ if (!ep)
+ return -EINVAL;
+ subs->maxpacksize = ep->desc.wMaxPacketSize;
}
/* allocate and initialize data urbs */
ChangeSet 1.1938.446.8, 2004/12/15 15:10:26-08:00, [email protected]
[PATCH] USB Storage: Remove MODE_XLATE flag from unusual_devs.h
This patch removes all MODE_XLATE flags from unusual_devs.h. Since the
file is no longer close to in sync with the 2.4 version, Alan and I
agreed it's reasonable to remove all of these now.
Signed-off-by: Phil Dibowitz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/storage/unusual_devs.h | 58 ++++++++++++++++++-------------------
1 files changed, 29 insertions(+), 29 deletions(-)
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h 2005-01-07 15:50:31 -08:00
+++ b/drivers/usb/storage/unusual_devs.h 2005-01-07 15:50:31 -08:00
@@ -321,14 +321,14 @@
"Sony",
"DSC-S30/S70/S75/505V/F505/F707/F717/P8",
US_SC_SCSI, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
+ US_FL_SINGLE_LUN ),
/* This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0500,
"Sony",
"DSC-T1",
US_SC_8070, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
+ US_FL_SINGLE_LUN ),
/* Reported by [email protected] */
@@ -357,14 +357,14 @@
"Sony",
"Handycam",
US_SC_SCSI, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN | US_FL_MODE_XLATE),
+ US_FL_SINGLE_LUN ),
/* Submitted by Rajesh Kumble Nayak <[email protected]> */
UNUSUAL_DEV( 0x054c, 0x002e, 0x0500, 0x0500,
"Sony",
"Handycam HC-85",
US_SC_UFI, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN | US_FL_MODE_XLATE),
+ US_FL_SINGLE_LUN ),
UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999,
"Sony",
@@ -494,7 +494,7 @@
"Lexar",
"Jumpshot USB CF Reader",
US_SC_SCSI, US_PR_JUMPSHOT, NULL,
- US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE ),
+ US_FL_NEED_OVERRIDE ),
#endif
/* Reported by Blake Matheny <[email protected]> */
@@ -510,7 +510,7 @@
"Vivitar",
"Vivicam 35Xx",
US_SC_SCSI, US_PR_BULK, NULL,
- US_FL_FIX_INQUIRY | US_FL_MODE_XLATE),
+ US_FL_FIX_INQUIRY ),
UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100,
"TEAC",
@@ -620,48 +620,48 @@
"Datafab",
"MDCFE-B USB CF Reader",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
- /*
- * The following Datafab-based devices may or may not work
- * using the current driver...the 0xffff is arbitrary since I
- * don't know what device versions exist for these guys.
- *
- * The 0xa003 and 0xa004 devices in particular I'm curious about.
- * I'm told they exist but so far nobody has come forward to say that
- * they work with this driver. Given the success we've had getting
- * other Datafab-based cards operational with this driver, I've decided
- * to leave these two devices in the list.
- */
+/*
+ * The following Datafab-based devices may or may not work
+ * using the current driver...the 0xffff is arbitrary since I
+ * don't know what device versions exist for these guys.
+ *
+ * The 0xa003 and 0xa004 devices in particular I'm curious about.
+ * I'm told they exist but so far nobody has come forward to say that
+ * they work with this driver. Given the success we've had getting
+ * other Datafab-based cards operational with this driver, I've decided
+ * to leave these two devices in the list.
+ */
UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
"SIIG/Datafab",
"SIIG/Datafab Memory Stick+CF Reader/Writer",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
"Datafab/Unknown",
"Datafab-based Reader",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
"Datafab/Unknown",
"Datafab-based Reader",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
"PNY/Datafab",
"PNY/Datafab CF+SM Reader",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
"Simple Tech/Datafab",
"Simple Tech/Datafab CF+SM Reader",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
#endif
#ifdef CONFIG_USB_STORAGE_SDDR55
@@ -679,7 +679,7 @@
"Datafab Systems, Inc.",
"USB to CF + SM Combo (LC1)",
US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
#endif
#ifdef CONFIG_USB_STORAGE_SDDR55
/* SM part - aeb <[email protected]> */
@@ -746,7 +746,7 @@
"AIPTEK",
"PocketCAM 3Mega",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
/* Entry needed for flags. Moreover, all devices with this ID use
* bulk-only transport, but _some_ falsely report Control/Bulk instead.
@@ -757,14 +757,14 @@
"Trumpion",
"t33520 USB Flash Card Controller",
US_SC_DEVICE, US_PR_BULK, NULL,
- US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE),
+ US_FL_NEED_OVERRIDE ),
/* Trumpion Microelectronics MP3 player ([email protected]) */
UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
"Trumpion",
"MP3 player",
US_SC_RBC, US_PR_BULK, NULL,
- US_FL_MODE_XLATE),
+ 0 ),
/* aeb */
UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
@@ -777,7 +777,7 @@
"Minds@Work",
"Digital Wallet",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
/* This Pentax still camera is not conformant
* to the USB storage specification: -
@@ -892,7 +892,7 @@
"CCYU TECHNOLOGY",
"EasyDisk Portable Device",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_MODE_XLATE ),
+ 0 ),
/* Reported by Kotrla Vitezslav <[email protected]> */
UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
ChangeSet 1.1938.444.3, 2004/12/15 10:51:58-08:00, [email protected]
Documentation: fix some grammer in the stable_api_nonsense.txt file
Thanks to Andries Brouwer <[email protected]> for pointing this out.
Documentation/stable_api_nonsense.txt | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff -Nru a/Documentation/stable_api_nonsense.txt b/Documentation/stable_api_nonsense.txt
--- a/Documentation/stable_api_nonsense.txt 2005-01-07 15:51:52 -08:00
+++ b/Documentation/stable_api_nonsense.txt 2005-01-07 15:51:52 -08:00
@@ -9,7 +9,7 @@
kernel to userspace interfaces. The kernel to userspace interface is
the one that application programs use, the syscall interface. That
interface is _very_ stable over time, and will not break. I have old
-programs that were built on a pre 0.9something kernel that still works
+programs that were built on a pre 0.9something kernel that still work
just fine on the latest 2.6 kernel release. This interface is the one
that users and application programmers can count on being stable.
@@ -167,7 +167,7 @@
ensures that your driver is always buildable, and works over time, with
very little effort on your part.
-The very good side affects of having your driver in the main kernel tree
+The very good side effects of having your driver in the main kernel tree
are:
- The quality of the driver will rise as the maintenance costs (to the
original developer) will decrease.
ChangeSet 1.1938.444.32, 2004/12/22 13:06:36-08:00, [email protected]
[PATCH] PCI: add legacy resources to sysfs for pci busses
This patch adds legacy_io and legacy_mem files to the pci_bus class hierarchy
in sysfs. The files can be used (if the platform supports them) to access
legacy I/O port space and legacy ISA memory space--useful for things like x86
emulators or VGA card POSTing. The interfaces are documented in
Documentation/filesystems/sysfs-pci.txt.
Signed-off-by: Jesse Barnes <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Documentation/filesystems/sysfs-pci.txt | 26 +++++++++-
drivers/pci/pci-sysfs.c | 70 +++++++++++++++++++++++++++
drivers/pci/probe.c | 82 ++++++++++++++++++++++++++------
include/linux/pci.h | 2
4 files changed, 164 insertions(+), 16 deletions(-)
diff -Nru a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
--- a/Documentation/filesystems/sysfs-pci.txt 2005-01-07 15:40:01 -08:00
+++ b/Documentation/filesystems/sysfs-pci.txt 2005-01-07 15:40:01 -08:00
@@ -3,7 +3,7 @@
sysfs, usually mounted at /sys, provides access to PCI resources on platforms
that support it. For example, a given bus might look like this:
- pci0000:17
+ /sys/devices/pci0000:17
|-- 0000:17:00.0
| |-- class
| |-- config
@@ -56,9 +56,33 @@
from userspace. Note that some platforms don't support mmapping of certain
resources, so be sure to check the return value from any attempted mmap.
+Accessing legacy resources through sysfs
+
+Legacy I/O port and ISA memory resources are also provided in sysfs if the
+underlying platform supports them. They're located in the PCI class heirarchy,
+e.g.
+
+ /sys/class/pci_bus/0000:17/
+ |-- bridge -> ../../../devices/pci0000:17
+ |-- cpuaffinity
+ |-- legacy_io
+ `-- legacy_mem
+
+The legacy_io file is a read/write file that can be used by applications to
+do legacy port I/O. The application should open the file, seek to the desired
+port (e.g. 0x3e8) and do a read or a write of 1, 2 or 4 bytes. The legacy_mem
+file should be mmapped with an offset corresponding to the memory offset
+desired, e.g. 0xa0000 for the VGA frame buffer. The application can then
+simply dereference the returned pointer (after checking for errors of course)
+to access legacy memory space.
+
Supporting PCI access on new platforms
In order to support PCI resource mapping as described above, Linux platform
code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function.
Platforms are free to only support subsets of the mmap functionality, but
useful return codes should be provided.
+
+Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
+wishing to support legacy functionality should define it and provide
+pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
\ No newline at end of file
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c 2005-01-07 15:40:01 -08:00
+++ b/drivers/pci/pci-sysfs.c 2005-01-07 15:40:01 -08:00
@@ -179,6 +179,76 @@
return count;
}
+#ifdef HAVE_PCI_LEGACY
+/**
+ * pci_read_legacy_io - read byte(s) from legacy I/O port space
+ * @kobj: kobject corresponding to file to read from
+ * @buf: buffer to store results
+ * @off: offset into legacy I/O port space
+ * @count: number of bytes to read
+ *
+ * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
+ * callback routine (pci_legacy_read).
+ */
+ssize_t
+pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct pci_bus *bus = to_pci_bus(container_of(kobj,
+ struct class_device,
+ kobj));
+
+ /* Only support 1, 2 or 4 byte accesses */
+ if (count != 1 && count != 2 && count != 4)
+ return -EINVAL;
+
+ return pci_legacy_read(bus, off, (u32 *)buf, count);
+}
+
+/**
+ * pci_write_legacy_io - write byte(s) to legacy I/O port space
+ * @kobj: kobject corresponding to file to read from
+ * @buf: buffer containing value to be written
+ * @off: offset into legacy I/O port space
+ * @count: number of bytes to write
+ *
+ * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
+ * callback routine (pci_legacy_write).
+ */
+ssize_t
+pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct pci_bus *bus = to_pci_bus(container_of(kobj,
+ struct class_device,
+ kobj));
+ /* Only support 1, 2 or 4 byte accesses */
+ if (count != 1 && count != 2 && count != 4)
+ return -EINVAL;
+
+ return pci_legacy_write(bus, off, *(u32 *)buf, count);
+}
+
+/**
+ * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
+ * @kobj: kobject corresponding to device to be mapped
+ * @attr: struct bin_attribute for this file
+ * @vma: struct vm_area_struct passed to mmap
+ *
+ * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
+ * legacy memory space (first meg of bus space) into application virtual
+ * memory space.
+ */
+int
+pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
+ struct vm_area_struct *vma)
+{
+ struct pci_bus *bus = to_pci_bus(container_of(kobj,
+ struct class_device,
+ kobj));
+
+ return pci_mmap_legacy_page_range(bus, vma);
+}
+#endif /* HAVE_PCI_LEGACY */
+
#ifdef HAVE_PCI_MMAP
/**
* pci_mmap_resource - map a PCI resource into user memory space
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c 2005-01-07 15:40:01 -08:00
+++ b/drivers/pci/probe.c 2005-01-07 15:40:01 -08:00
@@ -27,12 +27,76 @@
LIST_HEAD(pci_devices);
+#ifdef HAVE_PCI_LEGACY
+/**
+ * pci_create_legacy_files - create legacy I/O port and memory files
+ * @b: bus to create files under
+ *
+ * Some platforms allow access to legacy I/O port and ISA memory space on
+ * a per-bus basis. This routine creates the files and ties them into
+ * their associated read, write and mmap files from pci-sysfs.c
+ */
+static void pci_create_legacy_files(struct pci_bus *b)
+{
+ b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2,
+ GFP_ATOMIC);
+ if (b->legacy_io) {
+ b->legacy_io->attr.name = "legacy_io";
+ b->legacy_io->size = 0xffff;
+ b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
+ b->legacy_io->attr.owner = THIS_MODULE;
+ b->legacy_io->read = pci_read_legacy_io;
+ b->legacy_io->write = pci_write_legacy_io;
+ class_device_create_bin_file(&b->class_dev, b->legacy_io);
+
+ /* Allocated above after the legacy_io struct */
+ b->legacy_mem = b->legacy_io + 1;
+ b->legacy_mem->attr.name = "legacy_mem";
+ b->legacy_mem->size = 1024*1024;
+ b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
+ b->legacy_mem->attr.owner = THIS_MODULE;
+ b->legacy_mem->mmap = pci_mmap_legacy_mem;
+ class_device_create_bin_file(&b->class_dev, b->legacy_mem);
+ }
+}
+
+static void pci_remove_legacy_files(struct pci_bus *b)
+{
+ class_device_remove_bin_file(&b->class_dev, b->legacy_io);
+ class_device_remove_bin_file(&b->class_dev, b->legacy_mem);
+ kfree(b->legacy_io); /* both are allocated here */
+}
+#else /* !HAVE_PCI_LEGACY */
+static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
+static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
+#endif /* HAVE_PCI_LEGACY */
+
+/*
+ * PCI Bus Class Devices
+ */
+static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
+{
+ cpumask_t cpumask = pcibus_to_cpumask((to_pci_bus(class_dev))->number);
+ int ret;
+
+ ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
+ if (ret < PAGE_SIZE)
+ buf[ret++] = '\n';
+ return ret;
+}
+static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
+
/*
* PCI Bus Class
*/
static void release_pcibus_dev(struct class_device *class_dev)
{
struct pci_bus *pci_bus = to_pci_bus(class_dev);
+
+ pci_remove_legacy_files(pci_bus);
+ class_device_remove_file(&pci_bus->class_dev,
+ &class_device_attr_cpuaffinity);
+ sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
if (pci_bus->bridge)
put_device(pci_bus->bridge);
kfree(pci_bus);
@@ -50,21 +114,6 @@
postcore_initcall(pcibus_class_init);
/*
- * PCI Bus Class Devices
- */
-static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
-{
- cpumask_t cpumask = pcibus_to_cpumask((to_pci_bus(class_dev))->number);
- int ret;
-
- ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
- if (ret < PAGE_SIZE)
- buf[ret++] = '\n';
- return ret;
-}
-static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
-
-/*
* Translate the low bits of the PCI base
* to the resource type
*/
@@ -807,6 +856,9 @@
error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
if (error)
goto class_dev_create_file_err;
+
+ /* Create legacy_io and legacy_mem files for this bus */
+ pci_create_legacy_files(b);
error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
if (error)
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h 2005-01-07 15:40:01 -08:00
+++ b/include/linux/pci.h 2005-01-07 15:40:01 -08:00
@@ -594,6 +594,8 @@
unsigned short pad2;
struct device *bridge;
struct class_device class_dev;
+ struct bin_attribute *legacy_io; /* legacy I/O for this bus */
+ struct bin_attribute *legacy_mem; /* legacy mem */
};
#define pci_bus_b(n) list_entry(n, struct pci_bus, node)
ChangeSet 1.1938.446.30, 2004/12/17 11:41:02-08:00, [email protected]
[PATCH] USB Storage: Increase Genesys delay
This is patch as436 from Alan Stern.
This patch increases the delay used for Genesys devices about 10%. At
least one user reports that this created a significant improvement in
operation.
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Matthew Dharm <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/storage/transport.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c 2005-01-07 15:46:51 -08:00
+++ b/drivers/usb/storage/transport.c 2005-01-07 15:46:51 -08:00
@@ -992,9 +992,10 @@
/* send/receive data payload, if there is any */
/* Genesys Logic interface chips need a 100us delay between the
- * command phase and the data phase */
+ * command phase and the data phase. Some devices need a little
+ * more than that, probably because of clock rate inaccuracies. */
if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS)
- udelay(100);
+ udelay(110);
if (transfer_length) {
unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ?
ChangeSet 1.1938.439.54, 2005/01/07 08:46:29-08:00, [email protected]
[PATCH] USB: usb makefile tweaks
Two minor Makefile fixes, catching up to some driver removals.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/Makefile | 3 +--
1 files changed, 1 insertion(+), 2 deletions(-)
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile 2005-01-07 15:35:42 -08:00
+++ b/drivers/usb/Makefile 2005-01-07 15:35:42 -08:00
@@ -9,7 +9,7 @@
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
obj-$(CONFIG_USB_UHCI_HCD) += host/
-obj-$(CONFIG_USB_SL811HS) += host/
+obj-$(CONFIG_USB_SL811_HCD) += host/
obj-$(CONFIG_ETRAX_USB_HOST) += host/
obj-$(CONFIG_USB_ACM) += class/
@@ -49,7 +49,6 @@
obj-$(CONFIG_USB_RTL8150) += net/
obj-$(CONFIG_USB_USBNET) += net/
-obj-$(CONFIG_USB_DC2XX) += image/
obj-$(CONFIG_USB_HPUSBSCSI) += image/
obj-$(CONFIG_USB_MDC800) += image/
obj-$(CONFIG_USB_MICROTEK) += image/
ChangeSet 1.1938.446.14, 2004/12/15 16:32:16-08:00, [email protected]
[PATCH] USB: usbcore changes for usb_dev->ep[](2/15)
This patch updates usbcore to match interface changes in the previous patch.
- udev->ep[] arrays are updated during config change events and
as needed during enumeration;
- usb_epnum_to_ep_desc() vanishes;
- so do the udev->epmaxpacket[] arrays.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hcd.c | 10 ++--------
drivers/usb/core/hub.c | 45 +++++++++++++++++++++++++--------------------
drivers/usb/core/message.c | 45 +++++++++++++++++++++++++--------------------
drivers/usb/core/urb.c | 2 +-
drivers/usb/core/usb.c | 44 +++++---------------------------------------
drivers/usb/core/usb.h | 2 --
6 files changed, 58 insertions(+), 90 deletions(-)
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:49:45 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:49:45 -08:00
@@ -807,7 +807,7 @@
down (&usb_bus_list_lock);
usb_dev->bus->root_hub = usb_dev;
- usb_dev->epmaxpacketin[0] = usb_dev->epmaxpacketout[0] = 64;
+ usb_dev->ep0.desc.wMaxPacketSize = 64;
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) {
usb_dev->bus->root_hub = NULL;
@@ -1335,14 +1335,8 @@
local_irq_disable ();
+ /* ep is already gone from udev->ep_{in,out}[]; no more submits */
rescan:
- /* (re)block new requests, as best we can */
- if (endpoint & USB_DIR_IN)
- udev->epmaxpacketin [epnum] = 0;
- else
- udev->epmaxpacketout [epnum] = 0;
-
- /* then kill any current requests */
spin_lock (&hcd_data_lock);
list_for_each_entry (urb, &dev->urb_list, urb_list) {
int tmp = urb->pipe;
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:49:45 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:49:45 -08:00
@@ -2024,6 +2024,13 @@
return portstatus;
}
+static void ep0_reinit(struct usb_device *udev)
+{
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ udev->ep_in[0] = udev->ep_out[0] = &udev->ep0;
+}
+
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN)
@@ -2041,12 +2048,8 @@
USB_REQ_SET_ADDRESS, 0, udev->devnum, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (retval == 0) {
- int m = udev->epmaxpacketin[0];
-
usb_set_device_state(udev, USB_STATE_ADDRESS);
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
- udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = m;
+ ep0_reinit(udev);
}
return retval;
}
@@ -2104,22 +2107,21 @@
*/
switch (udev->speed) {
case USB_SPEED_HIGH: /* fixed at 64 */
- i = 64;
+ udev->ep0.desc.wMaxPacketSize = 64;
break;
case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
/* to determine the ep0 maxpacket size, try to read
* the device descriptor to get bMaxPacketSize0 and
* then correct our initial guess.
*/
- i = 64;
+ udev->ep0.desc.wMaxPacketSize = 64;
break;
case USB_SPEED_LOW: /* fixed at 8 */
- i = 8;
+ udev->ep0.desc.wMaxPacketSize = 8;
break;
default:
goto fail;
}
- udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = i;
dev_info (&udev->dev,
"%s %s speed USB device using %s and address %d\n",
@@ -2194,7 +2196,10 @@
retval = -ENODEV;
goto fail;
}
- if (udev->descriptor.bMaxPacketSize0 == 0) {
+ switch (udev->descriptor.bMaxPacketSize0) {
+ case 64: case 32: case 16: case 8:
+ break;
+ default:
dev_err(&udev->dev, "device descriptor "
"read/%s, error %d\n",
"64", j);
@@ -2241,12 +2246,14 @@
goto fail;
/* Should we verify that the value is valid? */
- i = udev->descriptor.bMaxPacketSize0;
- if (udev->epmaxpacketin[0] != i) {
- dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
- udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = i;
+ /* (YES!) */
+ if (udev->ep0.desc.wMaxPacketSize
+ != udev->descriptor.bMaxPacketSize0) {
+ udev->ep0.desc.wMaxPacketSize
+ = udev->descriptor.bMaxPacketSize0;
+ dev_dbg(&udev->dev, "ep0 maxpacket = %d\n",
+ udev->ep0.desc.wMaxPacketSize);
+ ep0_reinit(udev);
}
retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
@@ -2508,8 +2515,7 @@
loop:
hub_port_disable(hdev, port);
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ ep0_reinit(udev);
release_address(udev);
usb_put_dev(udev);
if (status == -ENOTCONN)
@@ -2893,8 +2899,7 @@
/* ep0 maxpacket size may change; let the HCD know about it.
* Other endpoints will be handled by re-enumeration. */
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ ep0_reinit(udev);
ret = hub_port_init(parent, udev, port, i);
if (ret >= 0)
break;
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c 2005-01-07 15:49:45 -08:00
+++ b/drivers/usb/core/message.c 2005-01-07 15:49:45 -08:00
@@ -918,16 +918,21 @@
*/
void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
{
- if (dev && dev->bus && dev->bus->op && dev->bus->op->disable)
- dev->bus->op->disable(dev, epaddr);
- else {
- unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
-
- if (usb_endpoint_out(epaddr))
- dev->epmaxpacketout[epnum] = 0;
- else
- dev->epmaxpacketin[epnum] = 0;
+ unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+ struct usb_host_endpoint *ep;
+
+ if (!dev)
+ return;
+
+ if (usb_endpoint_out(epaddr)) {
+ ep = dev->ep_out[epnum];
+ dev->ep_out[epnum] = NULL;
+ } else {
+ ep = dev->ep_in[epnum];
+ dev->ep_in[epnum] = NULL;
}
+ if (ep && dev->bus && dev->bus->op && dev->bus->op->disable)
+ dev->bus->op->disable(dev, ep->desc.bEndpointAddress);
}
/**
@@ -1002,27 +1007,27 @@
/*
* usb_enable_endpoint - Enable an endpoint for USB communications
* @dev: the device whose interface is being enabled
- * @epd: pointer to the endpoint descriptor
+ * @ep: the endpoint
*
- * Resets the endpoint toggle and stores its maxpacket value.
+ * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers.
* For control endpoints, both the input and output sides are handled.
*/
-void usb_enable_endpoint(struct usb_device *dev,
- struct usb_endpoint_descriptor *epd)
+static void
+usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
{
- int maxsize = epd->wMaxPacketSize;
- unsigned int epaddr = epd->bEndpointAddress;
+ unsigned int epaddr = ep->desc.bEndpointAddress;
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
- int is_control = ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_CONTROL);
+ int is_control;
+ is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_CONTROL);
if (usb_endpoint_out(epaddr) || is_control) {
usb_settoggle(dev, epnum, 1, 0);
- dev->epmaxpacketout[epnum] = maxsize;
+ dev->ep_out[epnum] = ep;
}
if (!usb_endpoint_out(epaddr) || is_control) {
usb_settoggle(dev, epnum, 0, 0);
- dev->epmaxpacketin[epnum] = maxsize;
+ dev->ep_in[epnum] = ep;
}
}
@@ -1040,7 +1045,7 @@
int i;
for (i = 0; i < alt->desc.bNumEndpoints; ++i)
- usb_enable_endpoint(dev, &alt->endpoint[i].desc);
+ usb_enable_endpoint(dev, &alt->endpoint[i]);
}
/**
diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
--- a/drivers/usb/core/urb.c 2005-01-07 15:49:45 -08:00
+++ b/drivers/usb/core/urb.c 2005-01-07 15:49:45 -08:00
@@ -265,7 +265,7 @@
max = usb_maxpacket (dev, pipe, is_out);
if (max <= 0) {
dev_dbg(&dev->dev,
- "bogus endpoint ep%d%s in %s (bad maxpacket %d)",
+ "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
usb_pipeendpoint (pipe), is_out ? "out" : "in",
__FUNCTION__, max);
return -EMSGSIZE;
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c 2005-01-07 15:49:45 -08:00
+++ b/drivers/usb/core/usb.c 2005-01-07 15:49:45 -08:00
@@ -267,44 +267,6 @@
}
/**
- * usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number
- * @dev: the device whose current configuration+altsettings is considered
- * @epnum: the desired endpoint, masked with USB_DIR_IN as appropriate.
- *
- * This walks the device descriptor for the currently active configuration,
- * and returns a pointer to the endpoint with that particular endpoint
- * number, or null.
- *
- * Note that interface descriptors are not required to list endpoint
- * numbers in any standardized order, so that it would be wrong to
- * assume that ep2in precedes either ep5in, ep2out, or even ep1out.
- * This routine helps device drivers avoid such mistakes.
- */
-struct usb_endpoint_descriptor *
-usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
-{
- struct usb_host_config *config = dev->actconfig;
- int i, k;
-
- if (!config)
- return NULL;
- for (i = 0; i < config->desc.bNumInterfaces; i++) {
- struct usb_interface *intf;
- struct usb_host_interface *alt;
-
- /* only endpoints in current altsetting are active */
- intf = config->interface[i];
- alt = intf->cur_altsetting;
-
- for (k = 0; k < alt->desc.bNumEndpoints; k++)
- if (epnum == alt->endpoint[k].desc.bEndpointAddress)
- return &alt->endpoint[k].desc;
- }
-
- return NULL;
-}
-
-/**
* usb_driver_claim_interface - bind a driver to an interface
* @driver: the driver to be bound
* @iface: the interface to which it will be bound; must be in the
@@ -728,6 +690,11 @@
dev->dev.release = usb_release_dev;
dev->state = USB_STATE_ATTACHED;
+ dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
+ dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
+ /* ep0 maxpacket comes later, from device descriptor */
+ dev->ep_in[0] = dev->ep_out[0] = &dev->ep0;
+
/* Save readable and stable topology id, distinguishing devices
* by location for diagnostics, tools, driver model, etc. The
* string is a path along hub ports, from the root. Each device's
@@ -1533,7 +1500,6 @@
* These symbols are exported for device (or host controller)
* driver modules to use.
*/
-EXPORT_SYMBOL(usb_epnum_to_ep_desc);
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
diff -Nru a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
--- a/drivers/usb/core/usb.h 2005-01-07 15:49:45 -08:00
+++ b/drivers/usb/core/usb.h 2005-01-07 15:49:45 -08:00
@@ -13,8 +13,6 @@
extern void usb_release_interface_cache(struct kref *ref);
extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
-extern void usb_enable_endpoint (struct usb_device *dev,
- struct usb_endpoint_descriptor *epd);
extern void usb_enable_interface (struct usb_device *dev,
struct usb_interface *intf);
ChangeSet 1.1938.446.23, 2004/12/15 16:35:49-08:00, [email protected]
[PATCH] USB: maintain usb_host_endpoint.urb_list (11/15)
This patch changes the HCD glue code to use the URB queue now kept in
usb_host_endpoint, and matching HCD API changes.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/config.c | 1
drivers/usb/core/hcd.c | 58 +++++++++++++++++++++------------------------
drivers/usb/core/message.c | 2 -
drivers/usb/core/usb.c | 1
4 files changed, 31 insertions(+), 31 deletions(-)
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- a/drivers/usb/core/config.c 2005-01-07 15:48:36 -08:00
+++ b/drivers/usb/core/config.c 2005-01-07 15:48:36 -08:00
@@ -88,6 +88,7 @@
memcpy(&endpoint->desc, d, n);
le16_to_cpus(&endpoint->desc.wMaxPacketSize);
+ INIT_LIST_HEAD(&endpoint->urb_list);
/* Skip over any Class Specific or Vendor Specific descriptors;
* find the next endpoint or interface descriptor */
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:48:36 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:48:36 -08:00
@@ -1045,10 +1045,12 @@
{
int status;
struct usb_hcd *hcd = urb->dev->bus->hcpriv;
- struct hcd_dev *dev = urb->dev->hcpriv;
+ struct usb_host_endpoint *ep;
unsigned long flags;
- if (!hcd || !dev)
+ ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out)
+ [usb_pipeendpoint(urb->pipe)];
+ if (!hcd || !ep)
return -ENODEV;
/*
@@ -1075,7 +1077,7 @@
case USB_STATE_RUNNING:
case USB_STATE_RESUMING:
usb_get_dev (urb->dev);
- list_add_tail (&urb->urb_list, &dev->urb_list);
+ list_add_tail (&urb->urb_list, &ep->urb_list);
status = 0;
break;
default:
@@ -1129,7 +1131,7 @@
: DMA_TO_DEVICE);
}
- status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
+ status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
done:
if (unlikely (status)) {
urb_unlink (urb);
@@ -1188,7 +1190,7 @@
*/
static int hcd_unlink_urb (struct urb *urb, int status)
{
- struct hcd_dev *dev;
+ struct usb_host_endpoint *ep;
struct usb_hcd *hcd = NULL;
struct device *sys = NULL;
unsigned long flags;
@@ -1197,6 +1199,12 @@
if (!urb)
return -EINVAL;
+ if (!urb->dev || !urb->dev->bus)
+ return -ENODEV;
+ ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out)
+ [usb_pipeendpoint(urb->pipe)];
+ if (!ep)
+ return -ENODEV;
/*
* we contend for urb->status with the hcd core,
@@ -1212,15 +1220,9 @@
spin_lock_irqsave (&urb->lock, flags);
spin_lock (&hcd_data_lock);
- if (!urb->dev || !urb->dev->bus) {
- retval = -ENODEV;
- goto done;
- }
-
- dev = urb->dev->hcpriv;
sys = &urb->dev->dev;
hcd = urb->dev->bus->hcpriv;
- if (!dev || !hcd) {
+ if (hcd == NULL) {
retval = -ENODEV;
goto done;
}
@@ -1232,7 +1234,7 @@
WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT);
/* insist the urb is still queued */
- list_for_each(tmp, &dev->urb_list) {
+ list_for_each(tmp, &ep->urb_list) {
if (tmp == &urb->urb_list)
break;
}
@@ -1284,40 +1286,36 @@
* the hcd to make sure all endpoint state is gone from hardware. use for
* set_configuration, set_interface, driver removal, physical disconnect.
*
- * example: a qh stored in hcd_dev.ep[], holding state related to endpoint
+ * example: a qh stored in ep->hcpriv, holding state related to endpoint
* type, maxpacket size, toggle, halt status, and scheduling.
*/
-static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
+static void
+hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep)
{
- struct hcd_dev *dev;
- struct usb_hcd *hcd;
- struct urb *urb;
- unsigned epnum = endpoint & USB_ENDPOINT_NUMBER_MASK;
+ struct usb_hcd *hcd;
+ struct urb *urb;
- dev = udev->hcpriv;
hcd = udev->bus->hcpriv;
WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT);
local_irq_disable ();
+ /* FIXME move most of this into message.c as part of its
+ * endpoint disable logic
+ */
+
/* ep is already gone from udev->ep_{in,out}[]; no more submits */
rescan:
spin_lock (&hcd_data_lock);
- list_for_each_entry (urb, &dev->urb_list, urb_list) {
- int tmp = urb->pipe;
-
- /* ignore urbs for other endpoints */
- if (usb_pipeendpoint (tmp) != epnum)
- continue;
- /* NOTE assumption that only ep0 is a control endpoint */
- if (epnum != 0 && ((tmp ^ endpoint) & USB_DIR_IN))
- continue;
+ list_for_each_entry (urb, &ep->urb_list, urb_list) {
+ int tmp;
/* another cpu may be in hcd, spinning on hcd_data_lock
* to giveback() this urb. the races here should be
* small, but a full fix needs a new "can't submit"
* urb state.
+ * FIXME urb->reject should allow that...
*/
if (urb->status != -EINPROGRESS)
continue;
@@ -1359,7 +1357,7 @@
*/
might_sleep ();
if (hcd->driver->endpoint_disable)
- hcd->driver->endpoint_disable (hcd, dev, endpoint);
+ hcd->driver->endpoint_disable (hcd, ep);
}
/*-------------------------------------------------------------------------*/
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c 2005-01-07 15:48:36 -08:00
+++ b/drivers/usb/core/message.c 2005-01-07 15:48:36 -08:00
@@ -932,7 +932,7 @@
dev->ep_in[epnum] = NULL;
}
if (ep && dev->bus && dev->bus->op && dev->bus->op->disable)
- dev->bus->op->disable(dev, ep->desc.bEndpointAddress);
+ dev->bus->op->disable(dev, ep);
}
/**
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c 2005-01-07 15:48:36 -08:00
+++ b/drivers/usb/core/usb.c 2005-01-07 15:48:36 -08:00
@@ -688,6 +688,7 @@
dev->dev.release = usb_release_dev;
dev->state = USB_STATE_ATTACHED;
+ INIT_LIST_HEAD(&dev->ep0.urb_list);
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
/* ep0 maxpacket comes later, from device descriptor */
ChangeSet 1.1938.446.13, 2004/12/15 16:31:49-08:00, [email protected]
[PATCH] USB: usb_dev->ep[] not usb_dev->epmaxpacket (1/15)
This starts updating the usbcore interface to use endpoints in places it
previously used pipes or other representations of the endpoint.
- add new arrays of "struct usb_host_endpoint" pointers, matching
current config and altsetting
- get rid of the two epmaxpacket[] arrays; they duplicate information
that's now readily accessible from the usb_host_endpoint.
- resolve a FIXME by removing a function that only existed because
the usb_host_endpoint wasn't readily accessible.
It also removes most of an old rant about pipes, trimming it down so
only the important bits remain.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/usb.h | 73 ++++++++++++++++++++++++++--------------------------
1 files changed, 37 insertions(+), 36 deletions(-)
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h 2005-01-07 15:49:52 -08:00
+++ b/include/linux/usb.h 2005-01-07 15:49:52 -08:00
@@ -224,11 +224,6 @@
int extralen;
};
-// FIXME remove; exported only for drivers/usb/misc/auserwald.c
-// prefer usb_device->epnum[0..31]
-extern struct usb_endpoint_descriptor *
- usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
-
int __usb_get_extra_descriptor(char *buffer, unsigned size,
unsigned char type, void **ptr);
#define usb_get_extra_descriptor(ifpoint,type,ptr)\
@@ -311,17 +306,19 @@
struct semaphore serialize;
unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
- int epmaxpacketin[16]; /* INput endpoint specific maximums */
- int epmaxpacketout[16]; /* OUTput endpoint specific maximums */
struct usb_device *parent; /* our hub, unless we're the root */
struct usb_bus *bus; /* Bus we're part of */
+ struct usb_host_endpoint ep0;
struct device dev; /* Generic device interface */
struct usb_device_descriptor descriptor;/* Descriptor */
struct usb_host_config *config; /* All of the configs */
+
struct usb_host_config *actconfig;/* the active configuration */
+ struct usb_host_endpoint *ep_in[16];
+ struct usb_host_endpoint *ep_out[16];
char **rawdescriptors; /* Raw descriptors for each config */
@@ -360,6 +357,8 @@
extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
+/*-------------------------------------------------------------------------*/
+
/* for drivers using iso endpoints */
extern int usb_get_current_frame_number (struct usb_device *usb_dev);
@@ -1040,55 +1039,35 @@
/* -------------------------------------------------------------------------- */
/*
- * Calling this entity a "pipe" is glorifying it. A USB pipe
- * is something embarrassingly simple: it basically consists
- * of the following information:
- * - device number (7 bits)
- * - endpoint number (4 bits)
- * - current Data0/1 state (1 bit) [Historical; now gone]
- * - direction (1 bit)
- * - speed (1 bit) [Historical and specific to USB 1.1; now gone.]
- * - max packet size (2 bits: 8, 16, 32 or 64) [Historical; now gone.]
- * - pipe type (2 bits: control, interrupt, bulk, isochronous)
- *
- * That's 18 bits. Really. Nothing more. And the USB people have
- * documented these eighteen bits as some kind of glorious
- * virtual data structure.
+ * For various legacy reasons, Linux has a small cookie that's paired with
+ * a struct usb_device to identify an endpoint queue. Queue characteristics
+ * are defined by the endpoint's descriptor. This cookie is called a "pipe",
+ * an unsigned int encoded as:
*
- * Let's not fall in that trap. We'll just encode it as a simple
- * unsigned int. The encoding is:
- *
- * - max size: bits 0-1 [Historical; now gone.]
* - direction: bit 7 (0 = Host-to-Device [Out],
* 1 = Device-to-Host [In] ...
* like endpoint bEndpointAddress)
- * - device: bits 8-14 ... bit positions known to uhci-hcd
+ * - device address: bits 8-14 ... bit positions known to uhci-hcd
* - endpoint: bits 15-18 ... bit positions known to uhci-hcd
- * - Data0/1: bit 19 [Historical; now gone. ]
- * - lowspeed: bit 26 [Historical; now gone. ]
* - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt,
* 10 = control, 11 = bulk)
*
- * Why? Because it's arbitrary, and whatever encoding we select is really
- * up to us. This one happens to share a lot of bit positions with the UHCI
- * specification, so that much of the uhci driver can just mask the bits
- * appropriately.
+ * Given the device address and endpoint descriptor, pipes are redundant.
*/
/* NOTE: these are not the standard USB_ENDPOINT_XFER_* values!! */
+/* (yet ... they're the values used by usbfs) */
#define PIPE_ISOCHRONOUS 0
#define PIPE_INTERRUPT 1
#define PIPE_CONTROL 2
#define PIPE_BULK 3
-#define usb_maxpacket(dev, pipe, out) (out \
- ? (dev)->epmaxpacketout[usb_pipeendpoint(pipe)] \
- : (dev)->epmaxpacketin [usb_pipeendpoint(pipe)] )
-
#define usb_pipein(pipe) ((pipe) & USB_DIR_IN)
#define usb_pipeout(pipe) (!usb_pipein(pipe))
+
#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f)
#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
+
#define usb_pipetype(pipe) (((pipe) >> 30) & 3)
#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT)
@@ -1115,6 +1094,28 @@
#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+
+/*-------------------------------------------------------------------------*/
+
+static inline __u16
+usb_maxpacket(struct usb_device *udev, int pipe, int is_out)
+{
+ struct usb_host_endpoint *ep;
+ unsigned epnum = usb_pipeendpoint(pipe);
+
+ if (is_out) {
+ WARN_ON(usb_pipein(pipe));
+ ep = udev->ep_out[epnum];
+ } else {
+ WARN_ON(usb_pipeout(pipe));
+ ep = udev->ep_in[epnum];
+ }
+ if (!ep)
+ return 0;
+
+ /* NOTE: only 0x07ff bits are for packet size... */
+ return ep->desc.wMaxPacketSize;
+}
/* -------------------------------------------------------------------------- */
ChangeSet 1.1938.444.33, 2004/12/22 13:50:21-08:00, [email protected]
[PATCH] driver core: Fix up vesafb failure probing.
bus.c file invokes a probe callback for most devices in a list, then checks
for -ENODEV return ("no such device"), if so it remains silent. However, some
drivers (including vesafb.c) may return -ENXIO ("no such device or address"),
which is indeed error -6.
I shut up the warning with the attached patch, that basically ignores
both -ENODEV and -ENXIO.
>From https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=125890
original patch by: Alessandro Suardi <[email protected]>
Signed-off-by: Dave Jones <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/base/bus.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c 2005-01-07 15:39:53 -08:00
+++ b/drivers/base/bus.c 2005-01-07 15:39:53 -08:00
@@ -326,7 +326,7 @@
if (!error)
/* success, driver matched */
return 1;
- if (error != -ENODEV)
+ if (error != -ENODEV && error != -ENXIO)
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
ChangeSet 1.1938.444.16, 2004/12/20 17:25:07-08:00, [email protected]
USB Gadget: fix up simple sparse warnings (NULL stuff) in dummy_hcd.c driver
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/dummy_hcd.c | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:42:02 -08:00
+++ b/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:42:02 -08:00
@@ -375,7 +375,7 @@
dum = ep_to_dummy (ep);
spin_lock_irqsave (&dum->lock, flags);
- ep->desc = 0;
+ ep->desc = NULL;
retval = 0;
nuke (dum, ep);
spin_unlock_irqrestore (&dum->lock, flags);
@@ -391,12 +391,12 @@
struct dummy_request *req;
if (!_ep)
- return 0;
+ return NULL;
ep = usb_ep_to_dummy_ep (_ep);
req = kmalloc (sizeof *req, mem_flags);
if (!req)
- return 0;
+ return NULL;
memset (req, 0, sizeof *req);
INIT_LIST_HEAD (&req->queue);
return &req->req;
@@ -432,7 +432,7 @@
dum = ep_to_dummy (ep);
if (!dum->driver)
- return 0;
+ return NULL;
retval = kmalloc (bytes, mem_flags);
*dma = (dma_addr_t) retval;
return retval;
@@ -516,7 +516,7 @@
struct dummy *dum;
int retval = -EINVAL;
unsigned long flags;
- struct dummy_request *req = 0;
+ struct dummy_request *req = NULL;
if (!_ep || !_req)
return retval;
@@ -730,7 +730,7 @@
ep->ep.maxpacket = ~0;
ep->last_io = jiffies;
ep->gadget = &dum->gadget;
- ep->desc = 0;
+ ep->desc = NULL;
INIT_LIST_HEAD (&ep->queue);
}
@@ -744,8 +744,8 @@
dev_dbg (dummy_dev(dum), "binding gadget driver '%s'\n",
driver->driver.name);
if ((retval = driver->bind (&dum->gadget)) != 0) {
- dum->driver = 0;
- dum->gadget.dev.driver = 0;
+ dum->driver = NULL;
+ dum->gadget.dev.driver = NULL;
return retval;
}
@@ -807,7 +807,7 @@
spin_unlock_irqrestore (&dum->lock, flags);
driver->unbind (&dum->gadget);
- dum->driver = 0;
+ dum->driver = NULL;
device_release_driver (&dum->gadget.dev);
@@ -1117,7 +1117,7 @@
struct urb *urb;
struct dummy_request *req;
u8 address;
- struct dummy_ep *ep = 0;
+ struct dummy_ep *ep = NULL;
int type;
urb = urbp->urb;
@@ -1372,7 +1372,7 @@
ep->already_seen = ep->setup_stage = 0;
spin_unlock (&dum->lock);
- usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, 0);
+ usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, NULL);
spin_lock (&dum->lock);
goto restart;
@@ -1644,7 +1644,7 @@
INIT_LIST_HEAD (&dum->urbp_list);
- root = usb_alloc_dev (0, &hcd->self, 0);
+ root = usb_alloc_dev (NULL, &hcd->self, 0);
if (!root)
return -ENOMEM;
@@ -1696,7 +1696,7 @@
static int dummy_h_get_frame (struct usb_hcd *hcd)
{
- return dummy_g_get_frame (0);
+ return dummy_g_get_frame (NULL);
}
static const struct hc_driver dummy_hcd = {
ChangeSet 1.1938.439.53, 2005/01/07 08:45:52-08:00, [email protected]
[PATCH] USB: definitions for USB2 debug device, debug port
This provides basic definitions to support "USB2 Debug Devices", as
supported by certain EHCI root hub ports (from ALI, Intel, NVidia, and
other vendors). Docs are available at Intel's USB spec webpage.
The basic idea is to help debug "legacy free" systems, with no serial port
for a console or debugger to use. The USB debug port uses PIO to send and
receive at most 8 bytes of high speed data at a time, so it can support one
I/O channel without needing _any_ of the usbcore infrastructure, or DMA,
or IRQs. (Cost can be 2KB rather than ~150KB.)
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci.h | 24 ++++++++++++++++++++++++
include/linux/usb_ch9.h | 13 +++++++++++++
2 files changed, 37 insertions(+)
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h 2005-01-07 15:36:12 -08:00
+++ b/drivers/usb/host/ehci.h 2005-01-07 15:36:12 -08:00
@@ -264,6 +264,30 @@
#define PORT_CONNECT (1<<0) /* device connected */
} __attribute__ ((packed));
+/* Appendix C, Debug port ... intended for use with special "debug devices"
+ * that can help if there's no serial console. (nonstandard enumeration.)
+ */
+struct ehci_dbg_port {
+ u32 control;
+#define DBGP_OWNER (1<<30)
+#define DBGP_ENABLED (1<<28)
+#define DBGP_DONE (1<<16)
+#define DBGP_INUSE (1<<10)
+#define DBGP_ERRCODE(x) (((x)>>7)&0x0f)
+# define DBGP_ERR_BAD 1
+# define DBGP_ERR_SIGNAL 2
+#define DBGP_ERROR (1<<6)
+#define DBGP_GO (1<<5)
+#define DBGP_OUT (1<<4)
+#define DBGP_LEN(x) (((x)>>0)&0x0f)
+ u32 pids;
+#define DBGP_PID_GET(x) (((x)>>16)&0xff)
+#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok));
+ u32 data03;
+ u32 data47;
+ u32 address;
+#define DBGP_EPADDR(dev,ep) (((dev)<<8)|(ep));
+} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
diff -Nru a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
--- a/include/linux/usb_ch9.h 2005-01-07 15:36:12 -08:00
+++ b/include/linux/usb_ch9.h 2005-01-07 15:36:12 -08:00
@@ -79,6 +79,7 @@
#define USB_DEVICE_B_HNP_ENABLE 3 /* dev may initiate HNP */
#define USB_DEVICE_A_HNP_SUPPORT 4 /* RH port supports HNP */
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* other RH port does */
+#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
@@ -320,6 +321,18 @@
/* from usb_otg_descriptor.bmAttributes */
#define USB_OTG_SRP (1 << 0)
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
+struct usb_debug_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ /* bulk endpoints with 8 byte maxpacket */
+ __u8 bDebugInEndpoint;
+ __u8 bDebugOutEndpoint;
+};
/*-------------------------------------------------------------------------*/
ChangeSet 1.1938.439.50, 2005/01/06 17:28:51-08:00, [email protected]
[PATCH] USB: ov511.c - vfree() checking cleanups
ov511.c vfree() checking cleanups.
Signed-off by: James Lamanna <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/media/ov511.c | 12 ++++--------
1 files changed, 4 insertions(+), 8 deletions(-)
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c 2005-01-07 15:37:39 -08:00
+++ b/drivers/usb/media/ov511.c 2005-01-07 15:37:39 -08:00
@@ -3908,15 +3908,11 @@
ov->fbuf = NULL;
}
- if (ov->rawfbuf) {
- vfree(ov->rawfbuf);
- ov->rawfbuf = NULL;
- }
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
- if (ov->tempfbuf) {
- vfree(ov->tempfbuf);
- ov->tempfbuf = NULL;
- }
+ vfree(ov->tempfbuf);
+ ov->tempfbuf = NULL;
for (i = 0; i < OV511_NUMSBUF; i++) {
if (ov->sbuf[i].data) {
ChangeSet 1.1938.444.19, 2004/12/21 10:36:20-08:00, [email protected]
[PATCH] module sysfs: expand module_attribute methods
Modify module_attribute show/store methods to accept self
argument to enable further extensions.
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/module.h | 5 +++--
kernel/module.c | 3 ++-
kernel/params.c | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h 2005-01-07 15:41:39 -08:00
+++ b/include/linux/module.h 2005-01-07 15:41:39 -08:00
@@ -48,8 +48,9 @@
struct module_attribute {
struct attribute attr;
- ssize_t (*show)(struct module *, char *);
- ssize_t (*store)(struct module *, const char *, size_t count);
+ ssize_t (*show)(struct module_attribute *, struct module *, char *);
+ ssize_t (*store)(struct module_attribute *, struct module *,
+ const char *, size_t count);
};
struct module_kobject
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c 2005-01-07 15:41:39 -08:00
+++ b/kernel/module.c 2005-01-07 15:41:39 -08:00
@@ -651,7 +651,8 @@
}
EXPORT_SYMBOL_GPL(symbol_put_addr);
-static ssize_t show_refcnt(struct module *mod, char *buffer)
+static ssize_t show_refcnt(struct module_attribute *mattr,
+ struct module *mod, char *buffer)
{
/* sysfs holds a reference */
return sprintf(buffer, "%u\n", module_refcount(mod)-1);
diff -Nru a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c 2005-01-07 15:41:39 -08:00
+++ b/kernel/params.c 2005-01-07 15:41:39 -08:00
@@ -693,7 +693,7 @@
if (!try_module_get(mk->mod))
return -ENODEV;
- ret = attribute->show(mk->mod, buf);
+ ret = attribute->show(attribute, mk->mod, buf);
module_put(mk->mod);
ChangeSet 1.1938.446.12, 2004/12/15 16:01:46-08:00, [email protected]
[PATCH] ftdi_sio: Add sysfs attributes for event character and latency
Setting the event character and latency timer can greatly improve
performance for some applications which use the ftdi_sio module (a
serial->USB converter). The following patch adds sysfs attributes,
exposing these configuration registers.
Signed-off-by: Edwin Olson ([email protected])
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/ftdi_sio.c | 133 ++++++++++++++++++++++++++++++++++++++++++
drivers/usb/serial/ftdi_sio.h | 51 ++++++++++++++++
2 files changed, 184 insertions(+)
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c 2005-01-07 15:50:00 -08:00
+++ b/drivers/usb/serial/ftdi_sio.c 2005-01-07 15:50:00 -08:00
@@ -1174,6 +1174,135 @@
} /* set_serial_info */
+
+/*
+ * ***************************************************************************
+ * Sysfs Attribute
+ * ***************************************************************************
+ */
+
+ssize_t show_latency_timer(struct device *dev, char *buf)
+{
+ struct usb_serial_port *port = to_usb_serial_port(dev);
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ struct usb_device *udev;
+ unsigned short latency = 0;
+ int rv = 0;
+
+ udev = to_usb_device(dev);
+
+ dbg("%s",__FUNCTION__);
+
+ rv = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, 0),
+ FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
+ FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
+ 0, priv->interface,
+ (char*) &latency, 1, WDR_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "Unable to read latency timer: %i", rv);
+ return -EIO;
+ }
+ return sprintf(buf, "%i\n", latency);
+}
+
+/* Write a new value of the latency timer, in units of milliseconds. */
+ssize_t store_latency_timer(struct device *dev, const char *valbuf, size_t count)
+{
+ struct usb_serial_port *port = to_usb_serial_port(dev);
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ struct usb_device *udev;
+ char buf[1];
+ int v = simple_strtoul(valbuf, NULL, 10);
+ int rv = 0;
+
+ udev = to_usb_device(dev);
+
+ dbg("%s: setting latency timer = %i", __FUNCTION__, v);
+
+ rv = usb_control_msg(udev,
+ usb_sndctrlpipe(udev, 0),
+ FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
+ FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
+ v, priv->interface,
+ buf, 0, WDR_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "Unable to write latency timer: %i", rv);
+ return -EIO;
+ }
+
+ return count;
+}
+
+/* Write an event character directly to the FTDI register. The ASCII
+ value is in the low 8 bits, with the enable bit in the 9th bit. */
+ssize_t store_event_char(struct device *dev, const char *valbuf, size_t count)
+{
+ struct usb_serial_port *port = to_usb_serial_port(dev);
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ struct usb_device *udev;
+ char buf[1];
+ int v = simple_strtoul(valbuf, NULL, 10);
+ int rv = 0;
+
+ udev = to_usb_device(dev);
+
+ dbg("%s: setting event char = %i", __FUNCTION__, v);
+
+ rv = usb_control_msg(udev,
+ usb_sndctrlpipe(udev, 0),
+ FTDI_SIO_SET_EVENT_CHAR_REQUEST,
+ FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE,
+ v, priv->interface,
+ buf, 0, WDR_TIMEOUT);
+
+ if (rv < 0) {
+ dbg("Unable to write event character: %i", rv);
+ return -EIO;
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(latency_timer, S_IWUGO | S_IRUGO, show_latency_timer, store_latency_timer);
+static DEVICE_ATTR(event_char, S_IWUGO, NULL, store_event_char);
+
+void create_sysfs_attrs(struct usb_serial *serial)
+{
+ struct ftdi_private *priv;
+ struct usb_device *udev;
+
+ dbg("%s",__FUNCTION__);
+
+ priv = usb_get_serial_port_data(serial->port[0]);
+ udev = serial->dev;
+
+ if (priv->chip_type == FT232BM) {
+ dbg("sysfs attributes for FT232BM");
+ device_create_file(&udev->dev, &dev_attr_event_char);
+ device_create_file(&udev->dev, &dev_attr_latency_timer);
+ }
+}
+
+void remove_sysfs_attrs(struct usb_serial *serial)
+{
+ struct ftdi_private *priv;
+ struct usb_device *udev;
+
+ dbg("%s",__FUNCTION__);
+
+ priv = usb_get_serial_port_data(serial->port[0]);
+ udev = serial->dev;
+
+ if (priv->chip_type == FT232BM) {
+ device_remove_file(&udev->dev, &dev_attr_event_char);
+ device_remove_file(&udev->dev, &dev_attr_latency_timer);
+ }
+
+}
+
/*
* ***************************************************************************
* FTDI driver specific functions
@@ -1291,6 +1420,8 @@
priv->chip_type = FT232BM;
priv->baud_base = 48000000 / 2; /* Would be / 16, but FT232BM supports multiple of 0.125 divisor fractions! */
+ create_sysfs_attrs(serial);
+
return (0);
} /* ftdi_FT232BM_startup */
@@ -1384,6 +1515,8 @@
dbg("%s", __FUNCTION__);
+ remove_sysfs_attrs(serial);
+
/* all open ports are closed at this point
* (by usbserial.c:__serial_close, which calls ftdi_close)
*/
diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
--- a/drivers/usb/serial/ftdi_sio.h 2005-01-07 15:50:00 -08:00
+++ b/drivers/usb/serial/ftdi_sio.h 2005-01-07 15:50:00 -08:00
@@ -249,6 +249,8 @@
#define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modern status register */
#define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */
#define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */
+#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */
+#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */
/* Port interface code for FT2232C */
#define INTERFACE_A 1
@@ -502,6 +504,55 @@
* and the lValue field contains the XON character.
*/
+/*
+ * FTDI_SIO_GET_LATENCY_TIMER
+ *
+ * Set the timeout interval. The FTDI collects data from the slave
+ * device, transmitting it to the host when either A) 62 bytes are
+ * received, or B) the timeout interval has elapsed and the buffer
+ * contains at least 1 byte. Setting this value to a small number
+ * can dramatically improve performance for applications which send
+ * small packets, since the default value is 16ms.
+ */
+#define FTDI_SIO_GET_LATENCY_TIMER_REQUEST FTDI_SIO_GET_LATENCY_TIMER
+#define FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE 0xC0
+
+/*
+ * BmRequestType: 1100 0000b
+ * bRequest: FTDI_SIO_GET_LATENCY_TIMER
+ * wValue: 0
+ * wIndex: Port
+ * wLength: 0
+ * Data: latency (on return)
+ */
+
+/*
+ * FTDI_SIO_SET_LATENCY_TIMER
+ *
+ * Set the timeout interval. The FTDI collects data from the slave
+ * device, transmitting it to the host when either A) 62 bytes are
+ * received, or B) the timeout interval has elapsed and the buffer
+ * contains at least 1 byte. Setting this value to a small number
+ * can dramatically improve performance for applications which send
+ * small packets, since the default value is 16ms.
+ */
+#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER
+#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40
+
+/*
+ * BmRequestType: 0100 0000b
+ * bRequest: FTDI_SIO_SET_LATENCY_TIMER
+ * wValue: Latency (milliseconds)
+ * wIndex: Port
+ * wLength: 0
+ * Data: None
+ *
+ * wValue:
+ * B0..7 Latency timer
+ * B8..15 0
+ *
+ */
+
/*
* FTDI_SIO_SET_EVENT_CHAR
*
ChangeSet 1.1938.446.3, 2004/12/15 14:13:03-08:00, [email protected]
[PATCH] USB: serial driver for TI USB 3410/5052 chips (2/3)
* New USB serial driver for devices based on the TI USB
3410 and 5052 chips. (2/3)
Signed-off-by: Al Borchers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/ti_fw_3410.h | 885 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 885 insertions(+)
diff -Nru a/drivers/usb/serial/ti_fw_3410.h b/drivers/usb/serial/ti_fw_3410.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_fw_3410.h 2005-01-07 15:51:09 -08:00
@@ -0,0 +1,885 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 3410 USB Serial Driver Firmware Header
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * 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.
+ */
+
+#ifndef _TI_FW_3410_H_
+#define _TI_FW_3410_H_
+
+/* firmware 9/10/04 FW3410_Special_StartWdogOnStartPort */
+
+static unsigned char ti_fw_3410[] = {
+0xC2, 0x35, /* firmware image length excluding header, little endian */
+0x00, /* placeholder for checksum */
+
+0x02,0x00,0x1e,0x02,0x1a,0xdb,0xff,0xff,0xff,0xff,0xff,0x02,0x32,0xcb,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x33,0x76,0x75,0x81,
+0xce,0x90,0xfd,0xe8,0x85,0x83,0xa0,0x12,0x34,0xea,0xec,0x4d,0x60,0x6a,0x78,0xab,
+0x80,0x03,0x76,0x00,0x18,0xb8,0x9c,0xfa,0x78,0x7f,0x80,0x03,0x76,0x00,0x18,0xb8,
+0x65,0xfa,0x78,0x20,0x80,0x03,0x76,0x00,0x18,0xb8,0x20,0xfa,0x90,0xfd,0xdd,0xae,
+0x83,0xaf,0x82,0x90,0xfb,0xf8,0x12,0x00,0xa1,0x60,0x05,0xe4,0xf0,0xa3,0x80,0xf6,
+0x90,0xfd,0xe8,0xa8,0x82,0x90,0xfd,0xe8,0xa9,0x82,0xe8,0xc3,0x99,0x50,0x05,0x76,
+0x00,0x08,0x80,0xf6,0x90,0x00,0xff,0x12,0x00,0xaa,0x90,0x01,0x03,0x12,0x00,0xaa,
+0x90,0x01,0x07,0x12,0x00,0xaa,0x90,0x01,0x0b,0x12,0x00,0xc8,0x90,0x01,0x11,0x12,
+0x00,0xc8,0x90,0x01,0x17,0x12,0x00,0xc8,0x75,0xd0,0x00,0x12,0x33,0xc8,0x02,0x01,
+0x1d,0xef,0x65,0x82,0x70,0x03,0xee,0x65,0x83,0x22,0xe4,0x93,0xf8,0x74,0x01,0x93,
+0xf9,0x74,0x02,0x93,0xfe,0x74,0x03,0x93,0xf5,0x82,0x8e,0x83,0xe8,0x69,0x70,0x01,
+0x22,0xe4,0x93,0xf6,0xa3,0x08,0x80,0xf4,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74,
+0x02,0x93,0xfe,0x74,0x03,0x93,0xff,0x74,0x04,0x93,0xf8,0x74,0x05,0x93,0xf5,0x82,
+0x88,0x83,0x12,0x00,0xa1,0x70,0x01,0x22,0xe4,0x93,0xa3,0xa8,0x83,0xa9,0x82,0x8c,
+0x83,0x8d,0x82,0xf0,0xa3,0xac,0x83,0xad,0x82,0x88,0x83,0x89,0x82,0x80,0xe3,0x21,
+0x21,0x04,0x92,0x80,0x80,0x04,0x92,0xac,0xae,0x04,0x92,0xfd,0xe8,0x04,0x94,0x04,
+0x94,0xfb,0xf3,0x04,0x99,0x04,0x94,0xfb,0xf3,0x04,0xf9,0x04,0xf9,0x80,0xfe,0xd0,
+0xf0,0x30,0xf0,0x09,0x20,0xf3,0x03,0xf6,0x80,0x10,0xf7,0x80,0x0d,0x30,0xf1,0x09,
+0x20,0xf3,0x03,0xf2,0x80,0x04,0xf3,0x80,0x01,0xf0,0x20,0xf4,0x04,0xfc,0xd0,0xe0,
+0xcc,0x22,0xcc,0xc0,0xe0,0x12,0x01,0x5a,0x02,0x01,0x4b,0xbc,0x00,0x05,0xd0,0xf0,
+0xac,0xf0,0x22,0xc3,0x13,0xdc,0xfc,0x02,0x01,0x21,0xbf,0x00,0x09,0xed,0x25,0x82,
+0x75,0xf0,0x01,0xf8,0xe6,0x22,0xbf,0x01,0x0f,0xed,0x25,0x82,0xf5,0x82,0xee,0x35,
+0x83,0xf5,0x83,0x75,0xf0,0x04,0xe0,0x22,0xed,0x25,0x82,0x75,0xf0,0x02,0xf8,0xe2,
+0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xc3,0xe4,0x93,0xa3,0xc5,0xf0,0x95,0xf0,0xc0,
+0xe0,0xc3,0xd0,0xf0,0xe4,0x93,0xa3,0x95,0xf0,0x40,0x12,0xa3,0xa3,0xc3,0xe5,0xf0,
+0x33,0x50,0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0x50,0x02,0x05,0x83,0x74,0x01,0x93,
+0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xe4,0x93,0x70,
+0x09,0x74,0x01,0x93,0x70,0x04,0xa3,0xa3,0x80,0x0c,0x74,0x02,0x93,0x65,0xf0,0x60,
+0x05,0xa3,0xa3,0xa3,0x80,0xe7,0x74,0x01,0x93,0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,
+0x12,0x02,0x5b,0x02,0x01,0xf2,0x12,0x02,0xaf,0x02,0x01,0xf2,0x12,0x02,0xd3,0x02,
+0x01,0xf2,0x30,0xe0,0x07,0x20,0xe3,0x02,0xe6,0x22,0xe7,0x22,0x30,0xe1,0x07,0x20,
+0xe3,0x02,0xe2,0x22,0xe3,0x22,0x30,0xe2,0x02,0xe0,0x22,0xe4,0x93,0x22,0x12,0x02,
+0xd3,0x02,0x02,0x1a,0x12,0x02,0xaf,0x02,0x02,0x1a,0xab,0xf0,0x12,0x02,0x24,0xcb,
+0xc5,0xf0,0xcb,0x22,0x30,0xe0,0x10,0x20,0xe3,0x06,0xe6,0xf5,0xf0,0x08,0xe6,0x22,
+0xe7,0xf5,0xf0,0x09,0xe7,0x19,0x22,0x30,0xe1,0x10,0x20,0xe3,0x06,0xe2,0xf5,0xf0,
+0x08,0xe2,0x22,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x30,0xe2,0x06,0xe0,0xf5,0xf0,
+0xa3,0xe0,0x22,0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x00,0x03,0x74,0x09,
+0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x74,0x04,0x22,0xbb,0x02,0x07,0x89,0x82,
+0x8a,0x83,0x74,0x10,0x22,0x74,0x0a,0x22,0x02,0x02,0x7b,0xbb,0x00,0x07,0xe9,0x25,
+0x82,0xf8,0x74,0x01,0x22,0xbb,0x01,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x04,0x22,0xbb,0x02,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x10,0x22,0xe9,0x25,0x82,0xf8,0x74,0x02,0x22,0x02,0x02,0xaf,0xbf,
+0x00,0x05,0xed,0xf8,0x74,0x01,0x22,0xbf,0x01,0x07,0x8d,0x82,0x8e,0x83,0x74,0x04,
+0x22,0xbf,0x02,0x07,0x8d,0x82,0x8e,0x83,0x74,0x10,0x22,0xed,0xf8,0x74,0x02,0x22,
+0x02,0x02,0xd3,0xbf,0x00,0x07,0xed,0x25,0x82,0xf8,0x74,0x01,0x22,0xbf,0x01,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x04,0x22,0xbf,0x02,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x10,0x22,0xed,0x25,0x82,
+0xf8,0x74,0x02,0x22,0x02,0x03,0x07,0xc0,0xe0,0x12,0x02,0x5b,0x02,0x03,0x1f,0xc0,
+0xe0,0x12,0x02,0xaf,0x02,0x03,0x1f,0xc0,0xe0,0x12,0x02,0xd3,0x02,0x03,0x1f,0x30,
+0xe0,0x0b,0x20,0xe3,0x04,0xd0,0xe0,0xf6,0x22,0xd0,0xe0,0xf7,0x22,0x30,0xe1,0x0b,
+0x20,0xe3,0x04,0xd0,0xe0,0xf2,0x22,0xd0,0xe0,0xf3,0x22,0xd0,0xe0,0xf0,0x22,0xc9,
+0xcd,0xc9,0xca,0xce,0xca,0xcb,0xcf,0xcb,0x12,0x03,0x52,0xed,0xf9,0xee,0xfa,0xef,
+0xfb,0x22,0xbb,0x00,0x2f,0xbf,0x00,0x0a,0xfa,0xed,0xf8,0xe7,0xf6,0x08,0x09,0xda,
+0xfa,0x22,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x03,0x6f,0x09,0xa3,0xe7,
+0xf0,0xd8,0xfa,0x22,0x02,0x03,0x7a,0xfa,0xed,0xf8,0xe7,0xf2,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x03,0x84,0xbb,0x01,0x4d,0xbf,0x00,0x14,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0x96,0x08,0xa3,0xe0,0xf6,0xd9,0xfa,0x22,0x02,0x03,0xa7,0xbf,0x01,
+0x22,0x8d,0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe0,
+0xa3,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xea,0xd8,0xe8,0x22,
+0x02,0x03,0xca,0x8d,0x82,0x8e,0x83,0xf9,0xed,0xf8,0xe0,0xf2,0x08,0xa3,0xd9,0xfa,
+0x22,0x02,0x03,0xd4,0xbb,0x02,0x4d,0xbf,0x00,0x12,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0xe6,0x08,0xa3,0xe4,0x93,0xf6,0xd9,0xf9,0x22,0xbf,0x01,0x23,0x8d,
+0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe4,0x93,0xa3,
+0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xe9,0xd8,0xe7,0x22,0x02,
+0x04,0x19,0x89,0x82,0x8a,0x83,0xf9,0xed,0xf8,0xe4,0x93,0xf2,0x08,0xa3,0xd9,0xf9,
+0x22,0x02,0x04,0x2a,0xbf,0x00,0x0d,0xfa,0xed,0xf8,0xe3,0xf6,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x04,0x34,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x04,0x41,0x09,
+0xa3,0xe3,0xf0,0xd8,0xfa,0x22,0x02,0x04,0x4c,0xfa,0xed,0xf8,0xe3,0xf2,0x08,0x09,
+0xda,0xfa,0x22,0x02,0x04,0x56,0xe6,0xfb,0x08,0xe6,0xfa,0x08,0xe6,0xf9,0x04,0xf6,
+0x18,0x70,0x01,0x06,0x22,0xe6,0xff,0x08,0xe6,0xfe,0x08,0xe6,0xfd,0x22,0xef,0xf0,
+0xa3,0xee,0xf0,0xa3,0xed,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,
+0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xfd,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xf9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xf9,0x00,0x61,0x05,0x68,0x00,
+0x26,0x05,0x8f,0x00,0x33,0x0a,0x00,0x00,0x61,0x0a,0x6c,0x00,0x66,0x15,0x1d,0x00,
+0x61,0x0c,0xf0,0x00,0x61,0x09,0xa0,0x00,0x61,0x09,0xd7,0x00,0x61,0x0d,0xb7,0x00,
+0x61,0x0b,0xe8,0x00,0x61,0x0a,0x13,0x00,0x61,0x0a,0x48,0x00,0x61,0x17,0x15,0x00,
+0x33,0x17,0x28,0x00,0x34,0x1d,0xf6,0x00,0x43,0x1e,0xa1,0x00,0x44,0x20,0x0e,0x00,
+0x44,0x1f,0xfc,0x00,0x47,0x1e,0xc8,0x00,0x47,0x1f,0x6d,0x00,0x4d,0x1f,0xbe,0x00,
+0x4f,0x1e,0xea,0x00,0x58,0x32,0x56,0x00,0x61,0x7c,0xcc,0x7d,0xff,0x12,0x1c,0xa7,
+0x22,0x90,0xff,0xfc,0xe0,0x20,0xe7,0x2d,0xc2,0xaf,0xae,0x59,0xaf,0x58,0x75,0x5a,
+0x20,0xe5,0x5a,0x14,0xc5,0x5a,0x60,0x19,0xe4,0xfe,0x7f,0x05,0xee,0x4f,0xce,0x24,
+0xff,0xce,0xcf,0x34,0xff,0xcf,0x60,0x07,0xe4,0x90,0xff,0x92,0xf0,0x80,0xed,0x80,
+0xe0,0x8e,0x59,0x8f,0x58,0x22,0x12,0x05,0x01,0x7d,0x07,0x7c,0xb7,0x12,0x32,0x72,
+0x7d,0x0f,0x7c,0x6e,0x12,0x32,0x8c,0x78,0x9d,0x7a,0x06,0xe4,0xf6,0x08,0xda,0xfc,
+0x7a,0x06,0x12,0x05,0xc4,0x7c,0x03,0x12,0x0e,0x4c,0x12,0x21,0x4a,0xe4,0xfe,0xff,
+0x7c,0x0f,0x12,0x31,0xfb,0xd2,0xa8,0x22,0x12,0x30,0xe6,0xe4,0x90,0xfc,0x38,0xf0,
+0x90,0xff,0xf0,0xe0,0x30,0xe4,0x08,0x74,0x01,0x90,0xfc,0x39,0xf0,0x80,0x05,0xe4,
+0x90,0xfc,0x39,0xf0,0x7d,0x0a,0x7c,0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,
+0x30,0xe6,0x90,0xfc,0x39,0xe0,0x14,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x44,0x10,0xf0,
+0x7c,0x00,0x12,0x25,0xbf,0x80,0x19,0x90,0xfc,0x39,0xe0,0x70,0x0e,0x90,0xff,0xf0,
+0xe0,0x54,0xef,0xf0,0x7c,0x00,0x12,0x25,0xbf,0x80,0x05,0x7c,0x17,0x12,0x25,0xbf,
+0x12,0x31,0x69,0x22,0x90,0xff,0xf0,0xe0,0x54,0xab,0xf0,0x90,0xff,0xf0,0xe0,0x44,
+0x20,0xf0,0x22,0x8c,0x37,0x8d,0x36,0x78,0x82,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,
+0xec,0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x80,0xf6,0x78,0x82,0xe6,
+0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,
+0x54,0x0f,0xfc,0x7d,0x80,0x12,0x17,0x46,0x78,0x80,0xe6,0x70,0x0d,0xad,0x3a,0xae,
+0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,
+0xf0,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x1e,0x78,0x82,0xe6,0xfd,0x08,0xe6,
+0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x44,
+0x01,0x90,0xff,0xf3,0xf0,0x02,0x06,0xd0,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,
+0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,
+0xf0,0x80,0x2b,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,
+0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,
+0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x82,
+0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,
+0x0e,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,
+0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,
+0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x44,0x01,0x90,0xff,0xf3,0xf0,
+0x78,0x83,0xe6,0x24,0x03,0xf6,0x18,0xe6,0x34,0x00,0xf6,0x78,0x80,0xe6,0x24,0xfe,
+0x50,0x09,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x07,0x90,0xff,0xf0,0xe0,0x44,
+0x02,0xf0,0xe4,0x90,0xff,0xf1,0xf0,0x78,0x81,0x76,0x00,0x78,0x80,0xe6,0x24,0xff,
+0xfc,0xe4,0x34,0xff,0xfd,0x78,0x81,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,
+0x80,0xcd,0x64,0x80,0x9d,0x40,0x2f,0x12,0x08,0xa4,0x40,0x0f,0x78,0x81,0xe6,0xad,
+0x3a,0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,
+0x78,0x82,0x86,0x83,0x08,0x86,0x82,0xec,0xf0,0x78,0x81,0x06,0xa3,0x78,0x82,0xa6,
+0x83,0x08,0xa6,0x82,0x80,0xb5,0x12,0x08,0xa4,0x40,0x0f,0x78,0x81,0xe6,0xad,0x3a,
+0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,
+0x82,0x86,0x83,0x08,0x86,0x82,0xec,0xf0,0x78,0x80,0xe6,0xad,0x3a,0xae,0x39,0xaf,
+0x38,0x12,0x03,0x0f,0x7c,0x00,0x22,0x8c,0x37,0x8d,0x36,0x78,0x82,0xed,0xf6,0x08,
+0xec,0xf6,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x81,
+0xf6,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,
+0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x81,0x12,0x17,0x46,0x78,0x81,0xe6,0x70,
+0x03,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,0x54,
+0xfd,0xf0,0x80,0x1b,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,
+0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x90,0xff,0xf3,0xf0,0x80,0x5b,0x78,
+0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,
+0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,0xf0,0x80,0x21,0x78,0x82,0xe6,0xfd,0x08,0xe6,
+0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,
+0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x82,0xe6,0xfd,0x08,
+0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,
+0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x83,0xe6,0x24,0x0a,0xf6,
+0x18,0xe6,0x34,0x00,0xf6,0x78,0x80,0x76,0x00,0x78,0x81,0xe6,0x24,0xff,0xfc,0xe4,
+0x34,0xff,0xfd,0x78,0x80,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,
+0x64,0x80,0x9d,0x40,0x21,0x78,0x82,0x86,0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,
+0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x80,0x06,0x78,0x83,0x06,0xe6,
+0x18,0x70,0x01,0x06,0x80,0xc3,0x90,0xff,0xf0,0xe0,0x44,0x01,0xf0,0x78,0x82,0x86,
+0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,
+0x22,0x7c,0x00,0x22,0x90,0xff,0xf0,0xe0,0x20,0xe7,0x12,0x90,0xff,0xf0,0xe0,0x30,
+0xe5,0x09,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x90,
+0xff,0xf0,0xe0,0x20,0xe3,0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,
+0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x8c,0x42,0x8d,0x41,0x7c,0x00,
+0xed,0x54,0xf0,0xfd,0xec,0x70,0x03,0xed,0x64,0x30,0x70,0x05,0x75,0x3e,0x03,0x80,
+0x03,0x75,0x3e,0x04,0xac,0x3e,0x12,0x0f,0x69,0x75,0x83,0x00,0x85,0x83,0x40,0xe5,
+0x41,0x54,0x0f,0xf5,0x3f,0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x03,0x70,0x35,0xe5,
+0x3e,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x02,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,
+0xe0,0x30,0xe6,0x05,0x12,0x10,0x4b,0x80,0x19,0xe5,0x3e,0x24,0x9d,0xf8,0xc6,0x54,
+0xfb,0xf6,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,
+0x0f,0xf0,0x80,0x59,0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x04,0x70,0x48,0xe5,0x3e,
+0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x02,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,
+0x30,0xe5,0x07,0xac,0x42,0xad,0x41,0x12,0x1c,0x3c,0xe5,0x42,0x30,0xe2,0x15,0x78,
+0xad,0xe6,0x30,0xe0,0x0f,0x78,0xad,0xe6,0x30,0xe1,0x09,0xe4,0xff,0x04,0xfe,0x7c,
+0x04,0x12,0x31,0xfb,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0x74,0x0f,0xf0,0x80,0x07,0xe4,0xfc,0x7d,0xee,0x12,0x1c,0x3c,0xc2,0x03,0x22,
+0x12,0x30,0xe6,0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x90,0xfc,0x38,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0xfc,0x39,0xf0,0xc2,0x03,0x7d,0x02,0x7c,0x00,
+0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,
+0x9d,0xf8,0xe6,0x30,0xe1,0x07,0x7c,0x13,0x12,0x25,0xbf,0x80,0x0f,0x90,0xfc,0x39,
+0xe0,0xfd,0x78,0x95,0xe6,0xfc,0x12,0x13,0xc8,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,
+0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x7d,0x00,0x12,0x0f,0x09,0x12,0x25,0xbf,0x12,
+0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,0x9d,0xf8,0xe6,0x30,
+0xe2,0x07,0x7c,0x13,0x12,0x25,0xbf,0x80,0x1b,0x78,0x95,0xe6,0x24,0x9d,0xf8,0xe6,
+0x20,0xe1,0x07,0x7c,0x12,0x12,0x25,0xbf,0x80,0x0a,0x78,0x95,0xe6,0xfc,0x12,0x13,
+0xec,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,
+0x24,0x9d,0xf8,0xe6,0x20,0xe2,0x07,0x7c,0x11,0x12,0x25,0xbf,0x80,0x0a,0x78,0x95,
+0xe6,0xfc,0x12,0x14,0xed,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,
+0x95,0xec,0xf6,0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x90,0xfc,0x3f,0xf0,0x78,0xa9,0xe6,0x24,0x0a,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0xfc,0x40,0xf0,0x78,0xa9,0xe6,0x24,0x03,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x62,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x63,0x8c,0x61,0xe4,0xec,0x33,0x33,0x54,
+0x01,0x78,0x95,0xf6,0x60,0x08,0xe5,0x62,0x30,0xe1,0x03,0x78,0x95,0x06,0x78,0x95,
+0xe6,0x90,0xfc,0x41,0xf0,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0x54,0x0c,0xfc,0xed,0x54,0xe6,0x8c,0x65,0xf5,0x64,
+0xe5,0x61,0x30,0xe5,0x03,0x43,0x65,0x01,0xe5,0x62,0x20,0xe5,0x0e,0xe5,0x61,0x54,
+0x7f,0x70,0x08,0xe5,0x61,0x20,0xe7,0x03,0x43,0x65,0x02,0xe5,0x61,0x30,0xe3,0x03,
+0x43,0x65,0x10,0xe5,0x61,0x30,0xe2,0x03,0x43,0x65,0x20,0xe5,0x61,0x54,0x03,0x60,
+0x03,0x43,0x65,0x40,0xe5,0x61,0x30,0xe1,0x03,0x43,0x65,0x80,0xe5,0x61,0x30,0xe4,
+0x03,0x43,0x64,0x01,0xe5,0x61,0x30,0xe6,0x03,0x43,0x64,0x08,0xe5,0x62,0x20,0xe4,
+0x0e,0xe5,0x61,0x54,0x7f,0x70,0x08,0xe5,0x61,0x20,0xe7,0x03,0x43,0x64,0x10,0x53,
+0x65,0xfb,0x53,0x64,0x79,0xad,0x64,0xe5,0x65,0x90,0xfc,0x3a,0xcd,0xf0,0xa3,0xcd,
+0xf0,0xe5,0x63,0x30,0xe3,0x0d,0xe5,0x63,0x54,0x30,0xc4,0x54,0x0f,0x90,0xfc,0x3d,
+0xf0,0x80,0x05,0xe4,0x90,0xfc,0x3d,0xf0,0xe5,0x63,0x54,0x03,0x90,0xfc,0x3c,0xf0,
+0xe5,0x63,0x54,0x04,0xc3,0x13,0x90,0xfc,0x3e,0xf0,0x90,0xfc,0x3c,0xe0,0x70,0x0e,
+0x7d,0x35,0x7e,0xfc,0x7f,0x01,0x74,0x01,0x90,0x00,0x09,0x12,0x01,0x42,0x78,0xa9,
+0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7c,0x00,0xfd,0x78,
+0xa9,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7f,0x00,0x4c,
+0xfe,0xef,0x4d,0x90,0xfc,0x38,0xf0,0xa3,0xce,0xf0,0xce,0xc2,0x03,0x7d,0x0a,0x7c,
+0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x78,
+0x9a,0x76,0x01,0x08,0x76,0xfc,0x08,0x76,0x38,0x78,0x97,0x76,0x0c,0x78,0x9a,0x12,
+0x04,0x65,0x12,0x02,0x14,0x78,0x98,0xcb,0xf6,0xcb,0x08,0xf6,0x7f,0x00,0xef,0x24,
+0xea,0x40,0x1f,0xe4,0xef,0x25,0xe0,0x90,0x35,0x2c,0xfd,0x93,0xcd,0x04,0x93,0x78,
+0x99,0x66,0x70,0x03,0xed,0x18,0x66,0x70,0x06,0x78,0x97,0x76,0x00,0x80,0x03,0x0f,
+0x80,0xdc,0x78,0x96,0xef,0xf6,0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x02,0x12,0x02,
+0x0e,0x78,0x98,0xcb,0xf6,0xcb,0x08,0xf6,0x54,0x04,0xcb,0x54,0x86,0x4b,0x60,0x04,
+0x78,0x97,0x76,0x0b,0x78,0x99,0xe6,0x30,0xe3,0x13,0x78,0x9a,0x12,0x04,0x65,0x90,
+0x00,0x05,0x12,0x01,0xec,0x24,0xfb,0x50,0x04,0x78,0x97,0x76,0x0d,0x78,0x99,0xe6,
+0x54,0xc0,0x7d,0x00,0x64,0xc0,0x4d,0x70,0x04,0x78,0x97,0x76,0x0b,0x78,0x9a,0x12,
+0x04,0x65,0x90,0x00,0x04,0x12,0x01,0xec,0x24,0xfc,0x50,0x04,0x78,0x97,0x76,0x0f,
+0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x06,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,
+0x97,0x76,0x0e,0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x09,0x12,0x01,0xec,0x24,0xfd,
+0x50,0x04,0x78,0x97,0x76,0x0a,0x78,0x97,0xe6,0x70,0x2a,0x78,0x95,0xe6,0xfc,0x12,
+0x0f,0x69,0x78,0x9a,0x12,0x04,0x65,0x78,0xa7,0xe6,0xf9,0x78,0xa6,0xe6,0xfa,0x7b,
+0x01,0x74,0x0a,0x78,0x00,0x12,0x03,0x3f,0xc2,0x03,0x78,0x95,0xe6,0xfc,0x12,0x11,
+0x07,0x78,0x97,0xec,0xf6,0x78,0x97,0xe6,0xfc,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,
+0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x12,0x0f,0x69,0x78,0x95,0xe6,0x24,0xfd,0x75,
+0xf0,0x0a,0xa4,0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xac,0x82,0xad,0x83,
+0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,
+0x03,0xa7,0xc2,0x03,0x78,0x95,0xe6,0xfc,0x12,0x11,0x07,0x12,0x31,0x69,0x22,0x8d,
+0x2b,0x8c,0x2a,0xed,0x60,0x40,0x75,0x27,0x01,0x75,0x29,0x48,0x75,0x28,0xff,0xe5,
+0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,
+0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,
+0x28,0xaf,0x27,0x74,0x80,0x90,0x00,0x06,0x12,0x03,0x17,0x74,0x80,0x90,0x00,0x02,
+0x12,0x03,0x17,0x12,0x0f,0xb7,0xe5,0x2b,0x14,0x60,0x3b,0x75,0x27,0x01,0x75,0x29,
+0x08,0x75,0x28,0xff,0xe5,0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,
+0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,
+0xf5,0x28,0xad,0x29,0xae,0x28,0xaf,0x27,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0xe4,
+0x90,0x00,0x02,0x12,0x03,0x17,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,
+0x9d,0xf8,0xe6,0x30,0xe2,0x09,0x78,0x95,0xe6,0xfc,0x12,0x14,0xed,0xd2,0x00,0x78,
+0x95,0xe6,0xfc,0x12,0x0f,0x69,0x78,0x96,0x76,0x00,0x90,0xfc,0x39,0xe0,0x30,0xe7,
+0x04,0x78,0x96,0x76,0x01,0x78,0x96,0xe6,0xfd,0x78,0x95,0xe6,0xfc,0x12,0x0d,0x2f,
+0xc2,0x03,0x30,0x00,0x07,0x78,0x95,0xe6,0xfc,0x12,0x13,0xec,0x7c,0x00,0x12,0x25,
+0xbf,0x12,0x31,0x69,0x22,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x01,0xf0,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x30,0xe0,0x02,0x80,0xed,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xf8,0xf0,0x78,0xa9,0xe6,0x24,0x02,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0xc2,0x03,0x8c,0x58,
+0x12,0x0f,0x69,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x5d,0x7a,0x35,0x7b,0x0a,
+0x78,0x01,0x12,0x03,0xf5,0x12,0x0e,0x05,0xac,0x58,0x7d,0x02,0x12,0x0d,0x2f,0xc2,
+0x03,0xac,0x58,0x12,0x11,0x07,0x22,0x8d,0x53,0x8e,0x52,0x8f,0x51,0x8c,0x50,0x12,
+0x0f,0x69,0x75,0x4f,0x00,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x20,0xe4,0x1f,0xe5,0x4f,0x24,0xf6,0x40,0x19,0x05,0x4f,0xc2,0x03,
+0x7c,0x18,0x12,0x32,0xa9,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,0xac,0x50,
+0x12,0x0f,0x69,0x80,0xd0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x20,0xe4,0x05,0xc2,0x03,0x7c,0x02,0x22,0x78,0xa9,0xe6,0x24,0x05,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0x60,0x16,0x78,0xa9,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0xf0,0xc2,0x03,
+0x7c,0x01,0x22,0x78,0xa8,0x86,0x83,0x08,0x86,0x82,0xe0,0xad,0x53,0xae,0x52,0xaf,
+0x51,0x12,0x03,0x0f,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x31,0x8c,0x30,0x12,0x14,0xed,
+0xe5,0x31,0x60,0x0f,0xe5,0x30,0xb4,0x03,0x0a,0x7c,0x01,0x12,0x24,0xee,0x7c,0x81,
+0x12,0x24,0xee,0xac,0x30,0x12,0x0f,0x69,0xe5,0x31,0x60,0x1a,0x78,0xaa,0x86,0x83,
+0x08,0x86,0x82,0xe0,0x54,0xe7,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0xe7,0xf0,0xac,
+0x30,0x7d,0x02,0x12,0x0d,0x2f,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x67,0x7a,
+0x35,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0xc2,0x03,0xe5,0x30,0x24,0x9d,0xf8,0xc6,
+0x54,0xfd,0xf6,0xac,0x30,0x12,0x11,0x07,0x22,0x8c,0x26,0x30,0x03,0x05,0x12,0x32,
+0x48,0x80,0xf8,0x7c,0x0a,0x12,0x31,0x5b,0xd2,0x03,0xe5,0x26,0x24,0xfd,0x78,0xa3,
+0xf6,0x70,0x07,0x78,0xaa,0x76,0xff,0x08,0x76,0xe0,0x78,0xa3,0xe6,0x75,0xf0,0x10,
+0xa4,0xad,0xf0,0xfc,0x24,0xa0,0x78,0xa9,0xf6,0xed,0x34,0xff,0x18,0xf6,0x78,0xa3,
+0xe6,0x75,0xf0,0x0a,0xa4,0x24,0x00,0xfc,0xe4,0x34,0xfc,0xfd,0x78,0xa6,0xed,0xf6,
+0x08,0xec,0xf6,0x12,0x31,0xf4,0x22,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x30,0xe7,0x22,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0x78,0xaa,0x86,0x83,0x08,
+0x86,0x82,0xe0,0x54,0x7f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,
+0x82,0xf5,0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x54,0xf8,0xf0,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xab,0xe6,0x24,0x05,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x22,0x78,0xaa,0x86,0x83,0x08,
+0x86,0x82,0xe0,0x54,0x3f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,
+0x82,0xf5,0x83,0xe0,0x54,0x3f,0xf0,0x78,0xa3,0xe6,0x24,0xa4,0xf8,0xe6,0xfc,0x78,
+0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa3,
+0xe6,0x24,0xa4,0xf8,0xe6,0xfc,0x78,0xab,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x54,0xfb,0x44,0x02,0xf5,0x26,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe5,0x03,0x43,0x26,0x01,0x78,0xa9,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,0x03,0x12,0x0f,
+0xb7,0xe5,0x26,0xfc,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0x74,0x0f,0xf0,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xe0,0x44,0x80,0xf0,0xa3,0xa3,
+0xa3,0xa3,0xe0,0x44,0x80,0xf0,0x22,0x8c,0x2a,0x12,0x0f,0x69,0x78,0xa7,0xe6,0x24,
+0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x0a,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa7,0xe6,0x24,0x07,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x09,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0xe0,
+0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0x78,0xa9,0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xee,0xf0,0xec,0xfe,0x78,0xa9,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xee,0xf0,0x8c,0x29,0x8d,0x28,0xc3,0xec,0x94,0x05,0xed,0x94,
+0x0c,0x40,0x05,0x75,0x27,0x7c,0x80,0x33,0xd3,0xe5,0x29,0x94,0x01,0xe5,0x28,0x94,
+0x03,0x40,0x05,0x75,0x27,0x3c,0x80,0x23,0xd3,0xe5,0x29,0x94,0x81,0xe5,0x28,0x94,
+0x01,0x40,0x05,0x75,0x27,0x18,0x80,0x13,0xd3,0xe5,0x29,0x94,0x60,0xe5,0x28,0x94,
+0x00,0x40,0x05,0x75,0x27,0x0c,0x80,0x03,0x75,0x27,0x08,0xaf,0x27,0xe4,0xef,0x54,
+0x7c,0x44,0x83,0xff,0x8f,0x27,0xe5,0x27,0xfc,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xab,0xe6,0x24,0x05,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xa3,0xe6,
+0x24,0xa4,0xf8,0xec,0xf6,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xa3,0xe0,0x30,0xe3,0x17,0x53,0x27,0xc7,0x78,0xa7,0xe6,0x24,0x05,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0x35,0x58,0x93,0x42,0x27,0x53,0x27,
+0xfb,0x78,0xa7,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x60,
+0x03,0x43,0x27,0x04,0x53,0x27,0xfc,0x78,0xa7,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x42,0x27,0x43,0x27,0x80,0xe5,0x27,0xfc,0x78,0xa9,0xe6,
+0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,
+0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,
+0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe1,0x05,0x53,0x27,
+0xdf,0x80,0x03,0x43,0x27,0x20,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x30,0xe4,0x05,0x53,0x27,0xef,0x80,0x03,0x43,0x27,0x10,0x78,
+0xa7,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xb4,0x02,0x03,
+0x43,0x27,0x02,0xe5,0x27,0xfc,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x70,0x05,0x53,0x27,0x7f,0x80,0x03,0x43,0x27,0x80,0x78,0xa7,0xe6,
+0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe0,0x05,0x43,
+0x27,0x20,0x80,0x03,0x53,0x27,0xdf,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x30,0xe3,0x05,0x43,0x27,0x40,0x80,0x03,0x53,0x27,0xbf,
+0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,
+0x05,0x43,0x27,0x10,0x80,0x03,0x53,0x27,0xef,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe4,0x05,0x43,0x27,0x08,0x80,0x03,
+0x53,0x27,0xf7,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xa3,0xe0,0x30,0xe5,0x05,0x43,0x27,0x04,0x80,0x03,0x53,0x27,0xfb,0x78,0xa7,0xe6,
+0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe6,0x05,0x43,
+0x27,0x01,0x80,0x03,0x53,0x27,0xfe,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe7,0x05,0x43,0x27,0x02,0x80,0x03,0x53,0x27,
+0xfd,0xe5,0x27,0xfc,0x78,0xa9,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xec,0xf0,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x27,0x8c,0x26,0xed,0x54,0x03,0x14,
+0x60,0x03,0x7c,0x10,0x22,0xe5,0x27,0x54,0x7c,0x24,0xfc,0x40,0x03,0x7c,0x0b,0x22,
+0xe5,0x26,0x24,0x9d,0xf8,0xc6,0x44,0x02,0xf6,0x7c,0x00,0x22,0x8c,0x30,0x12,0x0f,
+0x69,0xe5,0x30,0x24,0x9d,0xf8,0xe6,0x20,0xe2,0x4f,0xac,0x30,0x7d,0x02,0x12,0x0d,
+0x2f,0xe5,0x30,0x24,0xfe,0x44,0x28,0xfc,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xec,
+0xf0,0xaf,0x83,0xe5,0x82,0x24,0x04,0xfe,0xe4,0x3f,0xff,0xec,0x8e,0x82,0x8f,0x83,
+0xf0,0x7c,0x03,0x8c,0x2c,0xe5,0x2c,0xfc,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x2c,0xfc,0x78,0xab,0xe6,0x24,0x05,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x75,0x2d,0x01,0x75,0x2f,0x48,0x75,
+0x2e,0xff,0xe5,0x30,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,
+0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x2f,0x2c,0xf5,0x2f,0xe5,0x2e,0x3d,0xf5,0x2e,
+0x78,0xab,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xe7,
+0xf5,0x2c,0xad,0x2f,0xae,0x2e,0xaf,0x2d,0xe4,0x90,0x00,0x02,0x12,0x03,0x17,0xe4,
+0x90,0x00,0x06,0x12,0x03,0x17,0x12,0x01,0xe6,0x30,0xe5,0x03,0x43,0x2c,0x10,0xe5,
+0x2c,0xfc,0x78,0xab,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,
+0xf0,0x12,0x10,0x4b,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xc2,0x03,0xfc,0xe5,0x30,0x24,0x9d,0xf8,0xc6,0x44,0x04,0xf6,0x8c,0x2c,
+0xe5,0x30,0x54,0x0f,0xc4,0x54,0xf0,0x7e,0x00,0xff,0xee,0xef,0x44,0x04,0x7d,0x00,
+0xff,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0x12,0x1c,0xa7,0x7c,0x00,0x22,0x8c,0x2f,0x12,
+0x0f,0x69,0x12,0x0f,0xeb,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,0x08,0xf0,
+0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0x08,0xf0,0xac,0x2f,0x7d,0x02,0x12,0x0d,0x2f,0xc2,
+0x03,0xe5,0x2f,0x24,0x9d,0xf8,0xc6,0x54,0xfb,0xf6,0x7c,0x00,0x22,0x12,0x30,0xe6,
+0x78,0x96,0xec,0xf6,0xec,0x24,0x9d,0xf8,0xe6,0x30,0xe1,0x0a,0x7d,0x00,0x7c,0x13,
+0x12,0x25,0x26,0x12,0x31,0x69,0x78,0x96,0xe6,0x24,0x9d,0xf8,0xc6,0x44,0x01,0xf6,
+0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0x96,0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,
+0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0x78,0xa6,0xe6,0xfa,0x08,0xe6,0xf9,
+0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x67,
+0x7a,0x35,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0x12,0x0f,0xb7,0xc2,0x03,0x78,0x96,
+0xe6,0xfc,0x12,0x11,0x07,0x78,0x95,0xec,0xf6,0xec,0x60,0x0a,0x7d,0x00,0x7c,0x08,
+0x12,0x25,0x26,0x12,0x31,0x69,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0xa9,0xe6,
+0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x10,0x54,0xdf,0xfc,
+0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,
+0x95,0xec,0xf6,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,
+0x69,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,
+0xef,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,
+0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x10,
+0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,
+0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x20,0xf0,
+0xc2,0x03,0x7c,0xf0,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0xa9,
+0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x15,0xc2,
+0x03,0x78,0x96,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,0x12,0x31,0xfb,0x12,0x31,
+0x69,0x02,0x17,0x14,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x54,0xcf,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,
+0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x44,0x30,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,
+0x0f,0x69,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,
+0x30,0xe4,0x14,0xc2,0x03,0x78,0x96,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,0x12,
+0x31,0xfb,0x12,0x31,0x69,0x80,0x5d,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x78,0x96,0xe6,0x24,0xfd,0x75,0xf0,
+0x0a,0xa4,0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xac,0x82,0xad,0x83,0x78,
+0xa6,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,0x03,
+0xa7,0xc2,0x03,0x78,0x96,0xe6,0xfc,0x12,0x11,0x07,0x7d,0x00,0x7c,0x0b,0x12,0x25,
+0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0xe4,0x90,0xfc,0x39,0xf0,0x7d,0x02,0x7c,
+0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x7c,0x00,0x12,0x25,0xbf,
+0x12,0x31,0x69,0x22,0x74,0x3c,0x90,0xfb,0xe0,0xf0,0x74,0x3e,0x90,0xfb,0xe0,0xf0,
+0xe4,0x90,0xfc,0x28,0xf0,0x22,0x8d,0x35,0x8c,0x34,0xec,0xb4,0x01,0x02,0x80,0x03,
+0xd3,0x40,0x02,0x80,0x28,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x08,0xa8,0x35,0xc6,
+0x25,0xe0,0xf6,0x80,0x18,0xb4,0x04,0x02,0x80,0x03,0xd3,0x40,0x0a,0xa8,0x35,0xc6,
+0x25,0xe0,0x25,0xe0,0xf6,0x80,0x06,0xa8,0x35,0x76,0x00,0x80,0x00,0x22,0x8c,0x3c,
+0x8d,0x3b,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x75,0x66,0x06,0x75,0x67,0x00,0x90,0xfc,
+0x29,0x12,0x04,0x6e,0x12,0x01,0xe6,0xb4,0x80,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,
+0x18,0x47,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x03,0x12,0x01,0xec,0x54,0xf0,
+0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x5f,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,
+0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfc,0x2c,0x12,0x04,0x6e,
+0xee,0xcd,0x90,0x35,0x71,0xfc,0xe4,0x93,0xff,0x74,0x01,0x93,0xfe,0xf9,0xef,0xfa,
+0x7b,0x01,0xea,0xff,0xe9,0xfe,0xec,0xc3,0x9e,0xed,0x9f,0x40,0x25,0x90,0x35,0x73,
+0xe4,0x93,0xfd,0x74,0x01,0x93,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0xee,0xcd,0xfc,
+0x90,0xfc,0x2e,0xe0,0xd3,0x9c,0x90,0xfc,0x2d,0xe0,0x9d,0x50,0x05,0x75,0x66,0x80,
+0x80,0x33,0x12,0x19,0x65,0x80,0x2e,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,0x0b,0xac,
+0x3c,0xad,0x3b,0x12,0x07,0x77,0x8c,0x66,0x80,0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,
+0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,0xd3,0x40,0x00,
+0x75,0x66,0x81,0x80,0x00,0x80,0x75,0xb4,0x81,0x02,0x80,0x03,0xd3,0x40,0x6b,0x90,
+0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x03,0x12,0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,
+0x80,0x03,0xd3,0x40,0x1d,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x08,0x12,0x02,
+0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x12,0x18,0xcf,
+0x80,0x36,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,0x13,0x75,0x3a,0x67,0xe4,0xf5,0x39,
+0xf5,0x38,0xac,0x3c,0xad,0x3b,0x12,0x05,0xd3,0x8c,0x66,0x80,0x1b,0xb4,0x10,0x03,
+0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,
+0xd3,0x40,0x00,0x75,0x66,0x81,0x80,0x00,0x80,0x02,0x80,0x00,0xe5,0x66,0xfc,0x90,
+0xfc,0x29,0x12,0x04,0x80,0xec,0x90,0x00,0x02,0x12,0x03,0x17,0xac,0x67,0x22,0x90,
+0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x60,0x04,0x74,0x01,0x80,
+0x01,0xe4,0xa2,0xe0,0x92,0x01,0x90,0xfc,0x29,0x12,0x04,0x80,0xed,0x24,0x03,0xfd,
+0x50,0x01,0x0e,0x90,0xfc,0x2c,0x12,0x04,0x6e,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,
+0x00,0x05,0x12,0x01,0xec,0xf5,0x67,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,
+0x7d,0x67,0x12,0x17,0x46,0xe5,0x67,0x70,0x04,0x75,0x66,0x08,0x22,0x75,0x66,0x00,
+0x78,0x84,0x76,0x00,0x78,0x84,0xe6,0xc3,0x95,0x67,0x50,0x38,0x90,0xfc,0x2f,0x12,
+0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfc,0x2c,0x12,0x04,0x80,0xec,0x12,0x03,0x0f,
+0x30,0x01,0x0e,0x90,0xfc,0x31,0xe0,0x04,0xf0,0x90,0xfc,0x30,0x70,0x03,0xe0,0x04,
+0xf0,0x78,0x84,0x06,0x90,0xfc,0x2e,0xe0,0x04,0xf0,0x90,0xfc,0x2d,0x70,0x03,0xe0,
+0x04,0xf0,0x80,0xc0,0x22,0x90,0xfc,0x2a,0xe0,0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0xec,
+0xfd,0x7f,0x01,0xed,0x24,0x0a,0xfd,0x50,0x01,0x0e,0x90,0xfc,0x32,0x12,0x04,0x6e,
+0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xb4,0x01,
+0x02,0x80,0x03,0xd3,0x40,0x17,0x90,0xfc,0x32,0x12,0x04,0x80,0x0d,0xed,0x70,0x01,
+0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x01,0x80,0x4e,0xb4,0x02,0x02,
+0x80,0x03,0xd3,0x40,0x19,0x90,0xfc,0x32,0x12,0x04,0x80,0xed,0x24,0x02,0xfd,0x50,
+0x01,0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x02,0x80,0x2d,0xb4,0x04,
+0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfc,0x32,0x12,0x04,0x80,0xed,0x24,0x04,0xfd,
+0x50,0x01,0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x04,0x80,0x0c,0xb4,
+0x00,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x66,0x08,0x22,0x90,0xfc,0x29,0x12,0x04,
+0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x67,0x78,0x85,0x76,0x00,0x78,0x85,0xe6,
+0xc3,0x95,0x67,0x40,0x03,0x02,0x1a,0xcd,0x78,0x86,0x76,0x00,0x78,0x86,0xe6,0xc3,
+0x78,0x88,0x96,0x50,0x76,0x90,0xfc,0x2c,0x12,0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,
+0xfc,0x32,0x12,0x04,0x89,0x12,0x01,0xe0,0xf4,0x5c,0xfc,0x12,0x01,0xe0,0xf8,0x90,
+0xfc,0x2f,0x12,0x04,0x80,0xe8,0xc0,0xe0,0x12,0x01,0xe6,0xc8,0xd0,0xe0,0xc8,0x58,
+0x4c,0xfc,0x90,0xfc,0x2c,0x12,0x04,0x80,0xec,0x12,0x03,0x0f,0x78,0x87,0xec,0xf6,
+0x90,0xfc,0x31,0xe0,0x04,0xf0,0x90,0xfc,0x30,0x70,0x03,0xe0,0x04,0xf0,0x09,0xe9,
+0x70,0x01,0x0a,0x90,0xfc,0x32,0x12,0x04,0x77,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,
+0x00,0x04,0x12,0x01,0xec,0x30,0xe4,0x0e,0x90,0xfc,0x2e,0xe0,0x04,0xf0,0x90,0xfc,
+0x2d,0x70,0x03,0xe0,0x04,0xf0,0x78,0x86,0x06,0x80,0x81,0x78,0x88,0xe6,0xfd,0xe4,
+0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfc,0x31,0xe0,0x2c,0xf0,0x90,0xfc,0x30,0xe0,0x3d,
+0xf0,0x78,0x88,0xe6,0xfd,0xe4,0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfc,0x34,0xe0,0x2c,
+0xf0,0x90,0xfc,0x33,0xe0,0x3d,0xf0,0x78,0x85,0x06,0x02,0x1a,0x0d,0x75,0x66,0x00,
+0x22,0xe5,0x3d,0x05,0x3d,0x04,0x70,0x02,0xb2,0xb0,0x22,0xc0,0xe0,0xc0,0xf0,0xc0,
+0x82,0xc0,0x83,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0,0xea,0xc0,0xe0,0xeb,0xc0,
+0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef,0xc0,0xe0,0x90,0xff,0x92,
+0xe0,0x12,0x01,0xb7,0x1b,0x29,0x30,0x1b,0x29,0x32,0x1b,0x38,0x38,0x1b,0x4a,0x3a,
+0x1b,0x5c,0x3e,0x1b,0x74,0x44,0x1b,0x68,0x46,0x1b,0x80,0x50,0x1b,0xc2,0x52,0x1b,
+0xa1,0x54,0x1b,0xe3,0x56,0x00,0x00,0x1c,0x04,0x90,0xff,0x92,0xe0,0x7f,0x00,0xfe,
+0x7c,0x01,0x12,0x31,0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x03,0x12,0x31,
+0xfb,0x74,0x20,0x90,0xff,0xfe,0xf0,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x02,
+0x12,0x31,0xfb,0x74,0x40,0x90,0xff,0xfe,0xf0,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,
+0x7c,0x04,0x12,0x31,0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x05,0x12,0x31,
+0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x06,0x12,0x31,0xfb,0x02,0x1c,0x14,
+0x90,0xff,0xa5,0xe0,0x7d,0x00,0x90,0xfb,0xf8,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfb,
+0xf9,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xf8,0xe0,0x44,0x33,0xfd,0x12,0x1c,0xa7,0x80,
+0x73,0x90,0xff,0xb5,0xe0,0x7d,0x00,0x90,0xfb,0xfa,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,
+0xfb,0xfb,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfa,0xe0,0x44,0x43,0xfd,0x12,0x1c,0xa7,
+0x80,0x52,0x90,0xff,0xa6,0xe0,0x7d,0x00,0x90,0xfb,0xfc,0xcd,0xf0,0xa3,0xcd,0xf0,
+0x90,0xfb,0xfd,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfc,0xe0,0x44,0x34,0xfd,0x12,0x1c,
+0xa7,0x80,0x31,0x90,0xff,0xb6,0xe0,0x7d,0x00,0x90,0xfb,0xfe,0xcd,0xf0,0xa3,0xcd,
+0xf0,0x90,0xfb,0xff,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfe,0xe0,0x44,0x44,0xfd,0x12,
+0x1c,0xa7,0x80,0x10,0x90,0xff,0x92,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xaa,0xfd,0x12,
+0x1c,0xa7,0x80,0x00,0xe4,0x90,0xff,0x92,0xf0,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,
+0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,
+0xf8,0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32,0x05,0x81,0x05,0x81,
+0x05,0x81,0x05,0x81,0xa8,0x81,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0x90,0xff,
+0x5a,0xe0,0x20,0xe7,0x02,0x80,0xf7,0x90,0xff,0x59,0xe0,0x7d,0x00,0xa8,0x81,0x18,
+0xcd,0xf6,0xcd,0x08,0xf6,0x7d,0x03,0xa8,0x81,0xe6,0x18,0xfc,0xe6,0xcc,0x25,0xe0,
+0xcc,0x33,0xcc,0xdd,0xf9,0xcc,0xf6,0xcc,0x08,0xf6,0xa8,0x81,0x18,0xe6,0x44,0xf8,
+0xf6,0xa8,0x81,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0xa8,0x81,0x18,0x86,0x83,
+0x08,0x86,0x82,0xed,0xf0,0xa3,0xec,0xf0,0x74,0x02,0x90,0xff,0x5a,0xf0,0x15,0x81,
+0x15,0x81,0x15,0x81,0x15,0x81,0x22,0xe5,0x81,0x24,0x05,0xf5,0x81,0xe4,0xa8,0x81,
+0x18,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0x90,0xfb,0xf5,
+0xe0,0x24,0xf8,0x50,0x03,0x02,0x1d,0xc8,0xe4,0xa8,0x81,0x18,0x18,0xf6,0xa8,0x81,
+0x18,0xe6,0xfe,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x7f,0x00,
+0xef,0x24,0xf8,0x40,0x4d,0xe4,0xef,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,
+0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x6c,0x70,0x03,0xfa,0xeb,0x6d,0x70,0x09,0x74,0x01,
+0xa8,0x81,0x18,0x18,0xf6,0x80,0x2b,0xe4,0xef,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,
+0x34,0xfc,0xf5,0x83,0x7a,0x00,0xe0,0x54,0xf0,0xcc,0xf8,0xcc,0xcd,0xf9,0xcd,0xfb,
+0x78,0x00,0xe9,0x54,0xf0,0xf9,0xea,0x68,0x70,0x02,0xeb,0x69,0x70,0x01,0x0e,0x0f,
+0x80,0xae,0xa8,0x81,0x18,0xee,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,0xf6,0x08,
+0xec,0xf6,0xa8,0x81,0xef,0xf6,0xa8,0x81,0x18,0x18,0xe6,0x70,0x79,0xa8,0x81,0x18,
+0xe6,0x24,0xf7,0x40,0x71,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0x54,0x0f,0xa8,0x81,
+0xf6,0x64,0x04,0x60,0x17,0xa8,0x81,0xe6,0x64,0x03,0x60,0x10,0xa8,0x81,0x18,0x18,
+0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x1c,0x3c,0x80,0x4a,0x7c,0x0a,0x12,0x31,
+0x5b,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x90,0xfb,0xf4,0xe0,
+0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,
+0x90,0xfb,0xf4,0xe0,0xff,0xe4,0xef,0x04,0x54,0x07,0xff,0x90,0xfb,0xf4,0xf0,0x90,
+0xfb,0xf5,0xe0,0x04,0xf0,0x12,0x31,0xf4,0x90,0xfb,0xf6,0xe0,0x70,0x08,0xe4,0xfe,
+0xff,0x7c,0x0f,0x12,0x31,0xfb,0x80,0x27,0x90,0xfb,0xf7,0xe0,0x04,0xf0,0x54,0x3f,
+0x70,0x1d,0x90,0xfb,0xf7,0xe0,0x44,0xfe,0x7d,0x00,0xfc,0x90,0xfb,0xf4,0xe0,0x25,
+0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,0xe5,
+0x81,0x24,0xfb,0xf5,0x81,0x22,0x78,0x8b,0x76,0x00,0x78,0x8c,0x76,0x00,0x74,0x01,
+0x90,0xfb,0xf6,0xf0,0x12,0x30,0xe6,0x90,0xfb,0xf5,0xe0,0x60,0x57,0x7c,0x0a,0x12,
+0x31,0x5b,0x90,0xfb,0xf3,0xe0,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,
+0x83,0xe0,0xfd,0xa3,0xe0,0xfc,0x90,0xfb,0xf3,0xe0,0x25,0xe0,0x24,0x7d,0xf5,0x82,
+0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0xfb,0xf3,0xe0,0xff,0xe4,0xef,
+0x04,0x54,0x07,0xff,0x90,0xfb,0xf3,0xf0,0x90,0xfb,0xf5,0xe0,0x14,0xf0,0x78,0x89,
+0xed,0xf6,0x08,0xec,0xf6,0x12,0x31,0xf4,0x78,0x89,0xe6,0xfd,0x08,0xe6,0xfc,0x12,
+0x08,0xda,0x80,0xa3,0x12,0x32,0x48,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,
+0x78,0x8b,0x06,0xb6,0x00,0x11,0x78,0x8b,0x76,0x00,0x78,0x8c,0xe6,0xf4,0x04,0x04,
+0xa2,0xe0,0x92,0xb4,0x78,0x8c,0xf6,0x02,0x1e,0x07,0xe4,0x90,0xfb,0xf6,0xf0,0x90,
+0xfb,0xf5,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xcf,0xfd,0x12,0x1c,0x3c,0x12,0x31,0x69,
+0x22,0x12,0x30,0xe6,0xe5,0x70,0x64,0x49,0x45,0x6f,0x60,0x15,0x90,0xff,0x83,0xe0,
+0x54,0x0f,0x7d,0x00,0xd3,0x95,0x70,0xed,0x95,0x6f,0x50,0x05,0x12,0x2f,0x2f,0x80,
+0x03,0x12,0x2f,0xff,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0xe5,0x70,0x64,0x49,0x45,
+0x6f,0x60,0x05,0x12,0x30,0x39,0x80,0x0e,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x90,
+0xff,0x83,0xe0,0x54,0x7f,0xf0,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x8c,0x54,0xec,
+0x54,0xf0,0xb4,0x10,0x15,0x75,0x6a,0x35,0x75,0x69,0xfc,0x75,0x68,0x01,0xe5,0x6a,
+0x24,0x03,0xf5,0x6a,0xe5,0x69,0x34,0x00,0xf5,0x69,0xe4,0xf5,0x57,0xf5,0x56,0xe5,
+0x56,0xc3,0x94,0x01,0x50,0x27,0xe5,0x54,0x54,0x0f,0xfc,0xad,0x6a,0xae,0x69,0xaf,
+0x68,0x12,0x0e,0x77,0x8c,0x55,0xec,0x60,0x02,0x80,0x12,0x05,0x6a,0xe5,0x6a,0x70,
+0x02,0x05,0x69,0x05,0x57,0xe5,0x57,0x70,0x02,0x05,0x56,0x80,0xd2,0xe5,0x54,0x54,
+0x0f,0x24,0x9d,0xf8,0xc6,0x54,0xfe,0xf6,0xe5,0x54,0x54,0x0f,0x7f,0x00,0xfe,0x7c,
+0x12,0x12,0x31,0xfb,0xe5,0x55,0x14,0x70,0x09,0x7d,0x00,0x7c,0x09,0x12,0x25,0x26,
+0x80,0x07,0xad,0x57,0x7c,0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,
+0x90,0xff,0xfc,0xe0,0x44,0x02,0xf0,0x90,0xff,0x00,0xe0,0x30,0xe7,0x13,0x90,0xff,
+0x83,0xe0,0x44,0x80,0xf0,0x43,0x6d,0x80,0x90,0xff,0xfc,0xe0,0x44,0x01,0xf0,0x80,
+0x11,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x53,0x6d,0x7f,0x90,0xff,0xfc,0xe0,0x54,
+0xfe,0xf0,0x90,0xff,0x81,0xe0,0x44,0x80,0xf0,0x12,0x25,0xd9,0x90,0xff,0xfe,0xe0,
+0x44,0x05,0xf0,0x90,0xff,0xfc,0xe0,0x54,0xfd,0xf0,0x12,0x31,0x69,0x22,0x12,0x30,
+0xe6,0x7c,0x01,0x12,0x32,0xa9,0x78,0xad,0xe6,0x44,0x02,0xf6,0x74,0xfe,0xfc,0x04,
+0xfd,0x12,0x1c,0xa7,0x90,0xff,0x5a,0xe0,0x30,0xe7,0x02,0x80,0xf7,0xe4,0xf5,0x4e,
+0x75,0x4d,0x10,0xac,0x4e,0xad,0x4d,0xe5,0x4e,0x15,0x4e,0x70,0x02,0x15,0x4d,0xec,
+0x4d,0x60,0x02,0x80,0xee,0x43,0x87,0x01,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x7c,
+0x02,0x12,0x31,0x75,0x78,0xad,0xe6,0x54,0xfd,0xf6,0x12,0x31,0x69,0x22,0x12,0x30,
+0xe6,0x78,0xad,0xe6,0x30,0xe0,0x2c,0x78,0xad,0xe6,0x30,0xe1,0x26,0x78,0xad,0xe6,
+0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf0,0xfd,0x12,0x1c,0x3c,0x90,0xff,0xfc,0xe0,0x44,
+0x20,0xf0,0x7c,0x02,0x12,0x32,0xa9,0x78,0xad,0xe6,0x54,0xfd,0xf6,0x74,0x1a,0x90,
+0xff,0xfe,0xf0,0x78,0xad,0xe6,0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf1,0xfd,0x12,0x1c,
+0x3c,0x12,0x31,0x69,0x22,0x75,0x6d,0x00,0x90,0xff,0xff,0xe0,0x60,0x03,0x43,0x6d,
+0x01,0x75,0x6e,0x00,0xe4,0xf5,0x6c,0xf5,0x6b,0xe4,0xf5,0x6f,0x75,0x70,0x49,0x74,
+0x84,0x90,0xff,0x82,0xf0,0x74,0x84,0x90,0xff,0x80,0xf0,0x74,0x80,0x90,0xff,0x58,
+0xf0,0x74,0x80,0x90,0xff,0x5a,0xf0,0xad,0x46,0xaf,0x45,0x7e,0x00,0xee,0x24,0xfe,
+0x50,0x03,0x02,0x21,0x24,0xe4,0xee,0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,
+0x34,0xf8,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,0x80,0xfd,0xe4,0xef,0x54,0x0f,0x14,
+0xff,0xed,0x60,0x38,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0x80,0x34,0xe4,0xef,0x75,0xf0,
+0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,
+0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,
+0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,
+0x0e,0x02,0x20,0x8d,0x8d,0x46,0x8e,0x44,0x8f,0x45,0x74,0x7f,0x90,0xff,0xfd,0xf0,
+0x74,0x90,0x90,0xff,0xfc,0xf0,0x22,0x8c,0x58,0xec,0x24,0xf6,0x50,0x06,0xe5,0x58,
+0x24,0x37,0xfc,0x22,0xe5,0x58,0x24,0x30,0xfc,0x22,0x12,0x25,0x23,0xec,0x70,0x03,
+0x02,0x22,0x5e,0x75,0x5c,0x03,0xae,0x5b,0x7f,0x00,0xe5,0x5c,0x15,0x5c,0x64,0x80,
+0x24,0x7f,0x50,0x35,0xef,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfe,
+0x24,0xfe,0x50,0x1e,0xef,0x7d,0x00,0xfc,0xe4,0xfb,0x74,0x74,0xc3,0x9c,0xfa,0xeb,
+0x9d,0xfb,0xee,0x7d,0x00,0xfc,0xea,0xc3,0x9c,0xed,0x64,0x80,0xcb,0x64,0x80,0x9b,
+0x50,0x02,0x80,0x05,0xef,0x2e,0xff,0x80,0xc1,0x8e,0x5b,0x8f,0x5a,0xe5,0x5c,0x64,
+0x80,0x24,0x7f,0x50,0x03,0x02,0x22,0x5e,0xe5,0x5a,0x24,0x8e,0x50,0x03,0x02,0x22,
+0x5e,0x85,0x5a,0x5d,0x75,0x5b,0x00,0xae,0x5a,0xaf,0x5b,0x90,0x35,0x9c,0xe4,0x93,
+0xf5,0x5c,0xe5,0x5c,0x15,0x5c,0x64,0x80,0x24,0x7f,0x50,0x18,0xee,0x24,0x00,0xf5,
+0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfc,0xef,0x90,0x35,0x9c,0x93,0x6c,0x70,0x04,
+0x0e,0x0f,0x80,0xde,0x8e,0x5a,0x8f,0x5b,0xe5,0x5c,0x64,0x80,0x24,0x7f,0x40,0x6e,
+0x75,0x5e,0x01,0x75,0x60,0xe8,0x75,0x5f,0xff,0xe5,0x5d,0x24,0x02,0xf5,0x5a,0x75,
+0x5c,0x07,0xe5,0x5c,0x33,0x40,0x57,0xad,0x60,0xae,0x5f,0xaf,0x5e,0xe5,0x5c,0xf5,
+0x82,0x33,0x95,0xe0,0xf5,0x83,0x12,0x01,0xec,0xc4,0x54,0x0f,0xfc,0x12,0x21,0x37,
+0xe5,0x5a,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xec,0xf0,0x05,0x5a,0x05,
+0x5a,0xad,0x60,0xae,0x5f,0xaf,0x5e,0xe5,0x5c,0xf5,0x82,0x33,0x95,0xe0,0xf5,0x83,
+0x12,0x01,0xec,0x54,0x0f,0xfc,0x12,0x21,0x37,0xe5,0x5a,0x24,0x00,0xf5,0x82,0xe4,
+0x34,0xfb,0xf5,0x83,0xec,0xf0,0x05,0x5a,0x05,0x5a,0x15,0x5c,0x80,0xa4,0x74,0x02,
+0x90,0xf8,0x51,0xf0,0x90,0xf8,0x6b,0x79,0x75,0x7a,0x35,0x7b,0x27,0x78,0x01,0x12,
+0x03,0xf5,0x75,0x6a,0x35,0x75,0x69,0xfc,0x75,0x68,0x01,0xe4,0x90,0xff,0x83,0xf0,
+0x74,0x80,0x90,0xff,0x81,0xf0,0x75,0x59,0x02,0xe5,0x59,0x75,0xf0,0x07,0xa4,0x24,
+0x7f,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0x78,0x8f,0xf6,0xfc,0x54,0x0f,0x14,
+0xfc,0x78,0x8f,0xec,0xf6,0xe5,0x59,0x75,0xf0,0x07,0xa4,0x24,0x81,0xf5,0x82,0xe4,
+0x34,0xf8,0xf5,0x83,0xe0,0x78,0x92,0x76,0xfd,0x08,0x76,0xe8,0xfc,0x78,0x8f,0xe6,
+0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,
+0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xec,
+0xf0,0x78,0x92,0xe6,0xff,0x08,0xe6,0x7e,0x03,0xcf,0xc3,0x13,0xcf,0x13,0xde,0xf9,
+0xfe,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0xee,0xf0,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0x74,0x80,0xf0,0x78,0x90,0xec,0xf6,0x7d,0x00,0x78,0x93,0xe6,0x2c,
+0xf6,0x18,0xe6,0x3d,0xf6,0x78,0x92,0xe6,0xfd,0x08,0xe6,0x7c,0x03,0xcd,0xc3,0x13,
+0xcd,0x13,0xdc,0xf9,0xfc,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xec,0xf0,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4e,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x92,0xe6,0xfd,0x08,0xe6,0xfc,
+0x78,0x8f,0xe6,0xff,0x7e,0x00,0xee,0x24,0xfe,0x50,0x03,0x02,0x24,0xdd,0xe4,0xee,
+0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0xff,0xe4,
+0xef,0x54,0x80,0xfa,0xe4,0xef,0x54,0x0f,0x14,0xff,0xe4,0xee,0x75,0xf0,0x07,0xa4,
+0x24,0x81,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0x78,0x90,0xf6,0xe4,0xee,0x13,
+0x13,0x54,0x80,0x24,0xf0,0xf8,0xe4,0x34,0xfd,0xf9,0xe8,0xfc,0xe9,0xfd,0x8a,0x5a,
+0xea,0x70,0x03,0x02,0x24,0x4a,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x90,0xe6,0xfa,0xe4,0xef,0x75,0xf0,0x08,
+0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,0xec,0x7a,
+0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,
+0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x90,0xe6,0x7b,0x00,0xfa,
+0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,
+0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,
+0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0x02,0x24,0xd9,0xe4,0xef,0x75,0xf0,0x08,0xa4,
+0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x90,0xe6,0xfa,0xe4,
+0xef,0x75,0xf0,0x08,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,
+0xed,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,
+0xf0,0x08,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x90,
+0xe6,0x7b,0x00,0xfa,0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,
+0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0d,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x23,0x66,0x8e,0x59,0x78,
+0x92,0xed,0xf6,0x08,0xec,0xf6,0x78,0x8f,0xef,0xf6,0x12,0x20,0x55,0x22,0x8c,0x26,
+0xec,0x30,0xe7,0x18,0xe5,0x26,0x54,0x0f,0x14,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x80,0x16,0xe5,0x26,0x54,0x0f,
+0x14,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,
+0xdf,0xf0,0x22,0x7c,0x00,0x22,0xec,0x90,0xfc,0x37,0xf0,0x8c,0x24,0xed,0x24,0x03,
+0xf5,0x25,0x7d,0x00,0xd3,0x95,0x72,0xed,0x95,0x71,0x40,0x03,0x85,0x72,0x25,0xe5,
+0x25,0x24,0xb7,0x50,0x09,0x75,0x25,0x03,0x74,0x02,0x90,0xfc,0x37,0xf0,0xac,0x25,
+0x12,0x30,0x24,0x22,0xe4,0xf5,0x6c,0xf5,0x6b,0x12,0x25,0x5d,0x22,0x90,0xfc,0x35,
+0xe0,0x65,0x73,0x60,0x0e,0x74,0x04,0x90,0xfc,0x37,0xf0,0xe4,0xf5,0x6b,0x75,0x6c,
+0x03,0x80,0x46,0x7d,0x73,0xe4,0xfe,0xff,0x79,0x35,0x7a,0xfc,0x7b,0x01,0x74,0x05,
+0x78,0x00,0x12,0x03,0x3f,0xe5,0x6c,0x24,0x03,0xf5,0x6c,0xe5,0x6b,0x34,0x00,0xf5,
+0x6b,0xe5,0x6c,0xd3,0x95,0x72,0xe5,0x6b,0x95,0x71,0x40,0x06,0x85,0x72,0x6c,0x85,
+0x71,0x6b,0xd3,0xe5,0x6c,0x94,0x48,0xe5,0x6b,0x94,0x00,0x40,0x0c,0x74,0x02,0x90,
+0xfc,0x37,0xf0,0xe4,0xf5,0x6b,0x75,0x6c,0x03,0xac,0x6c,0x12,0x30,0x24,0x22,0xec,
+0x90,0xfc,0x37,0xf0,0xe4,0xf5,0x6c,0xf5,0x6b,0x8c,0x32,0xec,0x60,0x05,0x12,0x30,
+0x15,0x80,0x05,0x7c,0x00,0x12,0x30,0x24,0x22,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,
+0xb2,0xb3,0x90,0xff,0x04,0xe0,0xf5,0x4a,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,
+0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,
+0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0xc3,0xec,0x94,0x48,0xed,0x94,0x00,0x50,
+0x22,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,
+0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,
+0xfd,0x80,0x04,0xe4,0xfd,0x7c,0x48,0x8c,0x72,0x8d,0x71,0x90,0xff,0x02,0xe0,0xfd,
+0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x02,0xe0,0xff,0xa3,0xe0,
+0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xf5,0x4c,0xed,0x4f,0xf5,0x4b,0x75,0x6a,0x35,
+0x75,0x69,0xfc,0x75,0x68,0x01,0x7d,0x35,0x7e,0xfc,0x7f,0x01,0x79,0x73,0xe4,0xfa,
+0xfb,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,0x75,0x49,0x00,0xe5,0x49,0x24,0xfe,0x40,
+0x19,0xad,0x6a,0xae,0x69,0xaf,0x68,0xe4,0x12,0x03,0x0f,0x05,0x49,0x0d,0xed,0x70,
+0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,0x80,0xe1,0x75,0x6a,0x35,0x75,0x69,0xfc,
+0x75,0x68,0x01,0x90,0xff,0x00,0xe0,0x54,0x60,0xb4,0x00,0x02,0x80,0x06,0xd3,0x50,
+0x03,0x02,0x2c,0x6d,0xe5,0x4a,0x54,0x0f,0xf5,0x49,0xe5,0x4a,0x54,0x80,0xa2,0xe0,
+0x92,0x02,0x90,0xff,0x01,0xe0,0x12,0x01,0x81,0x00,0x0b,0x2c,0x68,0x26,0xe5,0x28,
+0x03,0x2c,0x68,0x29,0x0f,0x2c,0x68,0x29,0xf2,0x2a,0x26,0x2b,0x8d,0x2b,0x90,0x2b,
+0xd0,0x2c,0x11,0x2c,0x3f,0xe5,0x6d,0x30,0xe7,0x0e,0xe5,0x4c,0x45,0x4b,0x70,0x08,
+0xe5,0x72,0x64,0x02,0x45,0x71,0x60,0x03,0x02,0x2c,0x6a,0x90,0xff,0x00,0xe0,0x54,
+0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x4a,0x60,0x03,0x02,0x28,0x00,
+0xad,0x6a,0xae,0x69,0xaf,0x68,0x74,0x01,0x12,0x03,0x0f,0x78,0xad,0xe6,0x30,0xe0,
+0x0b,0xad,0x6a,0xae,0x69,0xaf,0x68,0x74,0x02,0x12,0x03,0x0f,0x7c,0x02,0x12,0x30,
+0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x1b,0xe5,0x6d,0x20,0xe1,0x07,0xe5,
+0x4a,0x60,0x03,0x02,0x28,0x00,0xe5,0x4a,0x24,0xfe,0x50,0x03,0x02,0x28,0x00,0x7c,
+0x02,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x27,0xfe,
+0xe5,0x6d,0x20,0xe1,0x0d,0xe5,0x4a,0x60,0x09,0xe5,0x4a,0x64,0x80,0x60,0x03,0x02,
+0x28,0x00,0xac,0x4a,0x12,0x30,0xab,0x40,0x03,0x02,0x28,0x00,0xe5,0x49,0x70,0x25,
+0x30,0x02,0x11,0x90,0xff,0x80,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,
+0x03,0x0f,0x80,0x0f,0x90,0xff,0x82,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,
+0x12,0x03,0x0f,0x80,0x3d,0x15,0x49,0x30,0x02,0x1d,0xe5,0x49,0x75,0xf0,0x08,0xa4,
+0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,
+0xaf,0x68,0x12,0x03,0x0f,0x80,0x1b,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,
+0x03,0x0f,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,0x01,0xe6,0x60,0x0b,0xad,0x6a,0xae,
+0x69,0xaf,0x68,0x74,0x01,0x12,0x03,0x0f,0x7c,0x02,0x12,0x30,0x24,0x22,0x80,0x00,
+0x02,0x2c,0x6a,0xe5,0x6d,0x20,0xe7,0x06,0xe5,0x72,0x45,0x71,0x60,0x03,0x02,0x2c,
+0x6a,0x90,0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,
+0x4c,0x14,0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0x0c,0x78,0xad,0xe6,
+0x54,0xfe,0xf6,0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,
+0x2a,0xe5,0x6d,0x20,0xe1,0x08,0xe5,0x6d,0x20,0xe0,0x03,0x02,0x29,0x0c,0xe5,0x6d,
+0x30,0xe0,0x04,0xe5,0x4a,0x70,0x0b,0xe5,0x6d,0x30,0xe1,0x09,0xe5,0x4a,0x24,0xfe,
+0x50,0x03,0x02,0x29,0x0c,0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x06,
+0xd3,0x50,0x03,0x02,0x29,0x0a,0xe5,0x4c,0x45,0x4b,0x60,0x03,0x02,0x29,0x0c,0xac,
+0x4a,0x12,0x30,0xab,0x40,0x03,0x02,0x29,0x0c,0xe5,0x6d,0x20,0xe1,0x07,0xe5,0x6d,
+0x20,0xe0,0x02,0x80,0x77,0xe5,0x6d,0x30,0xe0,0x06,0xe5,0x49,0x60,0x02,0x80,0x6c,
+0xe5,0x49,0x70,0x0f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x80,0xe0,0x54,
+0xf7,0xf0,0x22,0xe5,0x49,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,0x01,0x7c,
+0x03,0x12,0x0f,0x09,0x80,0x11,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,0x01,
+0x7c,0x04,0x12,0x0f,0x09,0x80,0x00,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x80,
+0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,
+0xe0,0x54,0xf7,0xf0,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x00,0x02,0x2c,0x6a,0xe5,
+0x6d,0x20,0xe7,0x06,0xe5,0x72,0x45,0x71,0x60,0x03,0x02,0x2c,0x6a,0x90,0xff,0x00,
+0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,0x4c,0x14,0x45,0x4b,
+0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0xef,0x78,0xad,0xe6,0x44,0x01,0xf6,0x7c,
+0x00,0x12,0x30,0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x6d,0x20,
+0xe1,0x08,0xe5,0x6d,0x20,0xe0,0x03,0x02,0x29,0xef,0xe5,0x6d,0x30,0xe0,0x04,0xe5,
+0x49,0x70,0x0b,0xe5,0x6d,0x30,0xe1,0x08,0xe5,0x49,0x24,0xfe,0x50,0x02,0x80,0x7f,
+0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x6f,0xe5,0x4c,
+0x45,0x4b,0x60,0x02,0x80,0x69,0xac,0x4a,0x12,0x30,0xab,0x40,0x02,0x80,0x60,0xe5,
+0x6d,0x20,0xe1,0x07,0xe5,0x6d,0x20,0xe0,0x02,0x80,0x54,0xe5,0x49,0x70,0x14,0x30,
+0x02,0x09,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x80,0x07,0x90,0xff,0x82,0xe0,0x44,
+0x08,0xf0,0x22,0xe5,0x6d,0x30,0xe1,0x33,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,0x75,
+0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x44,0x08,0xf0,
+0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0xe0,0x44,0x08,0xf0,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x02,0x80,0x00,0x02,
+0x2c,0x6a,0xe5,0x6d,0x20,0xe7,0x12,0xe5,0x72,0x45,0x71,0x70,0x0c,0xe5,0x4a,0x70,
+0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xe5,0x4c,0x90,0xff,
+0xff,0xf0,0x90,0xff,0xff,0xe0,0x60,0x05,0x43,0x6d,0x01,0x80,0x03,0x53,0x6d,0xfe,
+0x7c,0x00,0x12,0x30,0x24,0x22,0xe5,0x6d,0x30,0xe7,0x0e,0xe5,0x72,0x45,0x71,0x60,
+0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xad,0x4b,0xe5,0x4c,
+0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0xbd,0x00,0x02,0x80,0x03,0x02,0x2b,0x88,0xb4,
+0x01,0x02,0x80,0x03,0xd3,0x40,0x32,0xe5,0x4a,0x70,0x05,0xe5,0x4c,0xfc,0x60,0x03,
+0x02,0x2b,0x8a,0x75,0x6a,0x40,0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,0x94,
+0x12,0xe5,0x71,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x12,0x80,0x04,0xac,0x72,0xad,
+0x71,0x8c,0x70,0x8d,0x6f,0x12,0x30,0x39,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,
+0x59,0xe5,0x4a,0x60,0x03,0x02,0x2b,0x8a,0xe5,0x4c,0xfc,0x70,0x27,0x75,0x6a,0x52,
+0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,0x94,0x19,0xe5,0x71,0x94,0x00,0x40,
+0x06,0xe4,0xfd,0x7c,0x19,0x80,0x04,0xac,0x72,0xad,0x71,0x8c,0x70,0x8d,0x6f,0x12,
+0x30,0x39,0x80,0x25,0x75,0x6a,0x6b,0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,
+0x94,0x27,0xe5,0x71,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x27,0x80,0x04,0xac,0x72,
+0xad,0x71,0x8c,0x70,0x8d,0x6f,0x12,0x30,0x39,0x22,0xb4,0x03,0x02,0x80,0x06,0xd3,
+0x50,0x03,0x02,0x2b,0x88,0xe5,0x4c,0xf5,0x49,0x70,0x0f,0x90,0xff,0x04,0xe0,0xfd,
+0xa3,0xe0,0x4d,0x60,0x03,0x02,0x2b,0x8a,0x80,0x18,0x90,0xfb,0x02,0xe0,0xfd,0xa3,
+0xe0,0xfc,0x90,0xff,0x05,0xe0,0x6c,0x70,0x07,0x90,0xff,0x04,0xe0,0x6d,0x60,0x02,
+0x80,0x68,0xe4,0xf5,0x70,0xf5,0x6f,0x7f,0x00,0xe5,0x49,0x14,0xc5,0x49,0x60,0x0f,
+0xef,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x2f,0xff,0x80,0xea,0x8f,
+0x4a,0xe5,0x4a,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7d,0x00,0xd3,
+0x95,0x72,0xed,0x95,0x71,0x40,0x06,0xac,0x72,0xad,0x71,0x80,0x0f,0xe5,0x4a,0x24,
+0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7d,0x00,0xfc,0x8c,0x70,0x8d,0x6f,
+0xe5,0x4a,0x24,0x00,0xfc,0xe4,0x34,0xfb,0xfd,0xfe,0xec,0xfd,0x7f,0x01,0x8d,0x6a,
+0x8e,0x69,0x8f,0x68,0x12,0x30,0x39,0x22,0x80,0x00,0x02,0x2c,0x6a,0x02,0x2c,0x6a,
+0xe5,0x6d,0x30,0xe7,0x19,0xe5,0x72,0x14,0x45,0x71,0x70,0x12,0xe5,0x4a,0x70,0x0e,
+0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,
+0x6a,0xe5,0x6d,0x20,0xe0,0x08,0xe5,0x6d,0x20,0xe1,0x03,0x02,0x2c,0x6a,0x75,0x6a,
+0x6e,0xe4,0xf5,0x69,0xf5,0x68,0xe4,0xf5,0x6f,0x04,0xf5,0x70,0x12,0x30,0x39,0x22,
+0xe5,0x6d,0x20,0xe7,0x12,0xe5,0x72,0x45,0x71,0x70,0x0c,0xe5,0x4a,0x70,0x08,0x90,
+0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xe5,0x6d,0x20,0xe0,0x07,0xe5,
+0x6d,0x20,0xe1,0x02,0x80,0x74,0x85,0x4c,0x6e,0xe5,0x6e,0x70,0x08,0x43,0x6d,0x01,
+0x53,0x6d,0xfd,0x80,0x06,0x53,0x6d,0xfe,0x43,0x6d,0x02,0x7c,0x00,0x12,0x30,0x24,
+0x22,0xe5,0x6d,0x30,0xe7,0x1a,0xe5,0x72,0x14,0x45,0x71,0x70,0x13,0xe5,0x4a,0x70,
+0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,
+0x80,0x38,0xe5,0x6d,0x20,0xe1,0x02,0x80,0x31,0x7c,0x01,0x12,0x30,0x24,0x22,0xe5,
+0x6d,0x20,0xe7,0x15,0xe5,0x72,0x45,0x71,0x70,0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,
+0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,0x80,0x0f,0xe5,0x6d,0x20,0xe1,0x02,
+0x80,0x08,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x00,0x02,0x2f,0x2b,0xb4,0x40,0x02,
+0x80,0x06,0xd3,0x50,0x03,0x02,0x2f,0x21,0x90,0xff,0x01,0xe0,0x90,0xfc,0x35,0xf0,
+0xe5,0x4a,0x90,0xfc,0x36,0xf0,0xe4,0x90,0xfc,0x37,0xf0,0xe5,0x6a,0x24,0x03,0xf5,
+0x6a,0xe5,0x69,0x34,0x00,0xf5,0x69,0xad,0x4b,0xe5,0x4c,0x85,0x6a,0x82,0x85,0x69,
+0x83,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xff,0x01,0xe0,0x12,0x01,0xb7,0x2c,0xd8,0x01,
+0x2c,0xfe,0x02,0x2d,0x28,0x03,0x2d,0x52,0x04,0x2d,0xa0,0x05,0x2d,0xdd,0x06,0x2e,
+0x03,0x07,0x2e,0x29,0x08,0x2e,0x55,0x09,0x2e,0x7b,0x0b,0x2e,0xa1,0x0c,0x2e,0xb0,
+0x80,0x2e,0xb0,0x81,0x00,0x00,0x2f,0x0e,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,
+0x25,0xbf,0x22,0x7d,0x24,0x7e,0x35,0x7f,0x02,0x79,0x38,0x7a,0xfc,0x7b,0x01,0x74,
+0x08,0x78,0x00,0x12,0x03,0x3f,0x7d,0x08,0x7c,0x00,0x12,0x25,0x26,0x22,0xe5,0x6d,
+0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,
+0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x10,0x12,0x31,0xfb,0x22,
+0x7d,0x00,0x7c,0x07,0x12,0x25,0x26,0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,
+0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,
+0x4a,0x7f,0x00,0xfe,0x7c,0x11,0x12,0x31,0xfb,0x22,0x7d,0x00,0x7c,0x07,0x12,0x25,
+0x26,0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,
+0x05,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0a,0x12,0x31,0xfb,
+0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x08,0x12,
+0x31,0xfb,0x22,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,
+0x00,0xfe,0x7c,0x13,0x12,0x31,0xfb,0x22,0x7d,0x00,0x7c,0x07,0x12,0x25,0x26,0x22,
+0xe5,0x6d,0x20,0xe7,0x34,0xd3,0xe5,0x72,0x94,0x48,0xe5,0x71,0x94,0x00,0x50,0x06,
+0xe5,0x72,0x45,0x71,0x70,0x06,0x7c,0x02,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x01,
+0x03,0xb3,0x40,0x0b,0xc3,0xb4,0x03,0x00,0x40,0x09,0xb4,0x06,0x00,0x50,0x04,0x12,
+0x30,0xd1,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,
+0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,
+0x7f,0x00,0xfe,0x7c,0x16,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,
+0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,
+0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x19,0x12,0x31,0xfb,0x22,0x7c,
+0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x23,0x74,0x81,
+0x90,0xff,0x93,0xf0,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,
+0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x17,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,
+0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,
+0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x18,0x12,0x31,0xfb,
+0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,
+0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,
+0xfe,0x7c,0x15,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,
+0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,
+0xe5,0x6d,0x30,0xe7,0x20,0x90,0xff,0x00,0xe0,0x54,0x1f,0x70,0x10,0x90,0xff,0x01,
+0xe0,0xb4,0x80,0x05,0x12,0x25,0x54,0x80,0x03,0x12,0x25,0x5d,0x22,0x7d,0x00,0x7c,
+0x05,0x12,0x25,0x26,0x22,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x06,0x7c,0x05,0x12,
+0x25,0xbf,0x22,0xd3,0xe5,0x72,0x94,0x48,0xe5,0x71,0x94,0x00,0x50,0x0b,0xc3,0xe5,
+0x72,0x94,0x07,0xe5,0x71,0x94,0x00,0x50,0x06,0x7c,0x03,0x12,0x25,0xbf,0x22,0xe5,
+0x4a,0xb4,0x05,0x04,0x12,0x30,0xd1,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0xe5,0x6d,
+0x30,0xe7,0x08,0x7d,0x00,0x7c,0x05,0x12,0x25,0x26,0x22,0x7c,0x05,0x12,0x25,0xbf,
+0x22,0xb4,0x20,0x02,0x80,0x03,0xd3,0x40,0x00,0x80,0x00,0x12,0x2f,0xff,0x22,0x75,
+0x43,0x00,0x90,0xff,0x83,0xe0,0x54,0x0f,0xd3,0x95,0x43,0x40,0x24,0xe5,0x43,0x24,
+0xf0,0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,0xe0,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,
+0x03,0x0f,0x05,0x43,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,0x80,
+0xd1,0xe5,0x43,0x7d,0x00,0xfc,0xc3,0xe5,0x70,0x9c,0xf5,0x70,0xe5,0x6f,0x9d,0xf5,
+0x6f,0xe5,0x70,0x45,0x6f,0x60,0x06,0xe4,0x90,0xff,0x83,0xf0,0x22,0x90,0xff,0x82,
+0xe0,0x44,0x08,0xf0,0xe4,0xf5,0x6f,0x75,0x70,0x49,0x90,0xfc,0x35,0xe0,0xb4,0x05,
+0x02,0x80,0x03,0xd3,0x40,0x40,0x90,0xfc,0x36,0xe0,0xf5,0x43,0xb4,0x05,0x02,0x80,
+0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0b,0x12,0x31,0xfb,0x22,0xb4,0x01,
+0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x09,0x12,0x31,0xfb,0x22,
+0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x43,0x7f,0x00,0xfe,0x7c,
+0x14,0x12,0x31,0xfb,0x22,0x22,0xb4,0x80,0x00,0x40,0x23,0xb4,0x82,0x00,0x50,0x1e,
+0x7c,0x35,0x7d,0xfc,0x12,0x17,0x7e,0x7d,0x00,0x8c,0x6c,0x8d,0x6b,0x90,0xfc,0x37,
+0xe0,0x60,0x05,0x12,0x2f,0xff,0x80,0x05,0x7c,0x00,0x12,0x30,0x24,0x22,0x22,0x90,
+0xff,0x83,0xe0,0x54,0x7f,0xf0,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,
+0xe0,0x44,0x08,0xf0,0x22,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,
+0x44,0x08,0xf0,0x22,0x8c,0x23,0x7d,0x00,0x8c,0x70,0x8d,0x6f,0x75,0x6a,0x35,0x75,
+0x69,0xfc,0x75,0x68,0x01,0x12,0x30,0x39,0x22,0x90,0xff,0x83,0xe0,0x54,0x7f,0xf0,
+0xe5,0x70,0x64,0x49,0x45,0x6f,0x70,0x01,0x22,0xc3,0xe5,0x70,0x94,0x08,0xe5,0x6f,
+0x94,0x00,0x40,0x15,0x75,0x21,0x08,0xe5,0x21,0x7d,0x00,0xfc,0xc3,0xe5,0x70,0x9c,
+0xf5,0x70,0xe5,0x6f,0x9d,0xf5,0x6f,0x80,0x09,0x85,0x70,0x21,0xe4,0xf5,0x6f,0x75,
+0x70,0x49,0x75,0x22,0x00,0xe5,0x22,0xc3,0x95,0x21,0x50,0x26,0xad,0x6a,0xae,0x69,
+0xaf,0x68,0x12,0x01,0xe6,0xfc,0xe5,0x22,0x24,0xf8,0xf5,0x82,0xe4,0x34,0xfe,0xf5,
+0x83,0xec,0xf0,0x05,0x22,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,
+0x80,0xd3,0xe5,0x21,0x54,0x7f,0x90,0xff,0x81,0xf0,0x22,0x8c,0x48,0x7f,0x00,0xef,
+0x24,0xfd,0x40,0x19,0xe4,0xef,0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,0x34,
+0xf8,0xf5,0x83,0xe0,0x65,0x48,0x70,0x02,0xd3,0x22,0x0f,0x80,0xe2,0x8f,0x47,0xc3,
+0x22,0x85,0x72,0x70,0x85,0x71,0x6f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,
+0x83,0xe0,0x54,0x7f,0xf0,0x22,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,
+0xe5,0x78,0x24,0x08,0xf8,0x86,0x06,0x53,0x06,0x7f,0x7c,0xff,0x12,0x31,0x5b,0x7c,
+0x00,0x7d,0x00,0xe5,0x7b,0x60,0x46,0xff,0x90,0xfd,0x95,0xe0,0x54,0x7f,0x6e,0x70,
+0x0f,0xc0,0x83,0xc0,0x82,0xa3,0xe0,0xfd,0xa3,0xe0,0xfc,0xa3,0x15,0x7b,0x80,0x07,
+0xa3,0xa3,0xa3,0xdf,0xe6,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0x1e,0xe0,
+0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,
+0xa3,0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x12,0x31,0xf4,
+0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x22,0x85,0xa8,0x7a,0x75,0xa8,
+0x88,0xec,0x70,0x02,0x7c,0x3f,0x8c,0x79,0x22,0xe5,0x78,0x24,0x08,0xf8,0x76,0x00,
+0x12,0x32,0x48,0x80,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xae,
+0x04,0x7c,0xff,0x12,0x31,0x5b,0xe5,0x7b,0x60,0x42,0xff,0x90,0xfd,0x95,0xe0,0x54,
+0x7f,0x6e,0x70,0x0b,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x15,0x7b,0x80,0x07,0xa3,
+0xa3,0xa3,0xdf,0xea,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0xd8,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,
+0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x78,0x08,0x08,0x79,
+0x18,0x09,0x7c,0x01,0xe6,0x54,0x7f,0x6e,0x70,0x06,0x76,0x00,0x77,0x00,0x80,0x06,
+0x08,0x09,0x0c,0xbc,0x08,0xee,0x12,0x31,0xf4,0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,
+0x01,0xd0,0x00,0x22,0x75,0x79,0x00,0x85,0x7a,0xa8,0x22,0xc0,0xf0,0xc0,0x82,0xc0,
+0x83,0xc3,0xe5,0x7b,0x24,0xe8,0x50,0x05,0x12,0x32,0x48,0x80,0xf4,0xec,0x60,0x31,
+0x90,0x35,0x23,0xe4,0x93,0xc3,0x9c,0x40,0x28,0xc0,0x04,0x7c,0xff,0x12,0x31,0x5b,
+0xd0,0x04,0x43,0x04,0x80,0xe5,0x7b,0x75,0xf0,0x03,0xa4,0x24,0x95,0xf5,0x82,0xe4,
+0x34,0xfd,0xf5,0x83,0xec,0xf0,0xef,0xa3,0xf0,0xee,0xa3,0xf0,0x05,0x7b,0x12,0x31,
+0xf4,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0xc0,0x04,0x7c,0x20,0xd2,0x8c,0xd2,0x8d,
+0xd5,0x04,0xfd,0xd0,0x04,0x22,0x75,0xa8,0x00,0x75,0x88,0x00,0x75,0xb8,0x00,0x75,
+0xf0,0x00,0x75,0xd0,0x00,0xe4,0xf8,0x90,0x00,0x00,0xf6,0x08,0xb8,0x00,0xfb,0x02,
+0x00,0x00,0xc3,0xed,0x94,0x02,0x50,0x04,0x7d,0x03,0x7c,0xe8,0xec,0xf4,0xfc,0xed,
+0xf4,0xfd,0x0c,0xbc,0x00,0x01,0x0d,0x8c,0x7f,0x8d,0x7e,0x22,0xc3,0xec,0x94,0xbc,
+0xed,0x94,0x02,0x50,0x04,0x7d,0x07,0x7c,0xd0,0xec,0xf4,0xfc,0xed,0xf4,0xfd,0x0c,
+0xbc,0x00,0x01,0x0d,0x8c,0x7d,0x8d,0x7c,0x22,0xec,0x70,0x01,0x22,0xc0,0x00,0xe5,
+0x78,0x24,0x18,0xf8,0xa6,0x04,0xe5,0x78,0x24,0x08,0xf8,0xc6,0x54,0x7f,0xf6,0xe6,
+0x30,0xe7,0x03,0xd0,0x00,0x22,0x12,0x32,0x48,0x80,0xf4,0xc2,0x8c,0x85,0x7c,0x8c,
+0x85,0x7d,0x8a,0xd2,0x8c,0xc0,0xe0,0xc0,0xd0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,
+0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x12,
+0x1a,0xd1,0xe5,0x78,0x24,0x08,0xf8,0xe6,0x60,0x24,0xe5,0x78,0x24,0x10,0xf8,0xa6,
+0x81,0xe5,0x78,0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,
+0x78,0xae,0xe5,0x81,0x04,0xc3,0x98,0xf9,0xe6,0xf0,0x08,0xa3,0xd9,0xfa,0x74,0x08,
+0x25,0x78,0xf8,0x05,0x78,0x08,0xe6,0x54,0x80,0x70,0x0c,0xe5,0x78,0xb4,0x07,0xf3,
+0x78,0x08,0x75,0x78,0x00,0x80,0xef,0xe5,0x78,0x24,0x10,0xf8,0x86,0x81,0xe5,0x78,
+0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0x78,0xae,0xe5,
+0x81,0x04,0xc3,0x98,0xf9,0xe0,0xf6,0x08,0xa3,0xd9,0xfa,0xd0,0x07,0xd0,0x06,0xd0,
+0x05,0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,
+0xf0,0xd0,0xd0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02,
+0xc2,0x8e,0x85,0x7e,0x8d,0x85,0x7f,0x8b,0xd2,0x8e,0x78,0x19,0x79,0x09,0x7a,0x07,
+0xe7,0x70,0x04,0xa6,0x00,0x80,0x0b,0xe6,0x60,0x08,0x16,0xe6,0x70,0x04,0xe7,0x44,
+0x80,0xf7,0x08,0x09,0xda,0xea,0xe5,0x79,0x60,0x13,0x14,0xf5,0x79,0x70,0x0e,0xe5,
+0x78,0x24,0x08,0xf8,0x76,0x00,0x12,0x31,0xf4,0xd2,0x8c,0xd2,0x8d,0xd0,0x02,0xd0,
+0x01,0xd0,0x00,0xd0,0xd0,0xd0,0xe0,0x32,0x75,0x81,0xad,0x74,0x2a,0x90,0xff,0x93,
+0xf0,0x75,0x7f,0x30,0x75,0x7e,0xf8,0x75,0x7d,0x60,0x75,0x7c,0xf0,0x12,0x05,0x36,
+0x12,0x34,0x7c,0x12,0x17,0x34,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,0x12,
+0x34,0xa6,0x12,0x32,0x56,0x80,0xda,0x22,0xc0,0x00,0x7c,0x01,0xec,0x24,0x08,0xf8,
+0xe6,0x60,0x09,0x0c,0xbc,0x08,0xf5,0x12,0x32,0x48,0x80,0xee,0xd0,0x00,0x22,0xc0,
+0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,0xc0,0x06,0xc0,0x07,0xed,0x24,0x10,0xf8,0x76,
+0xbc,0xed,0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xc0,
+0x82,0xc0,0x83,0xa3,0xa3,0xe4,0x78,0x0d,0xf0,0xa3,0xd8,0xfc,0xec,0x54,0x7f,0x75,
+0xf0,0x02,0xa4,0x24,0xef,0xf5,0x82,0xe5,0xf0,0x34,0x34,0xf5,0x83,0xe4,0x93,0xfe,
+0x74,0x01,0x93,0xf5,0x82,0x8e,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xd0,0x83,
+0xd0,0x82,0xef,0xf0,0xa3,0xee,0xf0,0xed,0x24,0x08,0xf8,0xec,0x44,0x80,0xf6,0xd0,
+0x07,0xd0,0x06,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0x75,0x78,0x00,0x75,
+0x7b,0x00,0x7a,0x08,0x79,0x18,0x78,0x08,0x76,0x00,0x77,0x00,0x08,0x09,0xda,0xf8,
+0xe4,0x78,0x08,0x74,0x80,0x44,0x7f,0xf6,0x74,0x01,0x44,0x10,0xf5,0x89,0x75,0xb8,
+0x08,0xd2,0xab,0xd2,0xa9,0x22,0x75,0x81,0xad,0xd2,0x8e,0xd2,0x8c,0xd2,0xaf,0xe5,
+0x7b,0x60,0x32,0xff,0x90,0xfd,0x95,0xe0,0x54,0x80,0x60,0x24,0x78,0x08,0x79,0x08,
+0xe0,0x54,0x7f,0xfa,0x7b,0x00,0xe6,0x54,0x7f,0xb5,0x02,0x02,0x7b,0xff,0x08,0xd9,
+0xf5,0xeb,0x70,0x0c,0xea,0xf0,0x12,0x33,0xf8,0xad,0x04,0xac,0x02,0x12,0x34,0x0f,
+0xa3,0xa3,0xa3,0xdf,0xd2,0x12,0x32,0x48,0x80,0xc5,0x7c,0x01,0x7d,0x00,0x22,0x04,
+0xf5,0x04,0xe9,0x04,0xed,0x04,0xe1,0x04,0xdd,0x04,0xd9,0x04,0xe5,0x04,0xf1,0x04,
+0x9d,0x04,0xa1,0x04,0xcd,0x04,0xd1,0x04,0x99,0x04,0x99,0x04,0x99,0x04,0xd5,0x04,
+0xb5,0x04,0xad,0x04,0xb1,0x04,0xa9,0x04,0xc1,0x04,0xbd,0x04,0xb9,0x04,0xc5,0x04,
+0xc9,0x04,0xa5,0x19,0x01,0x03,0x00,0x22,0x00,0x48,0x02,0x00,0x48,0x0e,0x30,0x14,
+0x20,0xc8,0x1a,0xd0,0x18,0x0a,0x0c,0x05,0x06,0x02,0x03,0x01,0x02,0x00,0x01,0xce,
+0x01,0x81,0x01,0x00,0x00,0xc0,0x00,0x80,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x10,
+0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x08,0x18,0x38,0x28,0x0c,0x05,0x10,
+0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x10,0x0a,0x02,0x00,0x00,0x00,0x00,
+0x00,0xfb,0xe0,0xfb,0xf2,0x09,0x02,0x27,0x00,0x01,0x02,0x00,0xa0,0x32,0x09,0x04,
+0x00,0x00,0x03,0xff,0x00,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00,0x00,0x07,0x05,
+0x01,0x02,0x40,0x00,0x00,0x07,0x05,0x83,0x03,0x02,0x00,0x01,0x22,0x03,0x54,0x00,
+0x55,0x00,0x53,0x00,0x42,0x00,0x33,0x00,0x34,0x00,0x31,0x00,0x30,0x00,0x20,0x00,
+0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,
+0x00,0x00,
+};
+
+#endif /* ifndef _TI_FW_3410_H_ */
ChangeSet 1.1938.444.10, 2004/12/17 14:50:58-08:00, [email protected]
[PATCH] AOE: fix up sparse warnings and get rid of a kmalloc in the aoe driver.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/block/aoe/aoe.h | 2 +-
drivers/block/aoe/aoeblk.c | 4 ++--
drivers/block/aoe/aoechr.c | 28 ++++++----------------------
drivers/block/aoe/aoenet.c | 12 +++++++-----
4 files changed, 16 insertions(+), 30 deletions(-)
diff -Nru a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
--- a/drivers/block/aoe/aoe.h 2005-01-07 15:45:38 -08:00
+++ b/drivers/block/aoe/aoe.h 2005-01-07 15:45:38 -08:00
@@ -158,6 +158,6 @@
void aoenet_exit(void);
void aoenet_xmit(struct sk_buff *);
int is_aoe_netif(struct net_device *ifp);
-int set_aoe_iflist(char *str);
+int set_aoe_iflist(const char __user *str, size_t size);
u64 mac_addr(char addr[6]);
diff -Nru a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
--- a/drivers/block/aoe/aoeblk.c 2005-01-07 15:45:38 -08:00
+++ b/drivers/block/aoe/aoeblk.c 2005-01-07 15:45:38 -08:00
@@ -170,7 +170,7 @@
if (cmd == HDIO_GETGEO) {
d->geo.start = get_start_sect(inode->i_bdev);
- if (!copy_to_user((void *) arg, &d->geo, sizeof d->geo))
+ if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo))
return 0;
return -EFAULT;
}
@@ -227,7 +227,7 @@
printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
"sectors\n", mac_addr(d->addr), d->aoemajor, d->aoeminor,
- d->fw_ver, d->ssize);
+ d->fw_ver, (long long)d->ssize);
}
void __exit
diff -Nru a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
--- a/drivers/block/aoe/aoechr.c 2005-01-07 15:45:38 -08:00
+++ b/drivers/block/aoe/aoechr.c 2005-01-07 15:45:38 -08:00
@@ -51,9 +51,9 @@
}
static int
-interfaces(char *str)
+interfaces(const char __user *str, size_t size)
{
- if (set_aoe_iflist(str)) {
+ if (set_aoe_iflist(str, size)) {
printk(KERN_CRIT
"%s: could not set interface list: %s\n",
__FUNCTION__, "too many interfaces");
@@ -135,24 +135,10 @@
}
static ssize_t
-aoechr_write(struct file *filp, const char *buf, size_t cnt, loff_t *offp)
+aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp)
{
- char *str = kcalloc(1, cnt+1, GFP_KERNEL);
- int ret;
+ int ret = -EINVAL;
- if (!str) {
- printk(KERN_CRIT "aoe: aoechr_write: cannot allocate memory\n");
- return -ENOMEM;
- }
-
- ret = -EFAULT;
- if (copy_from_user(str, buf, cnt)) {
- printk(KERN_INFO "aoe: aoechr_write: copy from user failed\n");
- goto out;
- }
-
- str[cnt] = '\0';
- ret = -EINVAL;
switch ((unsigned long) filp->private_data) {
default:
printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n");
@@ -161,13 +147,11 @@
ret = discover();
break;
case MINOR_INTERFACES:
- ret = interfaces(str);
+ ret = interfaces(buf, cnt);
break;
}
if (ret == 0)
ret = cnt;
- out:
- kfree(str);
return ret;
}
@@ -192,7 +176,7 @@
}
static ssize_t
-aoechr_read(struct file *filp, char *buf, size_t cnt, loff_t *off)
+aoechr_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
{
int n;
char *mp;
diff -Nru a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
--- a/drivers/block/aoe/aoenet.c 2005-01-07 15:45:38 -08:00
+++ b/drivers/block/aoe/aoenet.c 2005-01-07 15:45:38 -08:00
@@ -53,14 +53,16 @@
}
int
-set_aoe_iflist(char *str)
+set_aoe_iflist(const char __user *user_str, size_t size)
{
- int len = strlen(str);
-
- if (len >= IFLISTSZ)
+ if (size >= IFLISTSZ)
return -EINVAL;
- strcpy(aoe_iflist, str);
+ if (copy_from_user(aoe_iflist, user_str, size)) {
+ printk(KERN_INFO "aoe: %s: copy from user failed\n", __FUNCTION__);
+ return -EFAULT;
+ }
+ aoe_iflist[size] = 0x00;
return 0;
}
ChangeSet 1.1938.446.21, 2004/12/15 16:35:03-08:00, [email protected]
[PATCH] USB: HCD/usb_bus interface cleanup (9/15)
This changes the usbcore interfaces provided to HCDs:
- Remove usb_device->hcpriv and it allocation/deallocation hooks
- Replace struct hcd_dev with more appropriate per-endpoint state
- Update HCD apis to use usb_host_endpoint in key places
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hcd.h | 20 ++++++--------------
include/linux/usb.h | 17 ++++++++++++++---
2 files changed, 20 insertions(+), 17 deletions(-)
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h 2005-01-07 15:48:51 -08:00
+++ b/drivers/usb/core/hcd.h 2005-01-07 15:48:51 -08:00
@@ -66,7 +66,6 @@
const char *description; /* "ehci-hcd" etc */
struct timer_list rh_timer; /* drives root hub */
- struct list_head dev_list; /* devices on this bus */
/*
* hardware info/state
@@ -113,14 +112,6 @@
}
-struct hcd_dev { /* usb_device.hcpriv points to this */
- struct list_head dev_list; /* on this hcd */
- struct list_head urb_list; /* pending on this dev */
-
- /* per-configuration HC/HCD state, such as QH or ED */
- void *ep[32];
-};
-
// urb.hcpriv is really hardware-specific
struct hcd_timeout { /* timeouts we allocate */
@@ -136,8 +127,6 @@
*/
struct usb_operations {
- int (*allocate)(struct usb_device *);
- int (*deallocate)(struct usb_device *);
int (*get_frame_number) (struct usb_device *usb_dev);
int (*submit_urb) (struct urb *urb, int mem_flags);
int (*unlink_urb) (struct urb *urb, int status);
@@ -149,7 +138,8 @@
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
- void (*disable)(struct usb_device *udev, int bEndpointAddress);
+ void (*disable)(struct usb_device *udev,
+ struct usb_host_endpoint *ep);
/* global suspend/resume of bus */
int (*hub_suspend)(struct usb_bus *);
@@ -200,13 +190,15 @@
struct usb_hcd *(*hcd_alloc) (void);
/* manage i/o requests, device state */
- int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
+ int (*urb_enqueue) (struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep,
+ struct urb *urb,
int mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
- struct hcd_dev *dev, int bEndpointAddress);
+ struct usb_host_endpoint *ep);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h 2005-01-07 15:48:51 -08:00
+++ b/include/linux/usb.h 2005-01-07 15:48:51 -08:00
@@ -40,9 +40,22 @@
* Devices may also have class-specific or vendor-specific descriptors.
*/
-/* host-side wrapper for parsed endpoint descriptors */
+/**
+ * struct usb_host_endpoint - host-side endpoint descriptor and queue
+ * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
+ * @urb_list: urbs queued to this endpoint; maintained by usbcore
+ * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
+ * with one or more transfer descriptors (TDs) per urb
+ * @extra: descriptors following this endpoint in the configuration
+ * @extralen: how many bytes of "extra" are valid
+ *
+ * USB requests are always queued to a given endpoint, identified by a
+ * descriptor within an active interface in a given USB configuration.
+ */
struct usb_host_endpoint {
struct usb_endpoint_descriptor desc;
+ struct list_head urb_list;
+ void *hcpriv;
unsigned char *extra; /* Extra descriptors */
int extralen;
@@ -325,8 +338,6 @@
int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */
- void *hcpriv; /* Host Controller private data */
-
struct list_head filelist;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
ChangeSet 1.1938.439.52, 2005/01/07 08:45:22-08:00, [email protected]
[PATCH] USB: minor usb doc/comment fixes
Some minor doc/comment fixes for USB.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/epautoconf.c | 3 +++
drivers/usb/gadget/omap_udc.c | 2 +-
include/linux/usb.h | 4 ++--
3 files changed, 6 insertions(+), 3 deletions(-)
diff -Nru a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
--- a/drivers/usb/gadget/epautoconf.c 2005-01-07 15:36:43 -08:00
+++ b/drivers/usb/gadget/epautoconf.c 2005-01-07 15:36:43 -08:00
@@ -55,6 +55,9 @@
*
* Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal.
* Less common restrictions are implied by gadget_is_*().
+ *
+ * NOTE: each endpoint is unidirectional, as specified by its USB
+ * descriptor; and isn't specific to a configuration or altsetting.
*/
static int __init
ep_matches (
diff -Nru a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
--- a/drivers/usb/gadget/omap_udc.c 2005-01-07 15:36:43 -08:00
+++ b/drivers/usb/gadget/omap_udc.c 2005-01-07 15:36:43 -08:00
@@ -1,5 +1,5 @@
/*
- * omap_udc.c -- for OMAP 1610 udc, with OTG support
+ * omap_udc.c -- for OMAP full speed udc; most chips support OTG.
*
* Copyright (C) 2004 Texas Instruments, Inc.
* Copyright (C) 2004 David Brownell
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h 2005-01-07 15:36:43 -08:00
+++ b/include/linux/usb.h 2005-01-07 15:36:43 -08:00
@@ -739,8 +739,8 @@
* to poll for transfers. After the URB has been submitted, the interval
* field reflects how the transfer was actually scheduled.
* The polling interval may be more frequent than requested.
- * For example, some controllers have a maximum interval of 32 microseconds,
- * while others support intervals of up to 1024 microseconds.
+ * For example, some controllers have a maximum interval of 32 milliseconds,
+ * while others support intervals of up to 1024 milliseconds.
* Isochronous URBs also have transfer intervals. (Note that for isochronous
* endpoints, as well as high speed interrupt endpoints, the encoding of
* the transfer interval in the endpoint descriptor is logarithmic.
ChangeSet 1.1938.444.7, 2004/12/16 13:19:24-08:00, [email protected]
USB: convert uhci-hcd driver to use debugfs.
Look, we saved 24 lines of code...
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/uhci-debug.c | 36 +++++++++++--------------
drivers/usb/host/uhci-hcd.c | 60 ++++++++++++++----------------------------
drivers/usb/host/uhci-hcd.h | 6 +---
3 files changed, 39 insertions(+), 63 deletions(-)
diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
--- a/drivers/usb/host/uhci-debug.c 2005-01-07 15:47:27 -08:00
+++ b/drivers/usb/host/uhci-debug.c 2005-01-07 15:47:27 -08:00
@@ -11,7 +11,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
@@ -496,19 +496,18 @@
#define MAX_OUTPUT (64 * 1024)
-static struct proc_dir_entry *uhci_proc_root = NULL;
+static struct dentry *uhci_debugfs_root = NULL;
-struct uhci_proc {
+struct uhci_debug {
int size;
char *data;
struct uhci_hcd *uhci;
};
-static int uhci_proc_open(struct inode *inode, struct file *file)
+static int uhci_debug_open(struct inode *inode, struct file *file)
{
- const struct proc_dir_entry *dp = PDE(inode);
- struct uhci_hcd *uhci = dp->data;
- struct uhci_proc *up;
+ struct uhci_hcd *uhci = inode->u.generic_ip;
+ struct uhci_debug *up;
int ret = -ENOMEM;
lock_kernel();
@@ -532,9 +531,9 @@
return ret;
}
-static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
+static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence)
{
- struct uhci_proc *up;
+ struct uhci_debug *up;
loff_t new = -1;
lock_kernel();
@@ -556,16 +555,16 @@
return (file->f_pos = new);
}
-static ssize_t uhci_proc_read(struct file *file, char __user *buf,
+static ssize_t uhci_debug_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
{
- struct uhci_proc *up = file->private_data;
+ struct uhci_debug *up = file->private_data;
return simple_read_from_buffer(buf, nbytes, ppos, up->data, up->size);
}
-static int uhci_proc_release(struct inode *inode, struct file *file)
+static int uhci_debug_release(struct inode *inode, struct file *file)
{
- struct uhci_proc *up = file->private_data;
+ struct uhci_debug *up = file->private_data;
kfree(up->data);
kfree(up);
@@ -573,11 +572,10 @@
return 0;
}
-static struct file_operations uhci_proc_operations = {
- .open = uhci_proc_open,
- .llseek = uhci_proc_lseek,
- .read = uhci_proc_read,
-// write: uhci_proc_write,
- .release = uhci_proc_release,
+static struct file_operations uhci_debug_operations = {
+ .open = uhci_debug_open,
+ .llseek = uhci_debug_lseek,
+ .read = uhci_debug_read,
+ .release = uhci_debug_release,
};
#endif
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c 2005-01-07 15:47:27 -08:00
+++ b/drivers/usb/host/uhci-hcd.c 2005-01-07 15:47:27 -08:00
@@ -46,7 +46,7 @@
#include <linux/unistd.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
#include <linux/pm.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
@@ -74,7 +74,7 @@
* debug = 0, no debugging messages
* debug = 1, dump failed URB's except for stalls
* debug = 2, dump all failed URB's (including stalls)
- * show all queues in /proc/driver/uhci/[pci_addr]
+ * show all queues in /debug/uhci/[pci_addr]
* debug = 3, show all TD's in URB's when dumping
*/
#ifdef DEBUG
@@ -1927,12 +1927,10 @@
uhci->fl = NULL;
}
-#ifdef CONFIG_PROC_FS
- if (uhci->proc_entry) {
- remove_proc_entry(uhci->hcd.self.bus_name, uhci_proc_root);
- uhci->proc_entry = NULL;
+ if (uhci->dentry) {
+ debugfs_remove(uhci->dentry);
+ uhci->dentry = NULL;
}
-#endif
}
static int uhci_reset(struct usb_hcd *hcd)
@@ -1972,25 +1970,17 @@
unsigned io_size;
dma_addr_t dma_handle;
struct usb_device *udev;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *ent;
-#endif
+ struct dentry *dentry;
io_size = pci_resource_len(to_pci_dev(uhci_dev(uhci)), hcd->region);
-#ifdef CONFIG_PROC_FS
- ent = create_proc_entry(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
- if (!ent) {
- dev_err(uhci_dev(uhci), "couldn't create uhci proc entry\n");
+ dentry = debugfs_create_file(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, &uhci_debug_operations);
+ if (!dentry) {
+ dev_err(uhci_dev(uhci), "couldn't create uhci debugfs entry\n");
retval = -ENOMEM;
- goto err_create_proc_entry;
+ goto err_create_debug_entry;
}
-
- ent->data = uhci;
- ent->proc_fops = &uhci_proc_operations;
- ent->size = 0;
- uhci->proc_entry = ent;
-#endif
+ uhci->dentry = dentry;
uhci->fsbr = 0;
uhci->fsbrtimeout = 0;
@@ -2192,13 +2182,10 @@
uhci->fl = NULL;
err_alloc_fl:
-#ifdef CONFIG_PROC_FS
- remove_proc_entry(hcd->self.bus_name, uhci_proc_root);
- uhci->proc_entry = NULL;
-
-err_create_proc_entry:
-#endif
+ debugfs_remove(uhci->dentry);
+ uhci->dentry = NULL;
+err_create_debug_entry:
return retval;
}
@@ -2405,11 +2392,9 @@
goto errbuf_failed;
}
-#ifdef CONFIG_PROC_FS
- uhci_proc_root = create_proc_entry("driver/uhci", S_IFDIR, NULL);
- if (!uhci_proc_root)
- goto proc_failed;
-#endif
+ uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
+ if (!uhci_debugfs_root)
+ goto debug_failed;
uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
sizeof(struct urb_priv), 0, 0, NULL, NULL);
@@ -2427,12 +2412,9 @@
warn("not all urb_priv's were freed!");
up_failed:
+ debugfs_remove(uhci_debugfs_root);
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("driver/uhci", NULL);
-
-proc_failed:
-#endif
+debug_failed:
if (errbuf)
kfree(errbuf);
@@ -2448,9 +2430,7 @@
if (kmem_cache_destroy(uhci_up_cachep))
warn("not all urb_priv's were freed!");
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("driver/uhci", NULL);
-#endif
+ debugfs_remove(uhci_debugfs_root);
if (errbuf)
kfree(errbuf);
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h 2005-01-07 15:47:27 -08:00
+++ b/drivers/usb/host/uhci-hcd.h 2005-01-07 15:47:27 -08:00
@@ -326,10 +326,8 @@
struct uhci_hcd {
struct usb_hcd hcd; /* must come first! */
-#ifdef CONFIG_PROC_FS
- /* procfs */
- struct proc_dir_entry *proc_entry;
-#endif
+ /* debugfs */
+ struct dentry *dentry;
/* Grabbed from PCI */
unsigned long io_addr;
ChangeSet 1.1938.446.31, 2004/12/17 11:41:58-08:00, [email protected]
[PATCH] USB: EHCI "park" mode disabled
This changes the default initialization of the EHCI "park" mode so
that silicon which supports it (NF2, NF3, ALI, GeneSys, ...) will not
use it unless explicitly told to do so by a (new) module parameter.
This is a workaround for some problems observed on some NF2 systems:
- Throughput ("hdparm -tT") is lower than expected with recent high
performance drives (Maxtor) ... disabling "park" increases it by
about 2 MByte/sec, but it's still much slower than expected.
(USB analyser traces should be informative here.)
- Some data corruption observed on reads from drives using an
ALI storage adapter ... disabling "park" stops the corruption.
(Strongly suggestive of hardware or peripheral firmware bugs;
multiple back-to-back bulk-IN packets should work just fine.)
The "don't use park mode" workaround will at most reduce USB (and PCI)
throughput slightly on systems that work as expected, but some of those
can re-enable the "park" mode.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-hcd.c | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c 2005-01-07 15:46:38 -08:00
+++ b/drivers/usb/host/ehci-hcd.c 2005-01-07 15:46:38 -08:00
@@ -124,11 +124,16 @@
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */
-/* Initial IRQ latency: lower than default */
+/* Initial IRQ latency: faster than hw default */
static int log2_irq_thresh = 0; // 0 to 6
module_param (log2_irq_thresh, int, S_IRUGO);
MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
+/* initial park setting: slower than hw default */
+static unsigned park = 0;
+module_param (park, uint, S_IRUGO);
+MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
+
#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
/*-------------------------------------------------------------------------*/
@@ -506,11 +511,24 @@
}
/* clear interrupt enables, set irq latency */
- temp = readl (&ehci->regs->command) & 0x0fff;
if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
log2_irq_thresh = 0;
- temp |= 1 << (16 + log2_irq_thresh);
- // if hc can park (ehci >= 0.96), default is 3 packets per async QH
+ temp = 1 << (16 + log2_irq_thresh);
+ if (HCC_CANPARK(hcc_params)) {
+ /* HW default park == 3, on hardware that supports it (like
+ * NVidia and ALI silicon), maximizes throughput on the async
+ * schedule by avoiding QH fetches between transfers.
+ *
+ * With fast usb storage devices and NForce2, "park" seems to
+ * make problems: throughput reduction (!), data errors...
+ */
+ if (park) {
+ park = min (park, (unsigned) 3);
+ temp |= CMD_PARK;
+ temp |= park << 8;
+ }
+ ehci_info (ehci, "park %d\n", park);
+ }
if (HCC_PGM_FRAMELISTLEN (hcc_params)) {
/* periodic schedule size can be smaller than default */
temp &= ~(3 << 2);
@@ -522,7 +540,6 @@
default: BUG ();
}
}
- temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),
// Philips, Intel, and maybe others need CMD_RUN before the
// root hub will detect new devices (why?); NEC doesn't
temp |= CMD_RUN;
ChangeSet 1.1938.446.18, 2004/12/15 16:33:56-08:00, [email protected]
[PATCH] USB: CRIS HCD and usb_dev->epmaxpacket (6/15)
Makes the CRIS HCD stop referencing the udev->epmaxpacket[] arrays.
Also makes it stop providing device allocate/deallocate routines;
this HCD doesn't need them, and a later patch will remove that API.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/hc_crisv10.c | 20 +-------------------
1 files changed, 1 insertion(+), 19 deletions(-)
diff -Nru a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
--- a/drivers/usb/host/hc_crisv10.c 2005-01-07 15:49:14 -08:00
+++ b/drivers/usb/host/hc_crisv10.c 2005-01-07 15:49:14 -08:00
@@ -479,8 +479,6 @@
static int etrax_usb_submit_urb(struct urb *urb, int mem_flags);
static int etrax_usb_unlink_urb(struct urb *urb, int status);
static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
-static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
-static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs);
static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
@@ -512,8 +510,6 @@
static struct usb_operations etrax_usb_device_operations =
{
- .allocate = etrax_usb_allocate_dev,
- .deallocate = etrax_usb_deallocate_dev,
.get_frame_number = etrax_usb_get_frame_number,
.submit_urb = etrax_usb_submit_urb,
.unlink_urb = etrax_usb_unlink_urb,
@@ -1579,20 +1575,6 @@
return (*R_USB_FM_NUMBER & 0x7ff);
}
-static int etrax_usb_allocate_dev(struct usb_device *usb_dev)
-{
- DBFENTER;
- DBFEXIT;
- return 0;
-}
-
-static int etrax_usb_deallocate_dev(struct usb_device *usb_dev)
-{
- DBFENTER;
- DBFEXIT;
- return 0;
-}
-
static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs)
{
DBFENTER;
@@ -4546,7 +4528,7 @@
usb_rh->speed = USB_SPEED_FULL;
usb_rh->devnum = 1;
hc->bus->devnum_next = 2;
- usb_rh->epmaxpacketin[0] = usb_rh->epmaxpacketout[0] = 64;
+ usb_rh->ep0.desc.wMaxPacketSize = 64;
usb_get_device_descriptor(usb_rh, USB_DT_DEVICE_SIZE);
usb_new_device(usb_rh);
ChangeSet 1.1938.446.1, 2004/12/15 14:12:02-08:00, [email protected]
[PATCH] USB: serial driver for TI USB 3410/5052 chips (3/3)
* New USB serial driver for devices based on the TI USB
3410 and 5052 chips. (3/3)
Signed-off-by: Al Borchers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/ti_fw_5052.h | 885 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 885 insertions(+)
diff -Nru a/drivers/usb/serial/ti_fw_5052.h b/drivers/usb/serial/ti_fw_5052.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_fw_5052.h 2005-01-07 15:51:26 -08:00
@@ -0,0 +1,885 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 5052 USB Serial Driver Firmware Header
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * 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.
+ */
+
+#ifndef _TI_FW_5052_H_
+#define _TI_FW_5052_H_
+
+/* firmware 9/18/04 */
+
+static unsigned char ti_fw_5052[] = {
+0xC1, 0x35, /* firmware image length excluding header, little endian */
+0x00, /* placeholder for checksum */
+
+0x02,0x00,0x1e,0x02,0x1b,0x32,0xff,0xff,0xff,0xff,0xff,0x02,0x32,0x6a,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x33,0x15,0x75,0x81,
+0xc8,0x90,0xfe,0xf0,0x85,0x83,0xa0,0x12,0x34,0x7d,0xec,0x4d,0x60,0x6a,0x78,0xa5,
+0x80,0x03,0x76,0x00,0x18,0xb8,0x96,0xfa,0x78,0x79,0x80,0x03,0x76,0x00,0x18,0xb8,
+0x5f,0xfa,0x78,0x20,0x80,0x03,0x76,0x00,0x18,0xb8,0x20,0xfa,0x90,0xfe,0xe5,0xae,
+0x83,0xaf,0x82,0x90,0xfd,0x00,0x12,0x00,0xa1,0x60,0x05,0xe4,0xf0,0xa3,0x80,0xf6,
+0x90,0xfe,0xf0,0xa8,0x82,0x90,0xfe,0xf0,0xa9,0x82,0xe8,0xc3,0x99,0x50,0x05,0x76,
+0x00,0x08,0x80,0xf6,0x90,0x00,0xff,0x12,0x00,0xaa,0x90,0x01,0x03,0x12,0x00,0xaa,
+0x90,0x01,0x07,0x12,0x00,0xaa,0x90,0x01,0x0b,0x12,0x00,0xc8,0x90,0x01,0x11,0x12,
+0x00,0xc8,0x90,0x01,0x17,0x12,0x00,0xc8,0x75,0xd0,0x00,0x12,0x33,0x67,0x02,0x01,
+0x1d,0xef,0x65,0x82,0x70,0x03,0xee,0x65,0x83,0x22,0xe4,0x93,0xf8,0x74,0x01,0x93,
+0xf9,0x74,0x02,0x93,0xfe,0x74,0x03,0x93,0xf5,0x82,0x8e,0x83,0xe8,0x69,0x70,0x01,
+0x22,0xe4,0x93,0xf6,0xa3,0x08,0x80,0xf4,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74,
+0x02,0x93,0xfe,0x74,0x03,0x93,0xff,0x74,0x04,0x93,0xf8,0x74,0x05,0x93,0xf5,0x82,
+0x88,0x83,0x12,0x00,0xa1,0x70,0x01,0x22,0xe4,0x93,0xa3,0xa8,0x83,0xa9,0x82,0x8c,
+0x83,0x8d,0x82,0xf0,0xa3,0xac,0x83,0xad,0x82,0x88,0x83,0x89,0x82,0x80,0xe3,0x21,
+0x21,0x04,0x92,0x7a,0x7a,0x04,0x92,0xa6,0xa8,0x04,0x92,0xfe,0xf0,0x04,0x94,0x04,
+0x94,0xfb,0xfb,0x04,0x99,0x04,0x94,0xfb,0xfb,0x04,0xf9,0x04,0xf9,0x80,0xfe,0xd0,
+0xf0,0x30,0xf0,0x09,0x20,0xf3,0x03,0xf6,0x80,0x10,0xf7,0x80,0x0d,0x30,0xf1,0x09,
+0x20,0xf3,0x03,0xf2,0x80,0x04,0xf3,0x80,0x01,0xf0,0x20,0xf4,0x04,0xfc,0xd0,0xe0,
+0xcc,0x22,0xcc,0xc0,0xe0,0x12,0x01,0x5a,0x02,0x01,0x4b,0xbc,0x00,0x05,0xd0,0xf0,
+0xac,0xf0,0x22,0xc3,0x13,0xdc,0xfc,0x02,0x01,0x21,0xbf,0x00,0x09,0xed,0x25,0x82,
+0x75,0xf0,0x01,0xf8,0xe6,0x22,0xbf,0x01,0x0f,0xed,0x25,0x82,0xf5,0x82,0xee,0x35,
+0x83,0xf5,0x83,0x75,0xf0,0x04,0xe0,0x22,0xed,0x25,0x82,0x75,0xf0,0x02,0xf8,0xe2,
+0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xc3,0xe4,0x93,0xa3,0xc5,0xf0,0x95,0xf0,0xc0,
+0xe0,0xc3,0xd0,0xf0,0xe4,0x93,0xa3,0x95,0xf0,0x40,0x12,0xa3,0xa3,0xc3,0xe5,0xf0,
+0x33,0x50,0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0x50,0x02,0x05,0x83,0x74,0x01,0x93,
+0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xe4,0x93,0x70,
+0x09,0x74,0x01,0x93,0x70,0x04,0xa3,0xa3,0x80,0x0c,0x74,0x02,0x93,0x65,0xf0,0x60,
+0x05,0xa3,0xa3,0xa3,0x80,0xe7,0x74,0x01,0x93,0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,
+0x12,0x02,0x5b,0x02,0x01,0xf2,0x12,0x02,0xaf,0x02,0x01,0xf2,0x12,0x02,0xd3,0x02,
+0x01,0xf2,0x30,0xe0,0x07,0x20,0xe3,0x02,0xe6,0x22,0xe7,0x22,0x30,0xe1,0x07,0x20,
+0xe3,0x02,0xe2,0x22,0xe3,0x22,0x30,0xe2,0x02,0xe0,0x22,0xe4,0x93,0x22,0x12,0x02,
+0xd3,0x02,0x02,0x1a,0x12,0x02,0xaf,0x02,0x02,0x1a,0xab,0xf0,0x12,0x02,0x24,0xcb,
+0xc5,0xf0,0xcb,0x22,0x30,0xe0,0x10,0x20,0xe3,0x06,0xe6,0xf5,0xf0,0x08,0xe6,0x22,
+0xe7,0xf5,0xf0,0x09,0xe7,0x19,0x22,0x30,0xe1,0x10,0x20,0xe3,0x06,0xe2,0xf5,0xf0,
+0x08,0xe2,0x22,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x30,0xe2,0x06,0xe0,0xf5,0xf0,
+0xa3,0xe0,0x22,0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x00,0x03,0x74,0x09,
+0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x74,0x04,0x22,0xbb,0x02,0x07,0x89,0x82,
+0x8a,0x83,0x74,0x10,0x22,0x74,0x0a,0x22,0x02,0x02,0x7b,0xbb,0x00,0x07,0xe9,0x25,
+0x82,0xf8,0x74,0x01,0x22,0xbb,0x01,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x04,0x22,0xbb,0x02,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x10,0x22,0xe9,0x25,0x82,0xf8,0x74,0x02,0x22,0x02,0x02,0xaf,0xbf,
+0x00,0x05,0xed,0xf8,0x74,0x01,0x22,0xbf,0x01,0x07,0x8d,0x82,0x8e,0x83,0x74,0x04,
+0x22,0xbf,0x02,0x07,0x8d,0x82,0x8e,0x83,0x74,0x10,0x22,0xed,0xf8,0x74,0x02,0x22,
+0x02,0x02,0xd3,0xbf,0x00,0x07,0xed,0x25,0x82,0xf8,0x74,0x01,0x22,0xbf,0x01,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x04,0x22,0xbf,0x02,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x10,0x22,0xed,0x25,0x82,
+0xf8,0x74,0x02,0x22,0x02,0x03,0x07,0xc0,0xe0,0x12,0x02,0x5b,0x02,0x03,0x1f,0xc0,
+0xe0,0x12,0x02,0xaf,0x02,0x03,0x1f,0xc0,0xe0,0x12,0x02,0xd3,0x02,0x03,0x1f,0x30,
+0xe0,0x0b,0x20,0xe3,0x04,0xd0,0xe0,0xf6,0x22,0xd0,0xe0,0xf7,0x22,0x30,0xe1,0x0b,
+0x20,0xe3,0x04,0xd0,0xe0,0xf2,0x22,0xd0,0xe0,0xf3,0x22,0xd0,0xe0,0xf0,0x22,0xc9,
+0xcd,0xc9,0xca,0xce,0xca,0xcb,0xcf,0xcb,0x12,0x03,0x52,0xed,0xf9,0xee,0xfa,0xef,
+0xfb,0x22,0xbb,0x00,0x2f,0xbf,0x00,0x0a,0xfa,0xed,0xf8,0xe7,0xf6,0x08,0x09,0xda,
+0xfa,0x22,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x03,0x6f,0x09,0xa3,0xe7,
+0xf0,0xd8,0xfa,0x22,0x02,0x03,0x7a,0xfa,0xed,0xf8,0xe7,0xf2,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x03,0x84,0xbb,0x01,0x4d,0xbf,0x00,0x14,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0x96,0x08,0xa3,0xe0,0xf6,0xd9,0xfa,0x22,0x02,0x03,0xa7,0xbf,0x01,
+0x22,0x8d,0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe0,
+0xa3,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xea,0xd8,0xe8,0x22,
+0x02,0x03,0xca,0x8d,0x82,0x8e,0x83,0xf9,0xed,0xf8,0xe0,0xf2,0x08,0xa3,0xd9,0xfa,
+0x22,0x02,0x03,0xd4,0xbb,0x02,0x4d,0xbf,0x00,0x12,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0xe6,0x08,0xa3,0xe4,0x93,0xf6,0xd9,0xf9,0x22,0xbf,0x01,0x23,0x8d,
+0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe4,0x93,0xa3,
+0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xe9,0xd8,0xe7,0x22,0x02,
+0x04,0x19,0x89,0x82,0x8a,0x83,0xf9,0xed,0xf8,0xe4,0x93,0xf2,0x08,0xa3,0xd9,0xf9,
+0x22,0x02,0x04,0x2a,0xbf,0x00,0x0d,0xfa,0xed,0xf8,0xe3,0xf6,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x04,0x34,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x04,0x41,0x09,
+0xa3,0xe3,0xf0,0xd8,0xfa,0x22,0x02,0x04,0x4c,0xfa,0xed,0xf8,0xe3,0xf2,0x08,0x09,
+0xda,0xfa,0x22,0x02,0x04,0x56,0xe6,0xfb,0x08,0xe6,0xfa,0x08,0xe6,0xf9,0x04,0xf6,
+0x18,0x70,0x01,0x06,0x22,0xe6,0xff,0x08,0xe6,0xfe,0x08,0xe6,0xfd,0x22,0xef,0xf0,
+0xa3,0xee,0xf0,0xa3,0xed,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,
+0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xfd,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xf9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xf9,0x00,0x5b,0x05,0x73,0x00,
+0x26,0x05,0x9a,0x00,0x33,0x0a,0x0b,0x00,0x5b,0x0a,0x77,0x00,0x60,0x15,0x52,0x00,
+0x5b,0x0c,0xfb,0x00,0x5b,0x09,0xab,0x00,0x5b,0x09,0xe2,0x00,0x5b,0x0d,0xc2,0x00,
+0x5b,0x0b,0xf3,0x00,0x5b,0x0a,0x1e,0x00,0x5b,0x0a,0x53,0x00,0x5b,0x17,0x4a,0x00,
+0x33,0x17,0x60,0x00,0x34,0x1e,0x4d,0x00,0x43,0x1e,0xf0,0x00,0x44,0x20,0x5d,0x00,
+0x44,0x20,0x4b,0x00,0x47,0x1f,0x17,0x00,0x47,0x1f,0xbc,0x00,0x4d,0x20,0x0d,0x00,
+0x4f,0x1f,0x39,0x00,0x58,0x31,0xf5,0x00,0x5b,0x7c,0xcc,0x7d,0xff,0x12,0x1c,0xfe,
+0x22,0x74,0x90,0x90,0xff,0x91,0xf0,0x90,0xff,0xfc,0xe0,0x20,0xe7,0x2d,0xc2,0xaf,
+0xae,0x59,0xaf,0x58,0x75,0x5a,0x20,0xe5,0x5a,0x14,0xc5,0x5a,0x60,0x19,0xe4,0xfe,
+0x7f,0x05,0xee,0x4f,0xce,0x24,0xff,0xce,0xcf,0x34,0xff,0xcf,0x60,0x07,0xe4,0x90,
+0xff,0x92,0xf0,0x80,0xed,0x80,0xe0,0x8e,0x59,0x8f,0x58,0x22,0x12,0x05,0x01,0x7d,
+0x07,0x7c,0xb7,0x12,0x32,0x11,0x7d,0x0f,0x7c,0x6e,0x12,0x32,0x2b,0x78,0x97,0x7a,
+0x06,0xe4,0xf6,0x08,0xda,0xfc,0x7a,0x06,0x12,0x05,0xcf,0x7c,0x03,0x12,0x0e,0x57,
+0x7c,0x04,0x12,0x0e,0x57,0x12,0x21,0x8b,0xe4,0xfe,0xff,0x7c,0x0f,0x12,0x31,0x9a,
+0xd2,0xa8,0x22,0x12,0x30,0x85,0xe4,0x90,0xfd,0x40,0xf0,0x90,0xff,0xf0,0xe0,0x30,
+0xe4,0x08,0x74,0x01,0x90,0xfd,0x41,0xf0,0x80,0x05,0xe4,0x90,0xfd,0x41,0xf0,0x7d,
+0x0a,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,0xfd,0x41,
+0xe0,0x14,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x44,0x10,0xf0,0x7c,0x00,0x12,0x25,0x4a,
+0x80,0x19,0x90,0xfd,0x41,0xe0,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x54,0xef,0xf0,0x7c,
+0x00,0x12,0x25,0x4a,0x80,0x05,0x7c,0x17,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x90,
+0xff,0xf0,0xe0,0x54,0xab,0xf0,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0x22,0x8c,0x37,
+0x8d,0x36,0x78,0x7c,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,
+0x00,0x05,0x12,0x01,0xec,0x78,0x7a,0xf6,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,
+0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x7a,
+0x12,0x17,0x9d,0x78,0x7a,0xe6,0x70,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,
+0x03,0x0f,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,
+0x54,0xfd,0xf0,0x80,0x1e,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,
+0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x44,0x01,0x90,0xff,0xf3,0xf0,
+0x02,0x06,0xdb,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,
+0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,0xf0,0x80,0x2b,0x78,0x7c,
+0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,
+0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,0x0d,0xad,0x3a,0xae,0x39,
+0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,
+0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,0xf1,0xf0,
+0x12,0x08,0xca,0x40,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,
+0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,
+0x00,0x06,0x12,0x02,0x0e,0x44,0x01,0x90,0xff,0xf3,0xf0,0x78,0x7d,0xe6,0x24,0x03,
+0xf6,0x18,0xe6,0x34,0x00,0xf6,0x78,0x7a,0xe6,0x24,0xfe,0x50,0x09,0x90,0xff,0xf0,
+0xe0,0x54,0xfd,0xf0,0x80,0x07,0x90,0xff,0xf0,0xe0,0x44,0x02,0xf0,0xe4,0x90,0xff,
+0xf1,0xf0,0x78,0x7b,0x76,0x00,0x78,0x7a,0xe6,0x24,0xff,0xfc,0xe4,0x34,0xff,0xfd,
+0x78,0x7b,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,0x64,0x80,0x9d,
+0x40,0x2f,0x12,0x08,0xaf,0x40,0x0f,0x78,0x7b,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,
+0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,0x7c,0x86,0x83,0x08,
+0x86,0x82,0xec,0xf0,0x78,0x7b,0x06,0xa3,0x78,0x7c,0xa6,0x83,0x08,0xa6,0x82,0x80,
+0xb5,0x12,0x08,0xaf,0x40,0x0f,0x78,0x7b,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,0x12,
+0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,0x7c,0x86,0x83,0x08,0x86,
+0x82,0xec,0xf0,0x78,0x7a,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,
+0x00,0x22,0x8c,0x37,0x8d,0x36,0x78,0x7c,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,0xec,
+0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x7b,0xf6,0x78,0x7c,0xe6,0xfd,
+0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,0x54,
+0x0f,0xfc,0x7d,0x7b,0x12,0x17,0x9d,0x78,0x7b,0xe6,0x70,0x03,0x7c,0x08,0x22,0x90,
+0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x1b,0x78,
+0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,
+0x02,0x0e,0x25,0xe0,0x90,0xff,0xf3,0xf0,0x80,0x5b,0x78,0x7c,0xe6,0xfd,0x08,0xe6,
+0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,
+0xff,0xf3,0xf0,0x80,0x21,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,
+0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,
+0xca,0x40,0x03,0x7c,0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,
+0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,
+0x40,0x03,0x7c,0x18,0x22,0x78,0x7d,0xe6,0x24,0x0a,0xf6,0x18,0xe6,0x34,0x00,0xf6,
+0x78,0x7a,0x76,0x00,0x78,0x7b,0xe6,0x24,0xff,0xfc,0xe4,0x34,0xff,0xfd,0x78,0x7a,
+0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,0x64,0x80,0x9d,0x40,0x21,
+0x78,0x7c,0x86,0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,
+0x03,0x7c,0x18,0x22,0x78,0x7a,0x06,0x78,0x7d,0x06,0xe6,0x18,0x70,0x01,0x06,0x80,
+0xc3,0x90,0xff,0xf0,0xe0,0x44,0x01,0xf0,0x78,0x7c,0x86,0x83,0x08,0x86,0x82,0xe0,
+0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,0x03,0x7c,0x18,0x22,0x7c,0x00,0x22,0x90,
+0xff,0xf0,0xe0,0x20,0xe7,0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,
+0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x90,0xff,0xf0,0xe0,0x20,0xe3,
+0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0xc3,
+0x22,0x80,0xe7,0xd3,0x22,0x8c,0x42,0x8d,0x41,0x7c,0x00,0xed,0x54,0xf0,0xfd,0xec,
+0x70,0x03,0xed,0x64,0x30,0x70,0x05,0x75,0x3e,0x03,0x80,0x03,0x75,0x3e,0x04,0xac,
+0x3e,0x12,0x0f,0x7c,0x75,0x83,0x00,0x85,0x83,0x40,0xe5,0x41,0x54,0x0f,0xf5,0x3f,
+0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x03,0x70,0x35,0xe5,0x3e,0x24,0xfd,0x75,0xf0,
+0x0a,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0x30,0xe6,0x05,0x12,
+0x10,0x67,0x80,0x19,0xe5,0x3e,0x24,0x97,0xf8,0xc6,0x54,0xfb,0xf6,0x78,0xa3,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x80,0x59,0xe5,
+0x40,0x70,0x04,0xe5,0x3f,0x64,0x04,0x70,0x48,0xe5,0x3e,0x24,0xfd,0x75,0xf0,0x0a,
+0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0x30,0xe5,0x07,0xac,0x42,
+0xad,0x41,0x12,0x1c,0x93,0xe5,0x42,0x30,0xe2,0x15,0x78,0xa7,0xe6,0x30,0xe0,0x0f,
+0x78,0xa7,0xe6,0x30,0xe1,0x09,0xe4,0xff,0x04,0xfe,0x7c,0x04,0x12,0x31,0x9a,0x78,
+0xa3,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x80,
+0x07,0xe4,0xfc,0x7d,0xee,0x12,0x1c,0x93,0xc2,0x03,0x22,0x12,0x30,0x85,0x12,0x0f,
+0x7c,0x78,0xa3,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,
+0xfd,0x40,0xf0,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x90,0xfd,0x41,0xf0,0xc2,0x03,0x7d,0x02,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,
+0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe1,
+0x07,0x7c,0x13,0x12,0x25,0x4a,0x80,0x0f,0x90,0xfd,0x41,0xe0,0xfd,0x78,0x8f,0xe6,
+0xfc,0x12,0x13,0xfd,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,
+0xec,0xf6,0x7d,0x00,0x12,0x0f,0x0b,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,
+0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe2,0x07,0x7c,0x13,0x12,
+0x25,0x4a,0x80,0x1b,0x78,0x8f,0xe6,0x24,0x97,0xf8,0xe6,0x20,0xe1,0x07,0x7c,0x12,
+0x12,0x25,0x4a,0x80,0x0a,0x78,0x8f,0xe6,0xfc,0x12,0x14,0x21,0x12,0x25,0x4a,0x12,
+0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x20,
+0xe2,0x07,0x7c,0x11,0x12,0x25,0x4a,0x80,0x0a,0x78,0x8f,0xe6,0xfc,0x12,0x15,0x22,
+0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0x12,0x0f,
+0x7c,0x78,0xa3,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,
+0xfd,0x47,0xf0,0x78,0xa3,0xe6,0x24,0x0a,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x90,0xfd,0x48,0xf0,0x78,0xa3,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xf5,0x5c,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xf5,0x5d,0x8c,0x5b,0xe4,0xec,0x33,0x33,0x54,0x01,0x78,0x8f,0xf6,0x60,
+0x08,0xe5,0x5c,0x30,0xe1,0x03,0x78,0x8f,0x06,0x78,0x8f,0xe6,0x90,0xfd,0x49,0xf0,
+0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfd,0xa3,
+0xe0,0x54,0x0c,0xfc,0xed,0x54,0xe6,0x8c,0x5f,0xf5,0x5e,0xe5,0x5b,0x30,0xe5,0x03,
+0x43,0x5f,0x01,0xe5,0x5c,0x20,0xe5,0x0e,0xe5,0x5b,0x54,0x7f,0x70,0x08,0xe5,0x5b,
+0x20,0xe7,0x03,0x43,0x5f,0x02,0xe5,0x5b,0x30,0xe3,0x03,0x43,0x5f,0x10,0xe5,0x5b,
+0x30,0xe2,0x03,0x43,0x5f,0x20,0xe5,0x5b,0x54,0x03,0x60,0x03,0x43,0x5f,0x40,0xe5,
+0x5b,0x30,0xe1,0x03,0x43,0x5f,0x80,0xe5,0x5b,0x30,0xe4,0x03,0x43,0x5e,0x01,0xe5,
+0x5b,0x30,0xe6,0x03,0x43,0x5e,0x08,0xe5,0x5c,0x20,0xe4,0x0e,0xe5,0x5b,0x54,0x7f,
+0x70,0x08,0xe5,0x5b,0x20,0xe7,0x03,0x43,0x5e,0x10,0x53,0x5f,0xfb,0x53,0x5e,0xf9,
+0xad,0x5e,0xe5,0x5f,0x90,0xfd,0x42,0xcd,0xf0,0xa3,0xcd,0xf0,0xe5,0x5d,0x30,0xe3,
+0x0d,0xe5,0x5d,0x54,0x30,0xc4,0x54,0x0f,0x90,0xfd,0x45,0xf0,0x80,0x05,0xe4,0x90,
+0xfd,0x45,0xf0,0xe5,0x5d,0x54,0x03,0x90,0xfd,0x44,0xf0,0xe5,0x5d,0x54,0x04,0xc3,
+0x13,0x90,0xfd,0x46,0xf0,0x90,0xfd,0x44,0xe0,0x70,0x0e,0x7d,0x3d,0x7e,0xfd,0x7f,
+0x01,0x74,0x01,0x90,0x00,0x09,0x12,0x01,0x42,0x78,0xa3,0xe6,0x24,0x08,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7c,0x00,0xfd,0x78,0xa3,0xe6,0x24,0x07,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7f,0x00,0x4c,0xfe,0xef,0x4d,0x90,0xfd,
+0x40,0xf0,0xa3,0xce,0xf0,0xce,0xc2,0x03,0x7d,0x0a,0x7c,0x00,0x12,0x24,0xb1,0x12,
+0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0x78,0x94,0x76,0x01,0x08,0x76,
+0xfd,0x08,0x76,0x40,0x78,0x91,0x76,0x0c,0x78,0x94,0x12,0x04,0x65,0x12,0x02,0x14,
+0x78,0x92,0xcb,0xf6,0xcb,0x08,0xf6,0x7f,0x00,0xef,0x24,0xeb,0x40,0x1f,0xe4,0xef,
+0x25,0xe0,0x90,0x34,0xbf,0xfd,0x93,0xcd,0x04,0x93,0x78,0x93,0x66,0x70,0x03,0xed,
+0x18,0x66,0x70,0x06,0x78,0x91,0x76,0x00,0x80,0x03,0x0f,0x80,0xdc,0x78,0x90,0xef,
+0xf6,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x02,0x12,0x02,0x0e,0x78,0x92,0xcb,0xf6,
+0xcb,0x08,0xf6,0x54,0x04,0xcb,0x54,0x06,0x4b,0x60,0x04,0x78,0x91,0x76,0x0b,0x78,
+0x93,0xe6,0x30,0xe3,0x13,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x05,0x12,0x01,0xec,
+0x24,0xfb,0x50,0x04,0x78,0x91,0x76,0x0d,0x78,0x93,0xe6,0x54,0xc0,0x7d,0x00,0x64,
+0xc0,0x4d,0x70,0x04,0x78,0x91,0x76,0x0b,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x04,
+0x12,0x01,0xec,0x24,0xfc,0x50,0x04,0x78,0x91,0x76,0x0f,0x78,0x94,0x12,0x04,0x65,
+0x90,0x00,0x06,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,0x91,0x76,0x0e,0x78,0x94,
+0x12,0x04,0x65,0x90,0x00,0x09,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,0x91,0x76,
+0x0a,0x78,0x91,0xe6,0x70,0x2a,0x78,0x8f,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0x94,0x12,
+0x04,0x65,0x78,0xa1,0xe6,0xf9,0x78,0xa0,0xe6,0xfa,0x7b,0x01,0x74,0x0a,0x78,0x00,
+0x12,0x03,0x3f,0xc2,0x03,0x78,0x8f,0xe6,0xfc,0x12,0x11,0x23,0x78,0x91,0xec,0xf6,
+0x78,0x91,0xe6,0xfc,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,
+0xec,0xf6,0x12,0x0f,0x7c,0x78,0x8f,0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,
+0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xac,0x82,0xad,0x83,0x78,0xa0,0x86,0x83,0x08,
+0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0xc2,0x03,0x78,
+0x8f,0xe6,0xfc,0x12,0x11,0x23,0x12,0x31,0x08,0x22,0x8d,0x2b,0x8c,0x2a,0xed,0x60,
+0x40,0x75,0x27,0x01,0x75,0x29,0x48,0x75,0x28,0xff,0xe5,0x2a,0x24,0xfd,0xfc,0xe4,
+0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x29,
+0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,0x28,0xaf,0x27,0x74,0x80,
+0x90,0x00,0x06,0x12,0x03,0x17,0x74,0x80,0x90,0x00,0x02,0x12,0x03,0x17,0x12,0x0f,
+0xd3,0xe5,0x2b,0x14,0x60,0x3b,0x75,0x27,0x01,0x75,0x29,0x08,0x75,0x28,0xff,0xe5,
+0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,
+0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,
+0x28,0xaf,0x27,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0xe4,0x90,0x00,0x02,0x12,0x03,
+0x17,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe2,
+0x09,0x78,0x8f,0xe6,0xfc,0x12,0x15,0x22,0xd2,0x00,0x78,0x8f,0xe6,0xfc,0x12,0x0f,
+0x7c,0x78,0x90,0x76,0x00,0x90,0xfd,0x41,0xe0,0x30,0xe7,0x04,0x78,0x90,0x76,0x01,
+0x78,0x90,0xe6,0xfd,0x78,0x8f,0xe6,0xfc,0x12,0x0d,0x3a,0xc2,0x03,0x30,0x00,0x07,
+0x78,0x8f,0xe6,0xfc,0x12,0x14,0x21,0x7c,0x00,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,
+0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x01,
+0xf0,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,
+0xe0,0x02,0x80,0xed,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x54,0xf8,0xf0,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0xc2,0x03,0x8c,0x58,0x12,0x0f,0x7c,0x78,0xa0,
+0x86,0x83,0x08,0x86,0x82,0x79,0xee,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,
+0x12,0x0e,0x10,0xac,0x58,0x7d,0x02,0x12,0x0d,0x3a,0xc2,0x03,0xac,0x58,0x12,0x11,
+0x23,0x22,0x8d,0x53,0x8e,0x52,0x8f,0x51,0x8c,0x50,0x12,0x0f,0x7c,0x75,0x4f,0x00,
+0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x20,0xe4,
+0x16,0xe5,0x4f,0x24,0xf6,0x40,0x10,0x05,0x4f,0xc2,0x03,0x7c,0x18,0x12,0x32,0x48,
+0xac,0x50,0x12,0x0f,0x7c,0x80,0xd9,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x20,0xe4,0x05,0xc2,0x03,0x7c,0x02,0x22,0x78,0xa3,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0x60,0x16,0x78,
+0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0xf0,
+0xc2,0x03,0x7c,0x01,0x22,0x78,0xa2,0x86,0x83,0x08,0x86,0x82,0xe0,0xad,0x53,0xae,
+0x52,0xaf,0x51,0x12,0x03,0x0f,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x31,0x8c,0x30,0x12,
+0x15,0x22,0xe5,0x31,0x60,0x20,0xe5,0x30,0xb4,0x03,0x0c,0x7c,0x01,0x12,0x24,0x7c,
+0x7c,0x81,0x12,0x24,0x7c,0x80,0x0f,0xe5,0x30,0xb4,0x04,0x0a,0x7c,0x02,0x12,0x24,
+0x7c,0x7c,0x82,0x12,0x24,0x7c,0xac,0x30,0x12,0x0f,0x7c,0xe5,0x31,0x60,0x1a,0x78,
+0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,0xe7,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,
+0xe7,0xf0,0xac,0x30,0x7d,0x02,0x12,0x0d,0x3a,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,
+0x79,0xf8,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0xc2,0x03,0xe5,0x30,0x24,
+0x97,0xf8,0xc6,0x54,0xfd,0xf6,0xac,0x30,0x12,0x11,0x23,0x22,0x8c,0x26,0x30,0x03,
+0x05,0x12,0x31,0xe7,0x80,0xf8,0x7c,0x0a,0x12,0x30,0xfa,0xd2,0x03,0xe5,0x26,0x24,
+0xfd,0x78,0x9d,0xf6,0x70,0x09,0x78,0xa4,0x76,0xff,0x08,0x76,0xe0,0x80,0x07,0x78,
+0xa4,0x76,0xff,0x08,0x76,0xe2,0x78,0x9d,0xe6,0x75,0xf0,0x10,0xa4,0xad,0xf0,0xfc,
+0x24,0xa0,0x78,0xa3,0xf6,0xed,0x34,0xff,0x18,0xf6,0x78,0x9d,0xe6,0x75,0xf0,0x0a,
+0xa4,0x24,0x08,0xfc,0xe4,0x34,0xfd,0xfd,0x78,0xa0,0xed,0xf6,0x08,0xec,0xf6,0x12,
+0x31,0x93,0x22,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x30,0xe7,0x22,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0x78,0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,
+0x7f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,0x82,0xf5,0x83,0xe0,
+0x54,0x7f,0xf0,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x54,0xf8,0xf0,0x78,0xa5,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x44,0x03,0xf0,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0x74,0x0f,0xf0,0x22,0x78,0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,
+0x3f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,0x82,0xf5,0x83,0xe0,
+0x54,0x3f,0xf0,0x78,0x9d,0xe6,0x24,0x9e,0xf8,0xe6,0xfc,0x78,0xa5,0xe6,0x24,0x01,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0x9d,0xe6,0x24,0x9e,0xf8,
+0xe6,0xfc,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,
+0xf0,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,
+0xfb,0x44,0x02,0xf5,0x26,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x30,0xe5,0x03,0x43,0x26,0x01,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,0x03,0x12,0x0f,0xd3,0xe5,0x26,0xfc,
+0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,
+0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x78,
+0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x44,0x80,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x44,
+0x80,0xf0,0x22,0x8c,0x2a,0x12,0x0f,0x7c,0x78,0xa1,0xe6,0x24,0x08,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x0a,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa1,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xec,0xf0,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,0xe0,0xfd,0xa3,0xe0,0xfc,
+0xed,0xfe,0x78,0xa3,0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xee,
+0xf0,0xec,0xfe,0x78,0xa3,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xee,0xf0,0x8c,0x29,0x8d,0x28,0xc3,0xec,0x94,0x02,0xed,0x94,0x06,0x40,0x05,0x75,
+0x27,0x7c,0x80,0x33,0xd3,0xe5,0x29,0x94,0x81,0xe5,0x28,0x94,0x01,0x40,0x05,0x75,
+0x27,0x3c,0x80,0x23,0xd3,0xe5,0x29,0x94,0xc0,0xe5,0x28,0x94,0x00,0x40,0x05,0x75,
+0x27,0x18,0x80,0x13,0xd3,0xe5,0x29,0x94,0x30,0xe5,0x28,0x94,0x00,0x40,0x05,0x75,
+0x27,0x0c,0x80,0x03,0x75,0x27,0x08,0xaf,0x27,0xe4,0xef,0x54,0x7c,0x44,0x83,0xff,
+0x8f,0x27,0xe5,0x27,0xfc,0x78,0xa5,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0x9d,0xe6,0x24,0x9e,0xf8,0xec,
+0xf6,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,
+0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,
+0x30,0xe3,0x17,0x53,0x27,0xc7,0x78,0xa1,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x90,0x34,0xe9,0x93,0x42,0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe7,0x05,0x43,0x27,0x40,0x80,0x03,
+0x53,0x27,0xbf,0x53,0x27,0xfb,0x78,0xa1,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x60,0x03,0x43,0x27,0x04,0x53,0x27,0xfc,0x78,0xa1,0xe6,0x24,
+0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x42,0x27,0x43,0x27,0x80,0xe5,
+0x27,0xfc,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,
+0xf0,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,
+0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,
+0x30,0xe1,0x05,0x53,0x27,0xdf,0x80,0x03,0x43,0x27,0x20,0x78,0xa1,0xe6,0x24,0x02,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x05,0x53,0x27,0xef,0x80,
+0x03,0x43,0x27,0x10,0x78,0xa1,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xb4,0x02,0x03,0x43,0x27,0x02,0xe5,0x27,0xfc,0x78,0xa3,0xe6,0x24,0x04,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa3,0xe6,0x24,0x03,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa1,0xe6,0x24,0x09,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x70,0x05,0x53,0x27,0x7f,0x80,0x03,0x43,
+0x27,0x80,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,
+0xe0,0x30,0xe0,0x05,0x43,0x27,0x20,0x80,0x03,0x53,0x27,0xdf,0x78,0xa1,0xe6,0x24,
+0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe3,0x05,0x43,0x27,0x40,
+0x80,0x03,0x53,0x27,0xbf,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x30,0xe0,0x05,0x43,0x27,0x10,0x80,0x03,0x53,0x27,0xef,0x78,0xa1,
+0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe4,0x05,
+0x43,0x27,0x08,0x80,0x03,0x53,0x27,0xf7,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe5,0x05,0x43,0x27,0x04,0x80,0x03,0x53,
+0x27,0xfb,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,
+0xe0,0x30,0xe6,0x05,0x43,0x27,0x01,0x80,0x03,0x53,0x27,0xfe,0x78,0xa1,0xe6,0x24,
+0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe7,0x05,0x43,0x27,
+0x02,0x80,0x03,0x53,0x27,0xfd,0xe5,0x27,0xfc,0x78,0xa3,0xe6,0x24,0x03,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x27,0x8c,
+0x26,0xed,0x54,0x03,0x14,0x60,0x03,0x7c,0x10,0x22,0xe5,0x27,0x54,0x7c,0x24,0xfc,
+0x40,0x03,0x7c,0x0b,0x22,0xe5,0x26,0x24,0x97,0xf8,0xc6,0x44,0x02,0xf6,0x7c,0x00,
+0x22,0x8c,0x30,0x12,0x0f,0x7c,0xe5,0x30,0x24,0x97,0xf8,0xe6,0x20,0xe2,0x4f,0xac,
+0x30,0x7d,0x02,0x12,0x0d,0x3a,0xe5,0x30,0x24,0xfe,0x44,0x28,0xfc,0x78,0xa4,0x86,
+0x83,0x08,0x86,0x82,0xec,0xf0,0xaf,0x83,0xe5,0x82,0x24,0x04,0xfe,0xe4,0x3f,0xff,
+0xec,0x8e,0x82,0x8f,0x83,0xf0,0x7c,0x03,0x8c,0x2c,0xe5,0x2c,0xfc,0x78,0xa5,0xe6,
+0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x2c,0xfc,0x78,
+0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x75,0x2d,
+0x01,0x75,0x2f,0x48,0x75,0x2e,0xff,0xe5,0x30,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,
+0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x2f,0x2c,0xf5,0x2f,
+0xe5,0x2e,0x3d,0xf5,0x2e,0x78,0xa5,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x54,0xe7,0xf5,0x2c,0xad,0x2f,0xae,0x2e,0xaf,0x2d,0xe4,0x90,0x00,
+0x02,0x12,0x03,0x17,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0x12,0x01,0xe6,0x30,0xe5,
+0x03,0x43,0x2c,0x10,0xe5,0x2c,0xfc,0x78,0xa5,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xec,0xf0,0x12,0x10,0x67,0x78,0xa3,0xe6,0x24,0x06,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xc2,0x03,0xfc,0xe5,0x30,0x24,0x97,0xf8,0xc6,
+0x44,0x04,0xf6,0x8c,0x2c,0xe5,0x30,0x54,0x0f,0xc4,0x54,0xf0,0x7e,0x00,0xff,0xee,
+0xef,0x44,0x04,0x7d,0x00,0xff,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0x12,0x1c,0xfe,0x7c,
+0x00,0x22,0x8c,0x2f,0x12,0x0f,0x7c,0x12,0x10,0x07,0x78,0xa4,0x86,0x83,0x08,0x86,
+0x82,0xe0,0x54,0x08,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0x08,0xf0,0xac,0x2f,0x7d,
+0x02,0x12,0x0d,0x3a,0xc2,0x03,0xe5,0x2f,0x24,0x97,0xf8,0xc6,0x54,0xfb,0xf6,0x7c,
+0x00,0x22,0x12,0x30,0x85,0x78,0x90,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe1,
+0x0a,0x7d,0x00,0x7c,0x13,0x12,0x24,0xb1,0x12,0x31,0x08,0x78,0x90,0xe6,0x24,0x97,
+0xf8,0xc6,0x44,0x01,0xf6,0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0x90,0xe6,0x24,
+0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,0xa0,
+0xe6,0xfa,0x08,0xe6,0xf9,0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0x78,0xa0,0x86,0x83,
+0x08,0x86,0x82,0x79,0xf8,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0x12,0x0f,
+0xd3,0xc2,0x03,0x78,0x90,0xe6,0xfc,0x12,0x11,0x23,0x78,0x8f,0xec,0xf6,0xec,0x60,
+0x0a,0x7d,0x00,0x7c,0x08,0x12,0x24,0xb1,0x12,0x31,0x08,0x78,0x90,0xe6,0xfc,0x12,
+0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,
+0x44,0x10,0x54,0xdf,0xfc,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xec,0xf0,0x78,0x8f,0xec,0xf6,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,
+0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,0x90,
+0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x10,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,0x90,0xe6,
+0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x44,0x20,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0x48,0x78,0x90,0xe6,0xfc,
+0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x30,0xe4,0x15,0xc2,0x03,0x78,0x90,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,
+0x12,0x31,0x9a,0x12,0x31,0x08,0x02,0x17,0x49,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xcf,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,
+0x48,0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x30,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0x48,
+0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x14,0xc2,0x03,0x78,0x90,0xe6,0x44,0x10,0x7f,
+0x00,0xfe,0x7c,0x07,0x12,0x31,0x9a,0x12,0x31,0x08,0x80,0x5d,0x78,0xa3,0xe6,0x24,
+0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x78,0xa3,0xe6,
+0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x78,0x90,
+0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,
+0xac,0x82,0xad,0x83,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,
+0x0a,0x78,0x01,0x12,0x03,0xa7,0xc2,0x03,0x78,0x90,0xe6,0xfc,0x12,0x11,0x23,0x7d,
+0x00,0x7c,0x0b,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,0xff,0x91,
+0xe0,0x90,0xfd,0x41,0xf0,0x7d,0x02,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,
+0x12,0x30,0x85,0x90,0xfd,0x40,0xe0,0xf4,0xfc,0x90,0xff,0x91,0xe0,0x5c,0xf5,0x33,
+0x90,0xfd,0x41,0xe0,0xfc,0x90,0xfd,0x40,0xe0,0x5c,0x42,0x33,0xe5,0x33,0x90,0xff,
+0x91,0xf0,0x7c,0x00,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x74,0x3c,0x90,0xfb,0xe8,
+0xf0,0x74,0x3e,0x90,0xfb,0xe8,0xf0,0xe4,0x90,0xfd,0x30,0xf0,0x22,0x8d,0x35,0x8c,
+0x34,0xec,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x02,0x80,0x28,0xb4,0x02,0x02,0x80,
+0x03,0xd3,0x40,0x08,0xa8,0x35,0xc6,0x25,0xe0,0xf6,0x80,0x18,0xb4,0x04,0x02,0x80,
+0x03,0xd3,0x40,0x0a,0xa8,0x35,0xc6,0x25,0xe0,0x25,0xe0,0xf6,0x80,0x06,0xa8,0x35,
+0x76,0x00,0x80,0x00,0x22,0x8c,0x3c,0x8d,0x3b,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x75,
+0x60,0x06,0x75,0x61,0x00,0x90,0xfd,0x31,0x12,0x04,0x6e,0x12,0x01,0xe6,0xb4,0x80,
+0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x18,0x9e,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,
+0x00,0x03,0x12,0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x5f,0x90,
+0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,
+0x01,0x90,0xfd,0x34,0x12,0x04,0x6e,0xee,0xcd,0x90,0x35,0x02,0xfc,0xe4,0x93,0xff,
+0x74,0x01,0x93,0xfe,0xf9,0xef,0xfa,0x7b,0x01,0xea,0xff,0xe9,0xfe,0xec,0xc3,0x9e,
+0xed,0x9f,0x40,0x25,0x90,0x35,0x04,0xe4,0x93,0xfd,0x74,0x01,0x93,0xfc,0xed,0xfe,
+0xec,0xfd,0x7f,0x01,0xee,0xcd,0xfc,0x90,0xfd,0x36,0xe0,0xd3,0x9c,0x90,0xfd,0x35,
+0xe0,0x9d,0x50,0x05,0x75,0x60,0x80,0x80,0x33,0x12,0x19,0xbc,0x80,0x2e,0xb4,0x60,
+0x02,0x80,0x03,0xd3,0x40,0x0b,0xac,0x3c,0xad,0x3b,0x12,0x07,0x82,0x8c,0x60,0x80,
+0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,
+0x40,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,0x81,0x80,0x00,0x80,0x75,0xb4,0x81,
+0x02,0x80,0x03,0xd3,0x40,0x6b,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x03,0x12,
+0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x1d,0x90,0xfd,0x31,0x12,
+0x04,0x80,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfd,
+0x37,0x12,0x04,0x6e,0x12,0x19,0x26,0x80,0x36,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,
+0x13,0x75,0x3a,0x61,0xe4,0xf5,0x39,0xf5,0x38,0xac,0x3c,0xad,0x3b,0x12,0x05,0xde,
+0x8c,0x60,0x80,0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,
+0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,0x81,0x80,0x00,0x80,
+0x02,0x80,0x00,0xe5,0x60,0xfc,0x90,0xfd,0x31,0x12,0x04,0x80,0xec,0x90,0x00,0x02,
+0x12,0x03,0x17,0xac,0x61,0x22,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,0x12,
+0x01,0xec,0x60,0x04,0x74,0x01,0x80,0x01,0xe4,0xa2,0xe0,0x92,0x01,0x90,0xfd,0x31,
+0x12,0x04,0x80,0xed,0x24,0x03,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x34,0x12,0x04,0x6e,
+0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x61,0x90,0x00,
+0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x61,0x12,0x17,0x9d,0xe5,0x61,0x70,0x04,
+0x75,0x60,0x08,0x22,0x75,0x60,0x00,0x78,0x7e,0x76,0x00,0x78,0x7e,0xe6,0xc3,0x95,
+0x61,0x50,0x38,0x90,0xfd,0x37,0x12,0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfd,0x34,
+0x12,0x04,0x80,0xec,0x12,0x03,0x0f,0x30,0x01,0x0e,0x90,0xfd,0x39,0xe0,0x04,0xf0,
+0x90,0xfd,0x38,0x70,0x03,0xe0,0x04,0xf0,0x78,0x7e,0x06,0x90,0xfd,0x36,0xe0,0x04,
+0xf0,0x90,0xfd,0x35,0x70,0x03,0xe0,0x04,0xf0,0x80,0xc0,0x22,0x90,0xfd,0x32,0xe0,
+0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0xed,0x24,0x0a,0xfd,0x50,0x01,
+0x0e,0x90,0xfd,0x3a,0x12,0x04,0x6e,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,
+0x12,0x01,0xec,0x54,0x0f,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x17,0x90,0xfd,0x3a,
+0x12,0x04,0x80,0x0d,0xed,0x70,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,0x78,0x82,
+0x76,0x01,0x80,0x4e,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfd,0x3a,0x12,
+0x04,0x80,0xed,0x24,0x02,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,0x78,
+0x82,0x76,0x02,0x80,0x2d,0xb4,0x04,0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfd,0x3a,
+0x12,0x04,0x80,0xed,0x24,0x04,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,
+0x78,0x82,0x76,0x04,0x80,0x0c,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,
+0x08,0x22,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x61,
+0x78,0x7f,0x76,0x00,0x78,0x7f,0xe6,0xc3,0x95,0x61,0x40,0x03,0x02,0x1b,0x24,0x78,
+0x80,0x76,0x00,0x78,0x80,0xe6,0xc3,0x78,0x82,0x96,0x50,0x76,0x90,0xfd,0x34,0x12,
+0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfd,0x3a,0x12,0x04,0x89,0x12,0x01,0xe0,0xf4,
+0x5c,0xfc,0x12,0x01,0xe0,0xf8,0x90,0xfd,0x37,0x12,0x04,0x80,0xe8,0xc0,0xe0,0x12,
+0x01,0xe6,0xc8,0xd0,0xe0,0xc8,0x58,0x4c,0xfc,0x90,0xfd,0x34,0x12,0x04,0x80,0xec,
+0x12,0x03,0x0f,0x78,0x81,0xec,0xf6,0x90,0xfd,0x39,0xe0,0x04,0xf0,0x90,0xfd,0x38,
+0x70,0x03,0xe0,0x04,0xf0,0x09,0xe9,0x70,0x01,0x0a,0x90,0xfd,0x3a,0x12,0x04,0x77,
+0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x30,0xe4,0x0e,0x90,
+0xfd,0x36,0xe0,0x04,0xf0,0x90,0xfd,0x35,0x70,0x03,0xe0,0x04,0xf0,0x78,0x80,0x06,
+0x80,0x81,0x78,0x82,0xe6,0xfd,0xe4,0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfd,0x39,0xe0,
+0x2c,0xf0,0x90,0xfd,0x38,0xe0,0x3d,0xf0,0x78,0x82,0xe6,0xfd,0xe4,0xfe,0xff,0xee,
+0xcd,0xfc,0x90,0xfd,0x3c,0xe0,0x2c,0xf0,0x90,0xfd,0x3b,0xe0,0x3d,0xf0,0x78,0x7f,
+0x06,0x02,0x1a,0x64,0x75,0x60,0x00,0x22,0xe5,0x3d,0x05,0x3d,0x04,0x70,0x02,0xb2,
+0xb0,0x22,0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,
+0xc0,0xe0,0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,
+0xe0,0xef,0xc0,0xe0,0x90,0xff,0x92,0xe0,0x12,0x01,0xb7,0x1b,0x80,0x30,0x1b,0x80,
+0x32,0x1b,0x8f,0x38,0x1b,0xa1,0x3a,0x1b,0xb3,0x3e,0x1b,0xcb,0x44,0x1b,0xbf,0x46,
+0x1b,0xd7,0x50,0x1c,0x19,0x52,0x1b,0xf8,0x54,0x1c,0x3a,0x56,0x00,0x00,0x1c,0x5b,
+0x90,0xff,0x92,0xe0,0x7f,0x00,0xfe,0x7c,0x01,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,
+0xff,0x04,0xfe,0x7c,0x03,0x12,0x31,0x9a,0x74,0x20,0x90,0xff,0xfe,0xf0,0x02,0x1c,
+0x6b,0xe4,0xff,0x04,0xfe,0x7c,0x02,0x12,0x31,0x9a,0x74,0x40,0x90,0xff,0xfe,0xf0,
+0x02,0x1c,0x6b,0xe4,0xff,0x04,0xfe,0x7c,0x04,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,
+0xff,0x04,0xfe,0x7c,0x05,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,0xff,0x04,0xfe,0x7c,
+0x06,0x12,0x31,0x9a,0x02,0x1c,0x6b,0x90,0xff,0xa5,0xe0,0x7d,0x00,0x90,0xfd,0x00,
+0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x01,0xe0,0xfc,0xf5,0x83,0x90,0xfd,0x00,0xe0,
+0x44,0x33,0xfd,0x12,0x1c,0xfe,0x80,0x73,0x90,0xff,0xb5,0xe0,0x7d,0x00,0x90,0xfd,
+0x02,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x03,0xe0,0xfc,0xf5,0x83,0x90,0xfd,0x02,
+0xe0,0x44,0x43,0xfd,0x12,0x1c,0xfe,0x80,0x52,0x90,0xff,0xa6,0xe0,0x7d,0x00,0x90,
+0xfd,0x04,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x05,0xe0,0xfc,0xf5,0x83,0x90,0xfd,
+0x04,0xe0,0x44,0x34,0xfd,0x12,0x1c,0xfe,0x80,0x31,0x90,0xff,0xb6,0xe0,0x7d,0x00,
+0x90,0xfd,0x06,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x07,0xe0,0xfc,0xf5,0x83,0x90,
+0xfd,0x06,0xe0,0x44,0x44,0xfd,0x12,0x1c,0xfe,0x80,0x10,0x90,0xff,0x92,0xe0,0x7d,
+0x00,0xfc,0xed,0x44,0xaa,0xfd,0x12,0x1c,0xfe,0x80,0x00,0xe4,0x90,0xff,0x92,0xf0,
+0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,
+0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,
+0xd0,0xe0,0x32,0x05,0x81,0x05,0x81,0x05,0x81,0x05,0x81,0xa8,0x81,0x18,0x18,0x18,
+0xed,0xf6,0x08,0xec,0xf6,0x90,0xff,0x6a,0xe0,0x20,0xe7,0x02,0x80,0xf7,0x90,0xff,
+0x69,0xe0,0x7d,0x00,0xa8,0x81,0x18,0xcd,0xf6,0xcd,0x08,0xf6,0x7d,0x03,0xa8,0x81,
+0xe6,0x18,0xfc,0xe6,0xcc,0x25,0xe0,0xcc,0x33,0xcc,0xdd,0xf9,0xcc,0xf6,0xcc,0x08,
+0xf6,0xa8,0x81,0x18,0xe6,0x44,0xf8,0xf6,0xa8,0x81,0x18,0x18,0x18,0xe6,0xfd,0x08,
+0xe6,0xfc,0xa8,0x81,0x18,0x86,0x83,0x08,0x86,0x82,0xed,0xf0,0xa3,0xec,0xf0,0x74,
+0x02,0x90,0xff,0x6a,0xf0,0x15,0x81,0x15,0x81,0x15,0x81,0x15,0x81,0x22,0xe5,0x81,
+0x24,0x05,0xf5,0x81,0xe4,0xa8,0x81,0x18,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,
+0xf6,0x08,0xec,0xf6,0x90,0xfb,0xfd,0xe0,0x24,0xf8,0x50,0x03,0x02,0x1e,0x1f,0xe4,
+0xa8,0x81,0x18,0x18,0xf6,0xa8,0x81,0x18,0xe6,0xfe,0xa8,0x81,0x18,0x18,0x18,0x18,
+0xe6,0xfd,0x08,0xe6,0xfc,0x7f,0x00,0xef,0x24,0xf8,0x40,0x4d,0xe4,0xef,0x25,0xe0,
+0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x6c,0x70,0x03,
+0xfa,0xeb,0x6d,0x70,0x09,0x74,0x01,0xa8,0x81,0x18,0x18,0xf6,0x80,0x2b,0xe4,0xef,
+0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x7a,0x00,0xe0,0x54,0xf0,
+0xcc,0xf8,0xcc,0xcd,0xf9,0xcd,0xfb,0x78,0x00,0xe9,0x54,0xf0,0xf9,0xea,0x68,0x70,
+0x02,0xeb,0x69,0x70,0x01,0x0e,0x0f,0x80,0xae,0xa8,0x81,0x18,0xee,0xf6,0xa8,0x81,
+0x18,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0xa8,0x81,0xef,0xf6,0xa8,0x81,0x18,
+0x18,0xe6,0x70,0x79,0xa8,0x81,0x18,0xe6,0x24,0xf7,0x40,0x71,0xa8,0x81,0x18,0x18,
+0x18,0x18,0xe6,0x54,0x0f,0xa8,0x81,0xf6,0x64,0x04,0x60,0x17,0xa8,0x81,0xe6,0x64,
+0x03,0x60,0x10,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x1c,
+0x93,0x80,0x4a,0x7c,0x0a,0x12,0x30,0xfa,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,
+0x08,0xe6,0xfc,0x90,0xfb,0xfc,0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,
+0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,0x90,0xfb,0xfc,0xe0,0xff,0xe4,0xef,0x04,0x54,
+0x07,0xff,0x90,0xfb,0xfc,0xf0,0x90,0xfb,0xfd,0xe0,0x04,0xf0,0x12,0x31,0x93,0x90,
+0xfb,0xfe,0xe0,0x70,0x08,0xe4,0xfe,0xff,0x7c,0x0f,0x12,0x31,0x9a,0x80,0x27,0x90,
+0xfb,0xff,0xe0,0x04,0xf0,0x54,0x3f,0x70,0x1d,0x90,0xfb,0xff,0xe0,0x44,0xfe,0x7d,
+0x00,0xfc,0x90,0xfb,0xfc,0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,
+0x83,0xed,0xf0,0xa3,0xec,0xf0,0xe5,0x81,0x24,0xfb,0xf5,0x81,0x22,0x78,0x85,0x76,
+0x00,0x78,0x86,0x76,0x00,0x74,0x01,0x90,0xfb,0xfe,0xf0,0x12,0x30,0x85,0x90,0xfb,
+0xfd,0xe0,0x60,0x59,0x7c,0x0a,0x12,0x30,0xfa,0x90,0xfb,0xfb,0xe0,0x25,0xe0,0x24,
+0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0xfc,0x90,0xfb,0xfb,
+0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,
+0x90,0xfb,0xfb,0xe0,0xff,0xe4,0xef,0x04,0x54,0x07,0xff,0x90,0xfb,0xfb,0xf0,0x90,
+0xfb,0xfd,0xe0,0x14,0xf0,0x78,0x83,0xed,0xf6,0x08,0xec,0xf6,0x12,0x31,0x93,0xb2,
+0xb3,0x78,0x83,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x08,0xe5,0x80,0xa1,0x12,0x31,0xe7,
+0x78,0x85,0x06,0xb6,0x00,0x11,0x78,0x85,0x76,0x00,0x78,0x86,0xe6,0xf4,0x04,0x04,
+0xa2,0xe0,0x92,0xb4,0x78,0x86,0xf6,0x80,0x85,0xe4,0x90,0xfb,0xfe,0xf0,0x90,0xfb,
+0xfd,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xcf,0xfd,0x12,0x1c,0x93,0x12,0x31,0x08,0x22,
+0x12,0x30,0x85,0xe5,0x6a,0x64,0x49,0x45,0x69,0x60,0x15,0x90,0xff,0x83,0xe0,0x54,
+0x0f,0x7d,0x00,0xd3,0x95,0x6a,0xed,0x95,0x69,0x50,0x05,0x12,0x2e,0xce,0x80,0x03,
+0x12,0x2f,0x9e,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0xe5,0x6a,0x64,0x49,0x45,0x69,
+0x60,0x05,0x12,0x2f,0xd8,0x80,0x0e,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x90,0xff,
+0x83,0xe0,0x54,0x7f,0xf0,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x8c,0x54,0xec,0x54,
+0xf0,0xb4,0x10,0x15,0x75,0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0xe5,0x64,0x24,
+0x03,0xf5,0x64,0xe5,0x63,0x34,0x00,0xf5,0x63,0xe4,0xf5,0x57,0xf5,0x56,0xe5,0x56,
+0xc3,0x94,0x01,0x50,0x27,0xe5,0x54,0x54,0x0f,0xfc,0xad,0x64,0xae,0x63,0xaf,0x62,
+0x12,0x0e,0x82,0x8c,0x55,0xec,0x60,0x02,0x80,0x12,0x05,0x64,0xe5,0x64,0x70,0x02,
+0x05,0x63,0x05,0x57,0xe5,0x57,0x70,0x02,0x05,0x56,0x80,0xd2,0xe5,0x54,0x54,0x0f,
+0x24,0x97,0xf8,0xc6,0x54,0xfe,0xf6,0xe5,0x54,0x54,0x0f,0x7f,0x00,0xfe,0x7c,0x12,
+0x12,0x31,0x9a,0xe5,0x55,0x14,0x70,0x09,0x7d,0x00,0x7c,0x09,0x12,0x24,0xb1,0x80,
+0x07,0xad,0x57,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,
+0xff,0xfc,0xe0,0x44,0x02,0xf0,0x90,0xff,0x00,0xe0,0x30,0xe7,0x13,0x90,0xff,0x83,
+0xe0,0x44,0x80,0xf0,0x43,0x67,0x80,0x90,0xff,0xfc,0xe0,0x44,0x01,0xf0,0x80,0x11,
+0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x53,0x67,0x7f,0x90,0xff,0xfc,0xe0,0x54,0xfe,
+0xf0,0x90,0xff,0x81,0xe0,0x44,0x80,0xf0,0x12,0x25,0x64,0x90,0xff,0xfe,0xe0,0x44,
+0x05,0xf0,0x90,0xff,0xfc,0xe0,0x54,0xfd,0xf0,0x12,0x31,0x08,0x22,0x12,0x30,0x85,
+0x7c,0x01,0x12,0x32,0x48,0x78,0xa7,0xe6,0x44,0x02,0xf6,0x74,0xfe,0xfc,0x04,0xfd,
+0x12,0x1c,0xfe,0x90,0xff,0x6a,0xe0,0x30,0xe7,0x02,0x80,0xf7,0xe4,0xf5,0x4e,0x75,
+0x4d,0x10,0xac,0x4e,0xad,0x4d,0xe5,0x4e,0x15,0x4e,0x70,0x02,0x15,0x4d,0xec,0x4d,
+0x60,0x02,0x80,0xee,0x43,0x87,0x01,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x7c,0x02,
+0x12,0x31,0x14,0x78,0xa7,0xe6,0x54,0xfd,0xf6,0x12,0x31,0x08,0x22,0x12,0x30,0x85,
+0x78,0xa7,0xe6,0x30,0xe0,0x2c,0x78,0xa7,0xe6,0x30,0xe1,0x26,0x78,0xa7,0xe6,0xfc,
+0xf5,0x83,0x18,0xe6,0x44,0xf0,0xfd,0x12,0x1c,0x93,0x90,0xff,0xfc,0xe0,0x44,0x20,
+0xf0,0x7c,0x02,0x12,0x32,0x48,0x78,0xa7,0xe6,0x54,0xfd,0xf6,0x74,0x1a,0x90,0xff,
+0xfe,0xf0,0x78,0xa7,0xe6,0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf1,0xfd,0x12,0x1c,0x93,
+0x12,0x31,0x08,0x22,0x75,0x67,0x00,0x75,0x68,0x00,0xe4,0xf5,0x66,0xf5,0x65,0xe4,
+0xf5,0x69,0x75,0x6a,0x49,0x74,0x84,0x90,0xff,0x82,0xf0,0x74,0x84,0x90,0xff,0x80,
+0xf0,0x74,0x80,0x90,0xff,0x68,0xf0,0x74,0x80,0x90,0xff,0x6a,0xf0,0xad,0x46,0xaf,
+0x45,0x7e,0x00,0xee,0x24,0xfc,0x50,0x03,0x02,0x21,0x6a,0xe4,0xee,0x75,0xf0,0x07,
+0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,0x80,
+0xfd,0xe4,0xef,0x54,0x0f,0x14,0xff,0xed,0x60,0x38,0xe4,0xef,0x75,0xf0,0x08,0xa4,
+0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,
+0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,
+0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,
+0x80,0x34,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x20,0xd3,0x8d,0x46,0x8e,0x44,0x8f,0x45,
+0x74,0x7f,0x90,0xff,0xfd,0xf0,0x74,0x90,0x90,0xff,0xfc,0xf0,0x90,0xfc,0x19,0xe0,
+0x30,0xe6,0x07,0x90,0xff,0xfc,0xe0,0x44,0x04,0xf0,0x22,0x90,0xfc,0x0d,0xe0,0x14,
+0x70,0x04,0x90,0xfc,0x0c,0xe0,0x70,0x39,0x90,0xfc,0x00,0x79,0x06,0x7a,0x35,0x7b,
+0x12,0x78,0x01,0x12,0x03,0xf5,0x7f,0x00,0xef,0x33,0x40,0x15,0xef,0x90,0x35,0x4d,
+0x93,0xfc,0xef,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xec,0xf0,0x0f,0x80,
+0xe7,0x8f,0x59,0x90,0xfc,0x2b,0x79,0x18,0x7a,0x35,0x7b,0x35,0x78,0x01,0x12,0x03,
+0xf5,0xe4,0x90,0xff,0xff,0xf0,0x74,0x51,0x90,0xff,0xfa,0xf0,0x74,0x04,0x90,0xff,
+0xfb,0xf0,0x74,0x53,0x90,0xff,0xf8,0xf0,0x74,0x51,0x90,0xff,0xf9,0xf0,0x74,0x55,
+0x90,0xff,0xf7,0xf0,0x74,0x93,0x90,0xff,0xf6,0xf0,0x74,0x32,0x90,0xff,0xf5,0xf0,
+0x75,0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0xe4,0x90,0xff,0x83,0xf0,0x74,0x80,
+0x90,0xff,0x81,0xf0,0x75,0x58,0x04,0xe5,0x58,0x75,0xf0,0x07,0xa4,0x24,0x3f,0xf5,
+0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x78,0x89,0xf6,0xfc,0x54,0x0f,0x14,0xfc,0x78,
+0x89,0xec,0xf6,0xe5,0x58,0x75,0xf0,0x07,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0xfc,
+0xf5,0x83,0xe0,0x78,0x8c,0x76,0xf8,0x08,0x76,0x00,0xfc,0x78,0x89,0xe6,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x89,0xe6,
+0x75,0xf0,0x08,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xec,0xf0,0x78,
+0x8c,0xe6,0xff,0x08,0xe6,0x7e,0x03,0xcf,0xc3,0x13,0xcf,0x13,0xde,0xf9,0xfe,0x78,
+0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xee,
+0xf0,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0x74,0x80,0xf0,0x78,0x8a,0xec,0xf6,0x7d,0x00,0x78,0x8d,0xe6,0x2c,0xf6,0x18,
+0xe6,0x3d,0xf6,0x78,0x8c,0xe6,0xfd,0x08,0xe6,0x7c,0x03,0xcd,0xc3,0x13,0xcd,0x13,
+0xdc,0xf9,0xfc,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xec,0xf0,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8c,0xe6,0xfd,0x08,0xe6,0xfc,0x78,0x89,
+0xe6,0xff,0x7e,0x00,0xee,0x24,0xfc,0x50,0x03,0x02,0x24,0x6b,0xe4,0xee,0x75,0xf0,
+0x07,0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,
+0x80,0xfa,0xe4,0xef,0x54,0x0f,0x14,0xff,0xe4,0xee,0x75,0xf0,0x07,0xa4,0x24,0x41,
+0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x78,0x8a,0xf6,0xee,0x75,0xf0,0x80,0xa4,
+0x24,0x08,0xf8,0xe5,0xf0,0x34,0xf8,0xf9,0xe8,0xfc,0xe9,0xfd,0x8a,0x59,0xea,0x70,
+0x03,0x02,0x23,0xd8,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8a,0xe6,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,
+0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,0xec,0x7a,0x03,0xcb,
+0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x8a,0xe6,0x7b,0x00,0xfa,0xec,0x2a,
+0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,
+0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,
+0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,
+0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,0x34,0xff,
+0xf5,0x83,0x74,0x80,0xf0,0x02,0x24,0x67,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x08,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8a,0xe6,0xfa,0xe4,0xef,0x75,
+0xf0,0x08,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,
+0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,
+0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x8a,0xe6,0x7b,
+0x00,0xfa,0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,
+0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0d,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x22,0xf4,0x8e,0x58,0x78,0x8c,0xed,
+0xf6,0x08,0xec,0xf6,0x78,0x89,0xef,0xf6,0x12,0x20,0xa4,0x22,0x8c,0x26,0xec,0x30,
+0xe7,0x18,0xe5,0x26,0x54,0x0f,0x14,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x80,0x16,0xe5,0x26,0x54,0x0f,0x14,0x75,
+0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,
+0x22,0xec,0x90,0xfd,0x3f,0xf0,0x8c,0x24,0xed,0x24,0x03,0xf5,0x25,0x7d,0x00,0xd3,
+0x95,0x6c,0xed,0x95,0x6b,0x40,0x03,0x85,0x6c,0x25,0xe5,0x25,0x24,0xb7,0x50,0x09,
+0x75,0x25,0x03,0x74,0x02,0x90,0xfd,0x3f,0xf0,0xac,0x25,0x12,0x2f,0xc3,0x22,0xe4,
+0xf5,0x66,0xf5,0x65,0x12,0x24,0xe8,0x22,0x90,0xfd,0x3d,0xe0,0x65,0x6d,0x60,0x0e,
+0x74,0x04,0x90,0xfd,0x3f,0xf0,0xe4,0xf5,0x65,0x75,0x66,0x03,0x80,0x46,0x7d,0x6d,
+0xe4,0xfe,0xff,0x79,0x3d,0x7a,0xfd,0x7b,0x01,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,
+0xe5,0x66,0x24,0x03,0xf5,0x66,0xe5,0x65,0x34,0x00,0xf5,0x65,0xe5,0x66,0xd3,0x95,
+0x6c,0xe5,0x65,0x95,0x6b,0x40,0x06,0x85,0x6c,0x66,0x85,0x6b,0x65,0xd3,0xe5,0x66,
+0x94,0x48,0xe5,0x65,0x94,0x00,0x40,0x0c,0x74,0x02,0x90,0xfd,0x3f,0xf0,0xe4,0xf5,
+0x65,0x75,0x66,0x03,0xac,0x66,0x12,0x2f,0xc3,0x22,0xec,0x90,0xfd,0x3f,0xf0,0xe4,
+0xf5,0x66,0xf5,0x65,0x8c,0x32,0xec,0x60,0x05,0x12,0x2f,0xb4,0x80,0x05,0x7c,0x00,
+0x12,0x2f,0xc3,0x22,0x90,0xff,0x04,0xe0,0xf5,0x4a,0x90,0xff,0x06,0xe0,0xfd,0xa3,
+0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,
+0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0xc3,0xec,0x94,0x48,0xed,0x94,
+0x00,0x50,0x22,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,
+0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,
+0xed,0x4f,0xfd,0x80,0x04,0xe4,0xfd,0x7c,0x48,0x8c,0x6c,0x8d,0x6b,0x90,0xff,0x02,
+0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x02,0xe0,0xff,
+0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xf5,0x4c,0xed,0x4f,0xf5,0x4b,0x75,
+0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0x7d,0x3d,0x7e,0xfd,0x7f,0x01,0x79,0x6d,
+0xe4,0xfa,0xfb,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,0x75,0x49,0x00,0xe5,0x49,0x24,
+0xfe,0x40,0x19,0xad,0x64,0xae,0x63,0xaf,0x62,0xe4,0x12,0x03,0x0f,0x05,0x49,0x0d,
+0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,0xe1,0x75,0x64,0x3d,0x75,
+0x63,0xfd,0x75,0x62,0x01,0x90,0xff,0x00,0xe0,0x54,0x60,0xb4,0x00,0x02,0x80,0x06,
+0xd3,0x50,0x03,0x02,0x2c,0x12,0xe5,0x4a,0x54,0x0f,0xf5,0x49,0xe5,0x4a,0x54,0x80,
+0xa2,0xe0,0x92,0x02,0x90,0xff,0x01,0xe0,0x12,0x01,0x81,0x00,0x0b,0x2c,0x0d,0x26,
+0x67,0x27,0x85,0x2c,0x0d,0x28,0x91,0x2c,0x0d,0x29,0x74,0x29,0xa8,0x2b,0x0f,0x2b,
+0x12,0x2b,0x52,0x2b,0xb6,0x2b,0xe4,0xe5,0x67,0x30,0xe7,0x0e,0xe5,0x4c,0x45,0x4b,
+0x70,0x08,0xe5,0x6c,0x64,0x02,0x45,0x6b,0x60,0x03,0x02,0x2c,0x0f,0x90,0xff,0x00,
+0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x4a,0x60,0x03,0x02,
+0x27,0x82,0xad,0x64,0xae,0x63,0xaf,0x62,0x74,0x01,0x12,0x03,0x0f,0x78,0xa7,0xe6,
+0x30,0xe0,0x0b,0xad,0x64,0xae,0x63,0xaf,0x62,0x74,0x02,0x12,0x03,0x0f,0x7c,0x02,
+0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x1b,0xe5,0x67,0x20,0xe1,
+0x07,0xe5,0x4a,0x60,0x03,0x02,0x27,0x82,0xe5,0x4a,0x24,0xfe,0x50,0x03,0x02,0x27,
+0x82,0x7c,0x02,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,
+0x27,0x80,0xe5,0x67,0x20,0xe1,0x0d,0xe5,0x4a,0x60,0x09,0xe5,0x4a,0x64,0x80,0x60,
+0x03,0x02,0x27,0x82,0xac,0x4a,0x12,0x30,0x4a,0x40,0x03,0x02,0x27,0x82,0xe5,0x49,
+0x70,0x25,0x30,0x02,0x11,0x90,0xff,0x80,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,0xaf,
+0x62,0x12,0x03,0x0f,0x80,0x0f,0x90,0xff,0x82,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,
+0xaf,0x62,0x12,0x03,0x0f,0x80,0x3d,0x15,0x49,0x30,0x02,0x1d,0xe5,0x49,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x64,
+0xae,0x63,0xaf,0x62,0x12,0x03,0x0f,0x80,0x1b,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,
+0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,0xaf,
+0x62,0x12,0x03,0x0f,0xad,0x64,0xae,0x63,0xaf,0x62,0x12,0x01,0xe6,0x60,0x0b,0xad,
+0x64,0xae,0x63,0xaf,0x62,0x74,0x01,0x12,0x03,0x0f,0x7c,0x02,0x12,0x2f,0xc3,0x22,
+0x80,0x00,0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe7,0x06,0xe5,0x6c,0x45,0x6b,0x60,0x03,
+0x02,0x2c,0x0f,0x90,0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,
+0x1a,0xe5,0x4c,0x14,0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x28,0x8e,0x78,
+0xa7,0xe6,0x54,0xfe,0xf6,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,
+0xd3,0x40,0x2a,0xe5,0x67,0x20,0xe1,0x08,0xe5,0x67,0x20,0xe0,0x03,0x02,0x28,0x8e,
+0xe5,0x67,0x30,0xe0,0x04,0xe5,0x4a,0x70,0x0b,0xe5,0x67,0x30,0xe1,0x09,0xe5,0x4a,
+0x24,0xfe,0x50,0x03,0x02,0x28,0x8e,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,
+0x80,0x06,0xd3,0x50,0x03,0x02,0x28,0x8c,0xe5,0x4c,0x45,0x4b,0x60,0x03,0x02,0x28,
+0x8e,0xac,0x4a,0x12,0x30,0x4a,0x40,0x03,0x02,0x28,0x8e,0xe5,0x67,0x20,0xe1,0x07,
+0xe5,0x67,0x20,0xe0,0x02,0x80,0x77,0xe5,0x67,0x30,0xe0,0x06,0xe5,0x49,0x60,0x02,
+0x80,0x6c,0xe5,0x49,0x70,0x0f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x80,
+0xe0,0x54,0xf7,0xf0,0x22,0xe5,0x49,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,
+0x01,0x7c,0x03,0x12,0x0f,0x0b,0x80,0x11,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x09,
+0x7d,0x01,0x7c,0x04,0x12,0x0f,0x0b,0x80,0x00,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,
+0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xf7,
+0xf0,0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,
+0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x00,0x02,0x2c,
+0x0f,0xe5,0x67,0x20,0xe7,0x06,0xe5,0x6c,0x45,0x6b,0x60,0x03,0x02,0x2c,0x0f,0x90,
+0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,0x4c,0x14,
+0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0x71,0x78,0xa7,0xe6,0x44,0x01,
+0xf6,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,
+0x67,0x20,0xe1,0x08,0xe5,0x67,0x20,0xe0,0x03,0x02,0x29,0x71,0xe5,0x67,0x30,0xe0,
+0x04,0xe5,0x49,0x70,0x0b,0xe5,0x67,0x30,0xe1,0x08,0xe5,0x49,0x24,0xfe,0x50,0x02,
+0x80,0x7f,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x6f,
+0xe5,0x4c,0x45,0x4b,0x60,0x02,0x80,0x69,0xac,0x4a,0x12,0x30,0x4a,0x40,0x02,0x80,
+0x60,0xe5,0x67,0x20,0xe1,0x07,0xe5,0x67,0x20,0xe0,0x02,0x80,0x54,0xe5,0x49,0x70,
+0x14,0x30,0x02,0x09,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x80,0x07,0x90,0xff,0x82,
+0xe0,0x44,0x08,0xf0,0x22,0xe5,0x67,0x30,0xe1,0x33,0x15,0x49,0x30,0x02,0x15,0xe5,
+0x49,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x44,
+0x08,0xf0,0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xe0,0x44,0x08,0xf0,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x02,0x80,
+0x00,0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe7,0x12,0xe5,0x6c,0x45,0x6b,0x70,0x0c,0xe5,
+0x4a,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x0f,0xe5,0x4c,
+0x90,0xff,0xff,0xf0,0x90,0xff,0xff,0xe0,0x60,0x05,0x43,0x67,0x01,0x80,0x03,0x53,
+0x67,0xfe,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xe5,0x67,0x30,0xe7,0x0e,0xe5,0x6c,0x45,
+0x6b,0x60,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x0f,0xad,0x4b,
+0xe5,0x4c,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0xbd,0x00,0x02,0x80,0x03,0x02,0x2b,
+0x0a,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x32,0xe5,0x4a,0x70,0x05,0xe5,0x4c,0xfc,
+0x60,0x03,0x02,0x2b,0x0c,0x75,0x64,0x00,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,0xe5,
+0x6c,0x94,0x12,0xe5,0x6b,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x12,0x80,0x04,0xac,
+0x6c,0xad,0x6b,0x8c,0x6a,0x8d,0x69,0x12,0x2f,0xd8,0x22,0xb4,0x02,0x02,0x80,0x03,
+0xd3,0x40,0x59,0xe5,0x4a,0x60,0x03,0x02,0x2b,0x0c,0xe5,0x4c,0xfc,0x70,0x27,0x75,
+0x64,0x12,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,0xe5,0x6c,0x94,0x19,0xe5,0x6b,0x94,
+0x00,0x40,0x06,0xe4,0xfd,0x7c,0x19,0x80,0x04,0xac,0x6c,0xad,0x6b,0x8c,0x6a,0x8d,
+0x69,0x12,0x2f,0xd8,0x80,0x25,0x75,0x64,0x2b,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,
+0xe5,0x6c,0x94,0x35,0xe5,0x6b,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x35,0x80,0x04,
+0xac,0x6c,0xad,0x6b,0x8c,0x6a,0x8d,0x69,0x12,0x2f,0xd8,0x22,0xb4,0x03,0x02,0x80,
+0x06,0xd3,0x50,0x03,0x02,0x2b,0x0a,0xe5,0x4c,0xf5,0x49,0x70,0x0f,0x90,0xff,0x04,
+0xe0,0xfd,0xa3,0xe0,0x4d,0x60,0x03,0x02,0x2b,0x0c,0x80,0x18,0x90,0xfc,0x82,0xe0,
+0xfd,0xa3,0xe0,0xfc,0x90,0xff,0x05,0xe0,0x6c,0x70,0x07,0x90,0xff,0x04,0xe0,0x6d,
+0x60,0x02,0x80,0x68,0xe4,0xf5,0x6a,0xf5,0x69,0x7f,0x00,0xe5,0x49,0x14,0xc5,0x49,
+0x60,0x0f,0xef,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x2f,0xff,0x80,
+0xea,0x8f,0x4a,0xe5,0x4a,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x7d,
+0x00,0xd3,0x95,0x6c,0xed,0x95,0x6b,0x40,0x06,0xac,0x6c,0xad,0x6b,0x80,0x0f,0xe5,
+0x4a,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x7d,0x00,0xfc,0x8c,0x6a,
+0x8d,0x69,0xe5,0x4a,0x24,0x80,0xfc,0xe4,0x34,0xfc,0xfd,0xfe,0xec,0xfd,0x7f,0x01,
+0x8d,0x64,0x8e,0x63,0x8f,0x62,0x12,0x2f,0xd8,0x22,0x80,0x00,0x02,0x2c,0x0f,0x02,
+0x2c,0x0f,0xe5,0x67,0x30,0xe7,0x19,0xe5,0x6c,0x14,0x45,0x6b,0x70,0x12,0xe5,0x4a,
+0x70,0x0e,0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,
+0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe0,0x08,0xe5,0x67,0x20,0xe1,0x03,0x02,0x2c,0x0f,
+0x75,0x64,0x68,0xe4,0xf5,0x63,0xf5,0x62,0xe4,0xf5,0x69,0x04,0xf5,0x6a,0x12,0x2f,
+0xd8,0x22,0xe5,0x67,0x20,0xe7,0x27,0xe5,0x6c,0x45,0x6b,0x70,0x21,0xe5,0x4a,0x70,
+0x1d,0xe5,0x4c,0x64,0x02,0x45,0x4b,0x60,0x0d,0xe5,0x4c,0x14,0x45,0x4b,0x60,0x06,
+0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,
+0x0f,0xe5,0x67,0x20,0xe0,0x08,0xe5,0x67,0x20,0xe1,0x03,0x02,0x2c,0x0f,0x85,0x4c,
+0x68,0xe5,0x68,0x70,0x08,0x43,0x67,0x01,0x53,0x67,0xfd,0x80,0x13,0xe5,0x68,0x64,
+0x02,0x60,0x07,0xe5,0x68,0x14,0x60,0x02,0x80,0x65,0x53,0x67,0xfe,0x43,0x67,0x02,
+0x7c,0x00,0x12,0x2f,0xc3,0x22,0xe5,0x67,0x30,0xe7,0x1a,0xe5,0x6c,0x14,0x45,0x6b,
+0x70,0x13,0xe5,0x4a,0x70,0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,
+0x54,0x1f,0x14,0x60,0x02,0x80,0x38,0xe5,0x67,0x20,0xe1,0x02,0x80,0x31,0x7c,0x01,
+0x12,0x2f,0xc3,0x22,0xe5,0x67,0x20,0xe7,0x15,0xe5,0x6c,0x45,0x6b,0x70,0x0f,0xe5,
+0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,0x80,0x0f,
+0xe5,0x67,0x20,0xe1,0x02,0x80,0x08,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x00,0x02,
+0x2e,0xca,0xb4,0x40,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x2e,0xc0,0x90,0xff,0x01,
+0xe0,0x90,0xfd,0x3d,0xf0,0xe5,0x4a,0x90,0xfd,0x3e,0xf0,0xe4,0x90,0xfd,0x3f,0xf0,
+0xe5,0x64,0x24,0x03,0xf5,0x64,0xe5,0x63,0x34,0x00,0xf5,0x63,0xad,0x4b,0xe5,0x4c,
+0x85,0x64,0x82,0x85,0x63,0x83,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xff,0x01,0xe0,0x12,
+0x01,0xb7,0x2c,0x7d,0x01,0x2c,0xa3,0x02,0x2c,0xcd,0x03,0x2c,0xf7,0x04,0x2d,0x45,
+0x05,0x2d,0x82,0x06,0x2d,0xa8,0x07,0x2d,0xce,0x08,0x2d,0xf4,0x09,0x2e,0x1a,0x0b,
+0x2e,0x40,0x0c,0x2e,0x4f,0x80,0x2e,0x4f,0x81,0x00,0x00,0x2e,0xad,0xe5,0x67,0x20,
+0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0x7d,0xb7,0x7e,0x34,0x7f,0x02,0x79,0x40,
+0x7a,0xfd,0x7b,0x01,0x74,0x08,0x78,0x00,0x12,0x03,0x3f,0x7d,0x08,0x7c,0x00,0x12,
+0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0xe5,0x4a,
+0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,
+0x10,0x12,0x31,0x9a,0x22,0x7d,0x00,0x7c,0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,
+0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,
+0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x11,0x12,0x31,0x9a,0x22,0x7d,
+0x00,0x7c,0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,
+0x4a,0x22,0xe5,0x4a,0xb4,0x05,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,
+0x7c,0x0a,0x12,0x31,0x9a,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,
+0x04,0xfe,0x7c,0x08,0x12,0x31,0x9a,0x22,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,
+0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x13,0x12,0x31,0x9a,0x22,0x7d,0x00,0x7c,
+0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x34,0xd3,0xe5,0x6c,0x94,0x48,0xe5,
+0x6b,0x94,0x00,0x50,0x06,0xe5,0x6c,0x45,0x6b,0x70,0x06,0x7c,0x02,0x12,0x25,0x4a,
+0x22,0xe5,0x4a,0xb4,0x01,0x03,0xb3,0x40,0x0b,0xc3,0xb4,0x03,0x00,0x40,0x09,0xb4,
+0x06,0x00,0x50,0x04,0x12,0x30,0x70,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,
+0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,
+0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x16,0x12,0x31,0x9a,0x22,0x7c,0x07,
+0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,
+0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x19,
+0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,
+0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,
+0x4a,0x7f,0x00,0xfe,0x7c,0x17,0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,
+0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,
+0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x18,0x12,0x31,0x9a,0x22,
+0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,
+0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,
+0x7c,0x15,0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,
+0xe5,0x67,0x20,0xe7,0x06,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,
+0x67,0x30,0xe7,0x20,0x90,0xff,0x00,0xe0,0x54,0x1f,0x70,0x10,0x90,0xff,0x01,0xe0,
+0xb4,0x80,0x05,0x12,0x24,0xdf,0x80,0x03,0x12,0x24,0xe8,0x22,0x7d,0x00,0x7c,0x05,
+0x12,0x24,0xb1,0x22,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x06,0x7c,0x05,0x12,0x25,
+0x4a,0x22,0xd3,0xe5,0x6c,0x94,0x48,0xe5,0x6b,0x94,0x00,0x50,0x0b,0xc3,0xe5,0x6c,
+0x94,0x07,0xe5,0x6b,0x94,0x00,0x50,0x06,0x7c,0x03,0x12,0x25,0x4a,0x22,0xe5,0x4a,
+0xb4,0x05,0x04,0x12,0x30,0x70,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0xe5,0x67,0x30,
+0xe7,0x08,0x7d,0x00,0x7c,0x05,0x12,0x24,0xb1,0x22,0x7c,0x05,0x12,0x25,0x4a,0x22,
+0xb4,0x20,0x02,0x80,0x03,0xd3,0x40,0x00,0x80,0x00,0x12,0x2f,0x9e,0x22,0x75,0x43,
+0x00,0x90,0xff,0x83,0xe0,0x54,0x0f,0xd3,0x95,0x43,0x40,0x24,0xe5,0x43,0x24,0xf0,
+0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,0xe0,0xad,0x64,0xae,0x63,0xaf,0x62,0x12,0x03,
+0x0f,0x05,0x43,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,0xd1,
+0xe5,0x43,0x7d,0x00,0xfc,0xc3,0xe5,0x6a,0x9c,0xf5,0x6a,0xe5,0x69,0x9d,0xf5,0x69,
+0xe5,0x6a,0x45,0x69,0x60,0x06,0xe4,0x90,0xff,0x83,0xf0,0x22,0x90,0xff,0x82,0xe0,
+0x44,0x08,0xf0,0xe4,0xf5,0x69,0x75,0x6a,0x49,0x90,0xfd,0x3d,0xe0,0xb4,0x05,0x02,
+0x80,0x03,0xd3,0x40,0x40,0x90,0xfd,0x3e,0xe0,0xf5,0x43,0xb4,0x05,0x02,0x80,0x03,
+0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0b,0x12,0x31,0x9a,0x22,0xb4,0x01,0x02,
+0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x09,0x12,0x31,0x9a,0x22,0xb4,
+0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x43,0x7f,0x00,0xfe,0x7c,0x14,
+0x12,0x31,0x9a,0x22,0x22,0xb4,0x80,0x00,0x40,0x23,0xb4,0x82,0x00,0x50,0x1e,0x7c,
+0x3d,0x7d,0xfd,0x12,0x17,0xd5,0x7d,0x00,0x8c,0x66,0x8d,0x65,0x90,0xfd,0x3f,0xe0,
+0x60,0x05,0x12,0x2f,0x9e,0x80,0x05,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x22,0x90,0xff,
+0x83,0xe0,0x54,0x7f,0xf0,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,
+0x44,0x08,0xf0,0x22,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,0x44,
+0x08,0xf0,0x22,0x8c,0x23,0x7d,0x00,0x8c,0x6a,0x8d,0x69,0x75,0x64,0x3d,0x75,0x63,
+0xfd,0x75,0x62,0x01,0x12,0x2f,0xd8,0x22,0x90,0xff,0x83,0xe0,0x54,0x7f,0xf0,0xe5,
+0x6a,0x64,0x49,0x45,0x69,0x70,0x01,0x22,0xc3,0xe5,0x6a,0x94,0x08,0xe5,0x69,0x94,
+0x00,0x40,0x15,0x75,0x21,0x08,0xe5,0x21,0x7d,0x00,0xfc,0xc3,0xe5,0x6a,0x9c,0xf5,
+0x6a,0xe5,0x69,0x9d,0xf5,0x69,0x80,0x09,0x85,0x6a,0x21,0xe4,0xf5,0x69,0x75,0x6a,
+0x49,0x75,0x22,0x00,0xe5,0x22,0xc3,0x95,0x21,0x50,0x26,0xad,0x64,0xae,0x63,0xaf,
+0x62,0x12,0x01,0xe6,0xfc,0xe5,0x22,0x24,0xf8,0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,
+0xec,0xf0,0x05,0x22,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,
+0xd3,0xe5,0x21,0x54,0x7f,0x90,0xff,0x81,0xf0,0x22,0x8c,0x48,0x7f,0x00,0xef,0x24,
+0xfb,0x40,0x19,0xe4,0xef,0x75,0xf0,0x07,0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,
+0xf5,0x83,0xe0,0x65,0x48,0x70,0x02,0xd3,0x22,0x0f,0x80,0xe2,0x8f,0x47,0xc3,0x22,
+0x85,0x6c,0x6a,0x85,0x6b,0x69,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x83,
+0xe0,0x54,0x7f,0xf0,0x22,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xe5,
+0x72,0x24,0x08,0xf8,0x86,0x06,0x53,0x06,0x7f,0x7c,0xff,0x12,0x30,0xfa,0x7c,0x00,
+0x7d,0x00,0xe5,0x75,0x60,0x46,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x7f,0x6e,0x70,0x0f,
+0xc0,0x83,0xc0,0x82,0xa3,0xe0,0xfd,0xa3,0xe0,0xfc,0xa3,0x15,0x75,0x80,0x07,0xa3,
+0xa3,0xa3,0xdf,0xe6,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0x1e,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,
+0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x12,0x31,0x93,0xd0,
+0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x22,0x85,0xa8,0x74,0x75,0xa8,0x88,
+0xec,0x70,0x02,0x7c,0x3f,0x8c,0x73,0x22,0xe5,0x72,0x24,0x08,0xf8,0x76,0x00,0x12,
+0x31,0xe7,0x80,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xae,0x04,
+0x7c,0xff,0x12,0x30,0xfa,0xe5,0x75,0x60,0x42,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x7f,
+0x6e,0x70,0x0b,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x15,0x75,0x80,0x07,0xa3,0xa3,
+0xa3,0xdf,0xea,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0xd8,0xe0,0xf8,0xa3,
+0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,0xea,
+0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x78,0x08,0x08,0x79,0x18,
+0x09,0x7c,0x01,0xe6,0x54,0x7f,0x6e,0x70,0x06,0x76,0x00,0x77,0x00,0x80,0x06,0x08,
+0x09,0x0c,0xbc,0x08,0xee,0x12,0x31,0x93,0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0x22,0x75,0x73,0x00,0x85,0x74,0xa8,0x22,0xc0,0xf0,0xc0,0x82,0xc0,0x83,
+0xc3,0xe5,0x75,0x24,0xe8,0x50,0x05,0x12,0x31,0xe7,0x80,0xf4,0xec,0x60,0x31,0x90,
+0x34,0xb6,0xe4,0x93,0xc3,0x9c,0x40,0x28,0xc0,0x04,0x7c,0xff,0x12,0x30,0xfa,0xd0,
+0x04,0x43,0x04,0x80,0xe5,0x75,0x75,0xf0,0x03,0xa4,0x24,0x9d,0xf5,0x82,0xe4,0x34,
+0xfe,0xf5,0x83,0xec,0xf0,0xef,0xa3,0xf0,0xee,0xa3,0xf0,0x05,0x75,0x12,0x31,0x93,
+0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0xc0,0x04,0x7c,0x20,0xd2,0x8c,0xd2,0x8d,0xd5,
+0x04,0xfd,0xd0,0x04,0x22,0x75,0xa8,0x00,0x75,0x88,0x00,0x75,0xb8,0x00,0x75,0xf0,
+0x00,0x75,0xd0,0x00,0xe4,0xf8,0x90,0x00,0x00,0xf6,0x08,0xb8,0x00,0xfb,0x02,0x00,
+0x00,0xc3,0xed,0x94,0x02,0x50,0x04,0x7d,0x03,0x7c,0xe8,0xec,0xf4,0xfc,0xed,0xf4,
+0xfd,0x0c,0xbc,0x00,0x01,0x0d,0x8c,0x79,0x8d,0x78,0x22,0xc3,0xec,0x94,0xbc,0xed,
+0x94,0x02,0x50,0x04,0x7d,0x07,0x7c,0xd0,0xec,0xf4,0xfc,0xed,0xf4,0xfd,0x0c,0xbc,
+0x00,0x01,0x0d,0x8c,0x77,0x8d,0x76,0x22,0xec,0x70,0x01,0x22,0xc0,0x00,0xe5,0x72,
+0x24,0x18,0xf8,0xa6,0x04,0xe5,0x72,0x24,0x08,0xf8,0xc6,0x54,0x7f,0xf6,0xe6,0x30,
+0xe7,0x03,0xd0,0x00,0x22,0x12,0x31,0xe7,0x80,0xf4,0xc2,0x8c,0x85,0x76,0x8c,0x85,
+0x77,0x8a,0xd2,0x8c,0xc0,0xe0,0xc0,0xd0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,
+0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x12,0x1b,
+0x28,0xe5,0x72,0x24,0x08,0xf8,0xe6,0x60,0x24,0xe5,0x72,0x24,0x10,0xf8,0xa6,0x81,
+0xe5,0x72,0x75,0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,
+0xa8,0xe5,0x81,0x04,0xc3,0x98,0xf9,0xe6,0xf0,0x08,0xa3,0xd9,0xfa,0x74,0x08,0x25,
+0x72,0xf8,0x05,0x72,0x08,0xe6,0x54,0x80,0x70,0x0c,0xe5,0x72,0xb4,0x07,0xf3,0x78,
+0x08,0x75,0x72,0x00,0x80,0xef,0xe5,0x72,0x24,0x10,0xf8,0x86,0x81,0xe5,0x72,0x75,
+0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,0xa8,0xe5,0x81,
+0x04,0xc3,0x98,0xf9,0xe0,0xf6,0x08,0xa3,0xd9,0xfa,0xd0,0x07,0xd0,0x06,0xd0,0x05,
+0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,
+0xd0,0xd0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc2,
+0x8e,0x85,0x78,0x8d,0x85,0x79,0x8b,0xd2,0x8e,0x78,0x19,0x79,0x09,0x7a,0x07,0xe7,
+0x70,0x04,0xa6,0x00,0x80,0x0b,0xe6,0x60,0x08,0x16,0xe6,0x70,0x04,0xe7,0x44,0x80,
+0xf7,0x08,0x09,0xda,0xea,0xe5,0x73,0x60,0x13,0x14,0xf5,0x73,0x70,0x0e,0xe5,0x72,
+0x24,0x08,0xf8,0x76,0x00,0x12,0x31,0x93,0xd2,0x8c,0xd2,0x8d,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0xd0,0xd0,0xd0,0xe0,0x32,0x75,0x81,0xa7,0x75,0x90,0x00,0x75,0x79,0x30,
+0x75,0x78,0xf8,0x75,0x77,0x60,0x75,0x76,0xf0,0x12,0x05,0x3c,0x12,0x34,0x0f,0x12,
+0x17,0x8b,0x12,0x34,0x39,0x12,0x31,0xf5,0x80,0xe3,0x22,0xc0,0x00,0x7c,0x01,0xec,
+0x24,0x08,0xf8,0xe6,0x60,0x09,0x0c,0xbc,0x08,0xf5,0x12,0x31,0xe7,0x80,0xee,0xd0,
+0x00,0x22,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,0xc0,0x06,0xc0,0x07,0xed,0x24,
+0x10,0xf8,0x76,0xb6,0xed,0x75,0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,
+0xf5,0x83,0xc0,0x82,0xc0,0x83,0xa3,0xa3,0xe4,0x78,0x0d,0xf0,0xa3,0xd8,0xfc,0xec,
+0x54,0x7f,0x75,0xf0,0x02,0xa4,0x24,0x82,0xf5,0x82,0xe5,0xf0,0x34,0x34,0xf5,0x83,
+0xe4,0x93,0xfe,0x74,0x01,0x93,0xf5,0x82,0x8e,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,
+0xff,0xd0,0x83,0xd0,0x82,0xef,0xf0,0xa3,0xee,0xf0,0xed,0x24,0x08,0xf8,0xec,0x44,
+0x80,0xf6,0xd0,0x07,0xd0,0x06,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0x75,
+0x72,0x00,0x75,0x75,0x00,0x7a,0x08,0x79,0x18,0x78,0x08,0x76,0x00,0x77,0x00,0x08,
+0x09,0xda,0xf8,0xe4,0x78,0x08,0x74,0x80,0x44,0x7f,0xf6,0x74,0x01,0x44,0x10,0xf5,
+0x89,0x75,0xb8,0x08,0xd2,0xab,0xd2,0xa9,0x22,0x75,0x81,0xa7,0xd2,0x8e,0xd2,0x8c,
+0xd2,0xaf,0xe5,0x75,0x60,0x32,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x80,0x60,0x24,0x78,
+0x08,0x79,0x08,0xe0,0x54,0x7f,0xfa,0x7b,0x00,0xe6,0x54,0x7f,0xb5,0x02,0x02,0x7b,
+0xff,0x08,0xd9,0xf5,0xeb,0x70,0x0c,0xea,0xf0,0x12,0x33,0x8b,0xad,0x04,0xac,0x02,
+0x12,0x33,0xa2,0xa3,0xa3,0xa3,0xdf,0xd2,0x12,0x31,0xe7,0x80,0xc5,0x7c,0x01,0x7d,
+0x00,0x22,0x04,0xf5,0x04,0xe9,0x04,0xed,0x04,0xe1,0x04,0xdd,0x04,0xd9,0x04,0xe5,
+0x04,0xf1,0x04,0x9d,0x04,0xa1,0x04,0xcd,0x04,0xd1,0x04,0x99,0x04,0x99,0x04,0x99,
+0x04,0xd5,0x04,0xb5,0x04,0xad,0x04,0xb1,0x04,0xa9,0x04,0xc1,0x04,0xbd,0x04,0xb9,
+0x04,0xc5,0x04,0xc9,0x04,0xa5,0x19,0x01,0x03,0x00,0x22,0x00,0x48,0x02,0x00,0x24,
+0x0f,0x18,0x0a,0x10,0x64,0x0d,0x68,0x0c,0x05,0x06,0x02,0x03,0x01,0x01,0x81,0x01,
+0x00,0x00,0xe7,0x00,0xc0,0x00,0x80,0x00,0x60,0x00,0x40,0x00,0x30,0x00,0x18,0x00,
+0x0c,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x08,0x18,0x38,0x28,0x06,0x02,
+0x10,0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x10,0x0a,0x02,0x00,0x00,0x00,
+0x00,0x00,0xfb,0xe8,0xfb,0xfa,0x12,0x01,0x10,0x01,0xff,0x00,0x00,0x08,0x51,0x04,
+0x5f,0x50,0x16,0x01,0x01,0x02,0x00,0x02,0x09,0x02,0x35,0x00,0x01,0x02,0x00,0xe0,
+0x00,0x09,0x04,0x00,0x00,0x05,0xff,0x00,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00,
+0x00,0x07,0x05,0x01,0x02,0x40,0x00,0x00,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,
+0x05,0x02,0x02,0x40,0x00,0x00,0x07,0x05,0x85,0x03,0x02,0x00,0x01,0x04,0x03,0x09,
+0x04,0x24,0x03,0x54,0x00,0x65,0x00,0x78,0x00,0x61,0x00,0x73,0x00,0x20,0x00,0x49,
+0x00,0x6e,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x75,0x00,0x6d,0x00,0x65,0x00,0x6e,
+0x00,0x74,0x00,0x73,0x00,0x2a,0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x35,
+0x00,0x30,0x00,0x35,0x00,0x32,0x00,0x20,0x00,0x53,0x00,0x65,0x00,0x72,0x00,0x69,
+0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x50,0x00,0x6f,0x00,0x72,0x00,0x74,0x00,0x22,
+0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x35,0x00,0x30,0x00,0x35,0x00,0x32,
+0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,
+0x00,
+};
+
+#endif /* ifndef _TI_FW_5052_H_ */
ChangeSet 1.1938.446.27, 2004/12/15 16:38:01-08:00, [email protected]
[PATCH] USB: better messages for "no-IRQ" cases (15/15)
This changes the usbcore message about HCD IRQ problems so it makes
sense on systems without ACPI or an APIC. It also updates the comments;
the issue doesn't appiear only with PCI, and with the recent enumeration
changes it doesn't happen just with set_address either.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/core/hcd.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:47:52 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:47:52 -08:00
@@ -1251,13 +1251,14 @@
goto done;
}
- /* PCI IRQ setup can easily be broken so that USB controllers
+ /* IRQ setup can easily be broken so that USB controllers
* never get completion IRQs ... maybe even the ones we need to
- * finish unlinking the initial failed usb_set_address().
+ * finish unlinking the initial failed usb_set_address()
+ * or device descriptor fetch.
*/
if (!hcd->saw_irq && hcd->self.root_hub != urb->dev) {
dev_warn (hcd->self.controller, "Unlink after no-IRQ? "
- "Different ACPI or APIC settings may help."
+ "Controller is probably using the wrong IRQ."
"\n");
hcd->saw_irq = 1;
}
ChangeSet 1.1938.446.10, 2004/12/15 15:12:10-08:00, [email protected]
[PATCH] USB Storage: Remove old XLATE-only entries from unusual_devs.h
This patch removes all entries from unusual_devs.h that appear to have
only been there for the MODE_XLATE flag which was removed in my previous
patch.
Signed-off-by: Phil Dibowitz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/storage/unusual_devs.h | 26 --------------------------
1 files changed, 26 deletions(-)
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h 2005-01-07 15:50:16 -08:00
+++ b/drivers/usb/storage/unusual_devs.h 2005-01-07 15:50:16 -08:00
@@ -739,15 +739,6 @@
US_FL_BULK32),
-/* Aiptek PocketCAM 3Mega
- * Nicolas DUPEUX <[email protected]>
- */
-UNUSUAL_DEV( 0x08ca, 0x2011, 0x0000, 0x9999,
- "AIPTEK",
- "PocketCAM 3Mega",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- 0 ),
-
/* Entry needed for flags. Moreover, all devices with this ID use
* bulk-only transport, but _some_ falsely report Control/Bulk instead.
* One example is "Trumpion Digital Research MYMP3".
@@ -773,12 +764,6 @@
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
-UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001,
- "Minds@Work",
- "Digital Wallet",
- US_SC_DEVICE, US_PR_DEVICE, 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
@@ -881,17 +866,6 @@
"Desknote",
"UCR-61S2B",
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
- 0 ),
-
-/* Reported by Dan Pilone <[email protected]>
- * The device needs the flags only.
- * 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,
- "CCYU TECHNOLOGY",
- "EasyDisk Portable Device",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
0 ),
/* Reported by Kotrla Vitezslav <[email protected]> */
ChangeSet 1.1938.446.4, 2004/12/15 14:13:33-08:00, [email protected]
[PATCH] USB: fix sparse and compiler warnings in ti_usb_3410_5052.c
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/ti_usb_3410_5052.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff -Nru a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
--- a/drivers/usb/serial/ti_usb_3410_5052.c 2005-01-07 15:51:02 -08:00
+++ b/drivers/usb/serial/ti_usb_3410_5052.c 2005-01-07 15:51:02 -08:00
@@ -179,7 +179,7 @@
static int ti_get_serial_info(struct ti_port *tport,
struct serial_struct __user *ret_arg);
static int ti_set_serial_info(struct ti_port *tport,
- struct serial_struct *new_arg);
+ struct serial_struct __user *new_arg);
static void ti_handle_new_msr(struct ti_port *tport, __u8 msr);
static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush);
@@ -200,10 +200,10 @@
/* circular buffer */
static struct circ_buf *ti_buf_alloc(void);
-static inline void ti_buf_free(struct circ_buf *cb);
-static inline void ti_buf_clear(struct circ_buf *cb);
-static inline int ti_buf_data_avail(struct circ_buf *cb);
-static inline int ti_buf_space_avail(struct circ_buf *cb);
+static void ti_buf_free(struct circ_buf *cb);
+static void ti_buf_clear(struct circ_buf *cb);
+static int ti_buf_data_avail(struct circ_buf *cb);
+static int ti_buf_space_avail(struct circ_buf *cb);
static int ti_buf_put(struct circ_buf *cb, const char *buf, int count);
static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
@@ -841,7 +841,7 @@
case TIOCSSERIAL:
dbg("%s - (%d) TIOCSSERIAL", __FUNCTION__, port->number);
- return ti_set_serial_info(tport, (struct serial_struct *)arg);
+ return ti_set_serial_info(tport, (struct serial_struct __user *)arg);
break;
case TIOCMIWAIT:
@@ -1428,7 +1428,7 @@
static int ti_set_serial_info(struct ti_port *tport,
- struct serial_struct *new_arg)
+ struct serial_struct __user *new_arg)
{
struct usb_serial_port *port = tport->tp_port;
struct serial_struct new_serial;
@@ -1734,7 +1734,7 @@
* Free the buffer and all associated memory.
*/
-static inline void ti_buf_free(struct circ_buf *cb)
+static void ti_buf_free(struct circ_buf *cb)
{
kfree(cb->buf);
kfree(cb);
@@ -1747,7 +1747,7 @@
* Clear out all data in the circular buffer.
*/
-static inline void ti_buf_clear(struct circ_buf *cb)
+static void ti_buf_clear(struct circ_buf *cb)
{
cb->head = cb->tail = 0;
}
@@ -1760,7 +1760,7 @@
* buffer.
*/
-static inline int ti_buf_data_avail(struct circ_buf *cb)
+static int ti_buf_data_avail(struct circ_buf *cb)
{
return CIRC_CNT(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
}
@@ -1773,7 +1773,7 @@
* buffer.
*/
-static inline int ti_buf_space_avail(struct circ_buf *cb)
+static int ti_buf_space_avail(struct circ_buf *cb)
{
return CIRC_SPACE(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
}
ChangeSet 1.1938.439.44, 2004/12/22 23:31:52-08:00, [email protected]
Merge kroah.com:/home/greg/linux/BK/bleed-2.6
into kroah.com:/home/greg/linux/BK/usb-2.6
drivers/usb/atm/usb_atm.c | 17 -----------------
drivers/usb/serial/keyspan.c | 12 ++++++------
2 files changed, 6 insertions(+), 23 deletions(-)
diff -Nru a/drivers/usb/atm/usb_atm.c b/drivers/usb/atm/usb_atm.c
--- a/drivers/usb/atm/usb_atm.c 2005-01-07 15:39:38 -08:00
+++ b/drivers/usb/atm/usb_atm.c 2005-01-07 15:39:38 -08:00
@@ -83,23 +83,6 @@
#include "usb_atm.h"
-/*
-#define DEBUG
-#define VERBOSE_DEBUG
-*/
-
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-# define DEBUG
-#endif
-
-#include <linux/usb.h>
-
-#ifdef DEBUG
-#define UDSL_ASSERT(x) BUG_ON(!(x))
-#else
-#define UDSL_ASSERT(x) do { if (!(x)) warn("failed assertion '" #x "' at line %d", __LINE__); } while(0)
-#endif
-
#ifdef VERBOSE_DEBUG
static int udsl_print_packet(const unsigned char *data, int len);
#define PACKETDEBUG(arg...) udsl_print_packet (arg)
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c 2005-01-07 15:39:38 -08:00
+++ b/drivers/usb/serial/keyspan.c 2005-01-07 15:39:38 -08:00
@@ -1174,16 +1174,16 @@
char *fw_name;
dbg("Keyspan startup version %04x product %04x",
- serial->dev->descriptor.bcdDevice,
- serial->dev->descriptor.idProduct);
+ le16_to_cpu(serial->dev->descriptor.bcdDevice),
+ le16_to_cpu(serial->dev->descriptor.idProduct));
- if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
+ if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000) != 0x8000) {
dbg("Firmware already loaded. Quitting.");
return(1);
}
/* Select firmware image on the basis of idProduct */
- switch (serial->dev->descriptor.idProduct) {
+ switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
case keyspan_usa28_pre_product_id:
record = &keyspan_usa28_firmware[0];
fw_name = "USA28";
@@ -2248,10 +2248,10 @@
dbg("%s", __FUNCTION__);
for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
- if (d_details->product_id == serial->dev->descriptor.idProduct)
+ if (d_details->product_id == le16_to_cpu(serial->dev->descriptor.idProduct))
break;
if (d_details == NULL) {
- dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, serial->dev->descriptor.idProduct);
+ dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, le16_to_cpu(serial->dev->descriptor.idProduct));
return 1;
}
ChangeSet 1.1938.444.13, 2004/12/20 15:43:59-08:00, [email protected]
USB: convert the idVendor, idProduct, bcdDevice and bcdUSB fields to __le16
These fields are in the struct usb_device_descriptor, and now we keep the
native (on-the-wire mode) format of these fields. Any driver using these
fields needs to convert it to cpu endian before using them.
All USB drivers in the kernel tree have been fixed up to work properly with
this change. All out-of-the USB kernel drivers are on their own...
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/char/watchdog/pcwd_usb.c | 6 --
drivers/isdn/hisax/hfc_usb.c | 7 +--
drivers/isdn/hisax/st5481_init.c | 3 -
drivers/media/dvb/dibusb/dvb-dibusb.c | 12 ++---
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 6 +-
drivers/media/dvb/ttusb-dec/ttusb_dec.c | 8 +--
drivers/net/irda/irda-usb.c | 4 -
drivers/net/irda/stir4200.c | 4 -
drivers/usb/atm/speedtch.c | 11 ++---
drivers/usb/class/audio.c | 3 -
drivers/usb/class/usb-midi.c | 26 ++++++------
drivers/usb/class/usb-midi.h | 4 -
drivers/usb/class/usblp.c | 19 ++++----
drivers/usb/core/devices.c | 10 +++-
drivers/usb/core/hcd.c | 16 +++----
drivers/usb/core/hub.c | 2
drivers/usb/core/message.c | 7 ---
drivers/usb/core/otg_whitelist.h | 16 +++----
drivers/usb/core/sysfs.c | 26 +++++++++---
drivers/usb/core/usb.c | 22 +++++-----
drivers/usb/host/hc_crisv10.c | 8 +--
drivers/usb/image/microtek.c | 4 -
drivers/usb/input/aiptek.c | 6 +-
drivers/usb/input/ati_remote.c | 17 ++-----
drivers/usb/input/hid-core.c | 8 ++-
drivers/usb/input/hid-ff.c | 4 -
drivers/usb/input/hid-input.c | 6 +-
drivers/usb/input/hid-lgff.c | 4 -
drivers/usb/input/hiddev.c | 6 +-
drivers/usb/input/kbtab.c | 6 +-
drivers/usb/input/mtouchusb.c | 6 +-
drivers/usb/input/powermate.c | 13 +++---
drivers/usb/input/touchkitusb.c | 6 +-
drivers/usb/input/usbkbd.c | 6 +-
drivers/usb/input/usbmouse.c | 6 +-
drivers/usb/input/wacom.c | 6 +-
drivers/usb/input/xpad.c | 10 ++--
drivers/usb/media/dabusb.c | 9 ++--
drivers/usb/media/ibmcam.c | 21 ++-------
drivers/usb/media/konicawc.c | 8 +--
drivers/usb/media/ov511.c | 6 +-
drivers/usb/media/se401.c | 22 +++++-----
drivers/usb/media/sn9c102_core.c | 4 -
drivers/usb/media/sn9c102_tas5110c1b.c | 6 +-
drivers/usb/media/sn9c102_tas5130d1b.c | 4 -
drivers/usb/media/stv680.c | 3 -
drivers/usb/media/ultracam.c | 8 ---
drivers/usb/media/vicam.c | 6 --
drivers/usb/media/w9968cf.c | 8 +--
drivers/usb/misc/auerswald.c | 9 +---
drivers/usb/misc/emi26.c | 8 +--
drivers/usb/misc/emi62.c | 6 --
drivers/usb/misc/legousbtower.c | 7 ---
drivers/usb/misc/usblcd.c | 15 ++++---
drivers/usb/misc/usbtest.c | 10 ++--
drivers/usb/misc/uss720.c | 3 -
drivers/usb/net/catc.c | 5 +-
drivers/usb/net/kaweth.c | 8 +--
drivers/usb/serial/belkin_sa.c | 4 -
drivers/usb/serial/io_edgeport.c | 4 -
drivers/usb/serial/io_ti.c | 4 -
drivers/usb/serial/keyspan.c | 12 ++---
drivers/usb/serial/keyspan_pda.c | 6 +-
drivers/usb/serial/kobil_sct.c | 2
drivers/usb/serial/mct_u232.c | 9 ++--
drivers/usb/serial/ti_usb_3410_5052.c | 5 +-
drivers/usb/serial/usb-serial.c | 14 +++---
drivers/usb/serial/usb-serial.h | 4 -
drivers/usb/serial/visor.c | 4 -
drivers/usb/storage/scsiglue.c | 2
drivers/usb/storage/transport.c | 2
drivers/usb/storage/usb.c | 20 +++++----
include/linux/usb_ch9.h | 10 ++--
sound/usb/usbaudio.c | 47 ++++++++++++----------
sound/usb/usbmidi.c | 6 +-
sound/usb/usbmixer.c | 6 +-
sound/usb/usx2y/usX2Yhwdep.c | 4 -
sound/usb/usx2y/usbusx2y.c | 11 ++---
sound/usb/usx2y/usbusx2yaudio.c | 4 -
79 files changed, 343 insertions(+), 347 deletions(-)
diff -Nru a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
--- a/drivers/char/watchdog/pcwd_usb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/char/watchdog/pcwd_usb.c 2005-01-07 15:42:28 -08:00
@@ -571,12 +571,6 @@
char fw_ver_str[20];
unsigned char option_switches, dummy;
- /* See if the device offered us matches what we can accept */
- if ((udev->descriptor.idVendor != USB_PCWD_VENDOR_ID) ||
- (udev->descriptor.idProduct != USB_PCWD_PRODUCT_ID)) {
- return -ENODEV;
- }
-
cards_found++;
if (cards_found > 1) {
printk(KERN_ERR PFX "This driver only supports 1 device\n");
diff -Nru a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
--- a/drivers/isdn/hisax/hfc_usb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/isdn/hisax/hfc_usb.c 2005-01-07 15:42:28 -08:00
@@ -1360,9 +1360,10 @@
// usb_show_device_descriptor(&dev->descriptor);
// usb_show_interface_descriptor(&iface->desc);
vend_idx=0xffff;
- for(i=0;vdata[i].vendor;i++)
- {
- if(dev->descriptor.idVendor==vdata[i].vendor && dev->descriptor.idProduct==vdata[i].prod_id) vend_idx=i;
+ for(i=0;vdata[i].vendor;i++) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == vdata[i].vendor &&
+ le16_to_cpu(dev->descriptor.idProduct) == vdata[i].prod_id)
+ vend_idx = i;
}
diff -Nru a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
--- a/drivers/isdn/hisax/st5481_init.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/isdn/hisax/st5481_init.c 2005-01-07 15:42:28 -08:00
@@ -67,7 +67,8 @@
int retval, i;
printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
- dev->descriptor.idVendor, dev->descriptor.idProduct,
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct),
number_of_leds);
adapter = kmalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
diff -Nru a/drivers/media/dvb/dibusb/dvb-dibusb.c b/drivers/media/dvb/dibusb/dvb-dibusb.c
--- a/drivers/media/dvb/dibusb/dvb-dibusb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/media/dvb/dibusb/dvb-dibusb.c 2005-01-07 15:42:28 -08:00
@@ -602,8 +602,8 @@
if (dib->fe == NULL) {
printk("dvb-dibusb: A frontend driver was not found for device %04x/%04x\n",
- dib->udev->descriptor.idVendor,
- dib->udev->descriptor.idProduct);
+ le16_to_cpu(dib->udev->descriptor.idVendor),
+ le16_to_cpu(dib->udev->descriptor.idProduct));
} else {
if (dvb_register_frontend(dib->adapter, dib->fe)) {
printk("dvb-dibusb: Frontend registration failed!\n");
@@ -917,11 +917,11 @@
int ret = -ENOMEM,i,cold=0;
for (i = 0; i < DIBUSB_SUPPORTED_DEVICES; i++)
- if (dibusb_devices[i].cold_product_id == udev->descriptor.idProduct ||
- dibusb_devices[i].warm_product_id == udev->descriptor.idProduct) {
+ if (dibusb_devices[i].cold_product_id == le16_to_cpu(udev->descriptor.idProduct) ||
+ dibusb_devices[i].warm_product_id == le16_to_cpu(udev->descriptor.idProduct)) {
dibdev = &dibusb_devices[i];
- cold = dibdev->cold_product_id == udev->descriptor.idProduct;
+ cold = dibdev->cold_product_id == le16_to_cpu(udev->descriptor.idProduct);
if (cold)
info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
@@ -931,7 +931,7 @@
if (dibdev == NULL) {
err("something went very wrong, "
- "unknown product ID: %.4x",udev->descriptor.idProduct);
+ "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
return -ENODEV;
}
diff -Nru a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 2005-01-07 15:42:28 -08:00
@@ -1348,7 +1348,7 @@
static void frontend_init(struct ttusb* ttusb)
{
- switch(ttusb->dev->descriptor.idProduct) {
+ switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6(tsa5059)
// try the ALPS BSRU6 first
ttusb->fe = stv0299_attach(&alps_bsru6_config, &ttusb->i2c_adap);
@@ -1381,8 +1381,8 @@
if (ttusb->fe == NULL) {
printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
- ttusb->dev->descriptor.idVendor,
- ttusb->dev->descriptor.idProduct);
+ le16_to_cpu(ttusb->dev->descriptor.idVendor),
+ le16_to_cpu(ttusb->dev->descriptor.idProduct));
} else {
if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) {
printk("dvb-ttusb-budget: Frontend registration failed!\n");
diff -Nru a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2005-01-07 15:42:28 -08:00
@@ -1447,7 +1447,7 @@
memset(dec, 0, sizeof(struct ttusb_dec));
- switch (id->idProduct) {
+ switch (le16_to_cpu(id->idProduct)) {
case 0x1006:
ttusb_dec_set_model(dec, TTUSB_DEC3000S);
break;
@@ -1471,7 +1471,7 @@
ttusb_dec_init_dvb(dec);
dec->adapter->priv = dec;
- switch (id->idProduct) {
+ switch (le16_to_cpu(id->idProduct)) {
case 0x1006:
dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
break;
@@ -1484,8 +1484,8 @@
if (dec->fe == NULL) {
printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n",
- dec->udev->descriptor.idVendor,
- dec->udev->descriptor.idProduct);
+ le16_to_cpu(dec->udev->descriptor.idVendor),
+ le16_to_cpu(dec->udev->descriptor.idProduct));
} else {
if (dvb_register_frontend(dec->adapter, dec->fe)) {
printk("budget-ci: Frontend registration failed!\n");
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/net/irda/irda-usb.c 2005-01-07 15:42:28 -08:00
@@ -1360,8 +1360,8 @@
* Jean II */
MESSAGE("IRDA-USB found at address %d, Vendor: %x, Product: %x\n",
- dev->devnum, dev->descriptor.idVendor,
- dev->descriptor.idProduct);
+ dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
net = alloc_irdadev(sizeof(*self));
if (!net)
diff -Nru a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
--- a/drivers/net/irda/stir4200.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/net/irda/stir4200.c 2005-01-07 15:42:28 -08:00
@@ -1072,8 +1072,8 @@
printk(KERN_INFO "SigmaTel STIr4200 IRDA/USB found at address %d, "
"Vendor: %x, Product: %x\n",
- dev->devnum, dev->descriptor.idVendor,
- dev->descriptor.idProduct);
+ dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
/* Initialize QoS for this device */
irda_init_max_qos_capabilies(&stir->qos);
diff -Nru a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
--- a/drivers/usb/atm/speedtch.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/atm/speedtch.c 2005-01-07 15:42:28 -08:00
@@ -594,7 +594,7 @@
const struct firmware **fw_p)
{
char buf[24];
- const u16 bcdDevice = instance->u.usb_dev->descriptor.bcdDevice;
+ const u16 bcdDevice = le16_to_cpu(instance->u.usb_dev->descriptor.bcdDevice);
const u8 major_revision = bcdDevice >> 8;
const u8 minor_revision = bcdDevice & 0xff;
@@ -737,11 +737,12 @@
int ret, i;
char buf7[SIZE_7];
- dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+ dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d",
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct), ifnum);
- if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
- (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
- (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
+ if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
+ (ifnum != 1))
return -ENODEV;
dbg("speedtch_usb_probe: device accepted");
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/class/audio.c 2005-01-07 15:42:28 -08:00
@@ -2971,7 +2971,8 @@
}
format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8);
/* Dallas DS4201 workaround */
- if (dev->descriptor.idVendor == 0x04fa && dev->descriptor.idProduct == 0x4201)
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x4201)
format = (AFMT_S16_LE | AFMT_S8);
fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i);
if (!fmt) {
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/class/usb-midi.c 2005-01-07 15:42:28 -08:00
@@ -1306,8 +1306,8 @@
return NULL;
}
u->deviceName = NULL;
- u->idVendor = d->descriptor.idVendor;
- u->idProduct = d->descriptor.idProduct;
+ u->idVendor = le16_to_cpu(d->descriptor.idVendor);
+ u->idProduct = le16_to_cpu(d->descriptor.idProduct);
u->interface = ifnum;
u->altSetting = altSetting;
u->in[0].endpoint = -1;
@@ -1661,11 +1661,11 @@
}
/* Failsafe */
if ( !u->deviceName[0] ) {
- if ( d->descriptor.idVendor == USB_VENDOR_ID_ROLAND ) {
+ if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_ROLAND ) {
strcpy(u->deviceName, "Unknown Roland");
- } else if ( d->descriptor.idVendor == USB_VENDOR_ID_STEINBERG ) {
+ } else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_STEINBERG ) {
strcpy(u->deviceName, "Unknown Steinberg");
- } else if ( d->descriptor.idVendor == USB_VENDOR_ID_YAMAHA ) {
+ } else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_YAMAHA ) {
strcpy(u->deviceName, "Unknown Yamaha");
} else {
strcpy(u->deviceName, "Unknown");
@@ -1782,7 +1782,7 @@
int alts=-1;
int ret;
- if (d->descriptor.idVendor != USB_VENDOR_ID_YAMAHA) {
+ if (le16_to_cpu(d->descriptor.idVendor) != USB_VENDOR_ID_YAMAHA) {
return -EINVAL;
}
@@ -1799,7 +1799,8 @@
}
printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n",
- d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
+ le16_to_cpu(d->descriptor.idVendor),
+ le16_to_cpu(d->descriptor.idProduct), ifnum);
i = d->actconfig - d->config;
buffer = d->rawdescriptors[i];
@@ -1833,8 +1834,8 @@
for ( i=0; i<VENDOR_SPECIFIC_USB_MIDI_DEVICES ; i++ ) {
u=&(usb_midi_devices[i]);
- if ( d->descriptor.idVendor != u->idVendor ||
- d->descriptor.idProduct != u->idProduct ||
+ if ( le16_to_cpu(d->descriptor.idVendor) != u->idVendor ||
+ le16_to_cpu(d->descriptor.idProduct) != u->idProduct ||
ifnum != u->interface )
continue;
@@ -1875,7 +1876,8 @@
}
printk(KERN_INFO "usb-midi: Found MIDISTREAMING on dev %04x:%04x, iface %d\n",
- d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
+ le16_to_cpu(d->descriptor.idVendor),
+ le16_to_cpu(d->descriptor.idProduct), ifnum);
/* From USB Spec v2.0, Section 9.5.
@@ -1915,8 +1917,8 @@
{
struct usb_midi_device u;
- if ( d->descriptor.idVendor != uvendor ||
- d->descriptor.idProduct != uproduct ||
+ if ( le16_to_cpu(d->descriptor.idVendor) != uvendor ||
+ le16_to_cpu(d->descriptor.idProduct) != uproduct ||
ifnum != uinterface ) {
return -EINVAL;
}
diff -Nru a/drivers/usb/class/usb-midi.h b/drivers/usb/class/usb-midi.h
--- a/drivers/usb/class/usb-midi.h 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/class/usb-midi.h 2005-01-07 15:42:28 -08:00
@@ -63,8 +63,8 @@
struct usb_midi_device {
char *deviceName;
- int idVendor;
- int idProduct;
+ u16 idVendor;
+ u16 idProduct;
int interface;
int altSetting; /* -1: auto detect */
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/class/usblp.c 2005-01-07 15:42:28 -08:00
@@ -527,7 +527,7 @@
case IOCNR_HP_SET_CHANNEL:
if (_IOC_DIR(cmd) != _IOC_WRITE ||
- usblp->dev->descriptor.idVendor != 0x03F0 ||
+ le16_to_cpu(usblp->dev->descriptor.idVendor) != 0x03F0 ||
usblp->quirks & USBLP_QUIRK_BIDIR) {
retval = -EINVAL;
goto done;
@@ -574,8 +574,8 @@
goto done;
}
- twoints[0] = usblp->dev->descriptor.idVendor;
- twoints[1] = usblp->dev->descriptor.idProduct;
+ twoints[0] = le16_to_cpu(usblp->dev->descriptor.idVendor);
+ twoints[1] = le16_to_cpu(usblp->dev->descriptor.idProduct);
if (copy_to_user((void __user *)arg,
(unsigned char *)twoints,
sizeof(twoints))) {
@@ -910,15 +910,15 @@
/* Lookup quirks for this printer. */
usblp->quirks = usblp_quirks(
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
/* Analyze and pick initial alternate settings and endpoints. */
protocol = usblp_select_alts(usblp);
if (protocol < 0) {
dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
goto abort;
}
@@ -938,8 +938,9 @@
usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
usblp->ifnum,
usblp->protocol[usblp->current_protocol].alt_setting,
- usblp->current_protocol, usblp->dev->descriptor.idVendor,
- usblp->dev->descriptor.idProduct);
+ usblp->current_protocol,
+ le16_to_cpu(usblp->dev->descriptor.idVendor),
+ le16_to_cpu(usblp->dev->descriptor.idProduct));
usb_set_intfdata (intf, usblp);
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/devices.c 2005-01-07 15:42:28 -08:00
@@ -335,10 +335,13 @@
*/
static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc)
{
+ u16 bcdUSB = le16_to_cpu(desc->bcdUSB);
+ u16 bcdDevice = le16_to_cpu(desc->bcdDevice);
+
if (start > end)
return start;
start += sprintf (start, format_device1,
- desc->bcdUSB >> 8, desc->bcdUSB & 0xff,
+ bcdUSB >> 8, bcdUSB & 0xff,
desc->bDeviceClass,
class_decode (desc->bDeviceClass),
desc->bDeviceSubClass,
@@ -348,8 +351,9 @@
if (start > end)
return start;
start += sprintf(start, format_device2,
- desc->idVendor, desc->idProduct,
- desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
+ le16_to_cpu(desc->idVendor),
+ le16_to_cpu(desc->idProduct),
+ bcdDevice >> 8, bcdDevice & 0xff);
return start;
}
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:42:28 -08:00
@@ -120,16 +120,16 @@
static const u8 usb2_rh_dev_descriptor [18] = {
0x12, /* __u8 bLength; */
0x01, /* __u8 bDescriptorType; Device */
- 0x00, 0x02, /* __u16 bcdUSB; v2.0 */
+ 0x00, 0x02, /* __le16 bcdUSB; v2.0 */
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/
0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
- 0x00, 0x00, /* __u16 idVendor; */
- 0x00, 0x00, /* __u16 idProduct; */
- KERNEL_VER, KERNEL_REL, /* __u16 bcdDevice */
+ 0x00, 0x00, /* __le16 idVendor; */
+ 0x00, 0x00, /* __le16 idProduct; */
+ KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */
0x03, /* __u8 iManufacturer; */
0x02, /* __u8 iProduct; */
@@ -143,16 +143,16 @@
static const u8 usb11_rh_dev_descriptor [18] = {
0x12, /* __u8 bLength; */
0x01, /* __u8 bDescriptorType; Device */
- 0x10, 0x01, /* __u16 bcdUSB; v1.1 */
+ 0x10, 0x01, /* __le16 bcdUSB; v1.1 */
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */
0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
- 0x00, 0x00, /* __u16 idVendor; */
- 0x00, 0x00, /* __u16 idProduct; */
- KERNEL_VER, KERNEL_REL, /* __u16 bcdDevice */
+ 0x00, 0x00, /* __le16 idVendor; */
+ 0x00, 0x00, /* __le16 idProduct; */
+ KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */
0x03, /* __u8 iManufacturer; */
0x02, /* __u8 iProduct; */
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:42:28 -08:00
@@ -2494,7 +2494,7 @@
}
/* check for devices running slower than they could */
- if (udev->descriptor.bcdUSB >= 0x0200
+ if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
&& udev->speed == USB_SPEED_FULL
&& highspeed_hubs != 0)
check_highspeed (hub, udev, port1);
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/message.c 2005-01-07 15:42:28 -08:00
@@ -796,13 +796,8 @@
return -ENOMEM;
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
- if (ret >= 0) {
- le16_to_cpus(&desc->bcdUSB);
- le16_to_cpus(&desc->idVendor);
- le16_to_cpus(&desc->idProduct);
- le16_to_cpus(&desc->bcdDevice);
+ if (ret >= 0)
memcpy(&dev->descriptor, desc, size);
- }
kfree(desc);
return ret;
}
diff -Nru a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
--- a/drivers/usb/core/otg_whitelist.h 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/otg_whitelist.h 2005-01-07 15:42:28 -08:00
@@ -55,8 +55,8 @@
return 1;
/* HNP test device is _never_ targeted (see OTG spec 6.6.6) */
- if (dev->descriptor.idVendor == 0x1a0a
- && dev->descriptor.idProduct == 0xbadd)
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
return 0;
/* NOTE: can't use usb_match_id() since interface caches
@@ -64,21 +64,21 @@
*/
for (id = whitelist_table; id->match_flags; id++) {
if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
- id->idVendor != dev->descriptor.idVendor)
+ id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
- id->idProduct != dev->descriptor.idProduct)
+ id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
continue;
/* No need to test id->bcdDevice_lo != 0, since 0 is never
greater than any unsigned number. */
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
- (id->bcdDevice_lo > dev->descriptor.bcdDevice))
+ (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
- (id->bcdDevice_hi < dev->descriptor.bcdDevice))
+ (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
@@ -101,8 +101,8 @@
/* OTG MESSAGE: report errors here, customize to match your product */
dev_err(&dev->dev, "device v%04x p%04x is not supported\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
#ifdef CONFIG_USB_OTG_WHITELIST
return 0;
#else
diff -Nru a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
--- a/drivers/usb/core/sysfs.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/sysfs.c 2005-01-07 15:42:28 -08:00
@@ -149,10 +149,11 @@
show_version (struct device *dev, char *buf)
{
struct usb_device *udev;
+ u16 bcdUSB;
- udev = to_usb_device (dev);
- return sprintf (buf, "%2x.%02x\n", udev->descriptor.bcdUSB >> 8,
- udev->descriptor.bcdUSB & 0xff);
+ udev = to_usb_device(dev);
+ bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB);
+ return sprintf(buf, "%2x.%02x\n", bcdUSB >> 8, bcdUSB & 0xff);
}
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
@@ -167,6 +168,22 @@
static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
/* Descriptor fields */
+#define usb_descriptor_attr_le16(field, format_string) \
+static ssize_t \
+show_##field (struct device *dev, char *buf) \
+{ \
+ struct usb_device *udev; \
+ \
+ udev = to_usb_device (dev); \
+ return sprintf (buf, format_string, \
+ le16_to_cpu(udev->descriptor.field)); \
+} \
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_descriptor_attr_le16(idVendor, "%04x\n")
+usb_descriptor_attr_le16(idProduct, "%04x\n")
+usb_descriptor_attr_le16(bcdDevice, "%04x\n")
+
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
show_##field (struct device *dev, char *buf) \
@@ -178,9 +195,6 @@
} \
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")
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/core/usb.c 2005-01-07 15:42:28 -08:00
@@ -423,21 +423,21 @@
id->driver_info; id++) {
if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
- id->idVendor != dev->descriptor.idVendor)
+ id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
- id->idProduct != dev->descriptor.idProduct)
+ id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
continue;
/* No need to test id->bcdDevice_lo != 0, since 0 is never
greater than any unsigned number. */
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
- (id->bcdDevice_lo > dev->descriptor.bcdDevice))
+ (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
- (id->bcdDevice_hi < dev->descriptor.bcdDevice))
+ (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
@@ -588,9 +588,9 @@
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PRODUCT=%x/%x/%x",
- usb_dev->descriptor.idVendor,
- usb_dev->descriptor.idProduct,
- usb_dev->descriptor.bcdDevice))
+ le16_to_cpu(usb_dev->descriptor.idVendor),
+ le16_to_cpu(usb_dev->descriptor.idProduct),
+ le16_to_cpu(usb_dev->descriptor.bcdDevice)))
return -ENOMEM;
/* class-based driver binding models */
@@ -959,12 +959,12 @@
int child;
dev_dbg(&dev->dev, "check for vendor %04x, product %04x ...\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
/* see if this device matches */
- if ((dev->descriptor.idVendor == vendor_id) &&
- (dev->descriptor.idProduct == product_id)) {
+ if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) &&
+ (product_id == le16_to_cpu(dev->descriptor.idProduct))) {
dev_dbg (&dev->dev, "matched this device!\n");
ret_dev = usb_get_dev(dev);
goto exit;
diff -Nru a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
--- a/drivers/usb/host/hc_crisv10.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/host/hc_crisv10.c 2005-01-07 15:42:28 -08:00
@@ -113,17 +113,17 @@
{
0x12, /* __u8 bLength; */
0x01, /* __u8 bDescriptorType; Device */
- 0x00, /* __u16 bcdUSB; v1.0 */
+ 0x00, /* __le16 bcdUSB; v1.0 */
0x01,
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x00, /* __u8 bDeviceProtocol; */
0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
- 0x00, /* __u16 idVendor; */
+ 0x00, /* __le16 idVendor; */
0x00,
- 0x00, /* __u16 idProduct; */
+ 0x00, /* __le16 idProduct; */
0x00,
- 0x00, /* __u16 bcdDevice; */
+ 0x00, /* __le16 bcdDevice; */
0x00,
0x00, /* __u8 iManufacturer; */
0x02, /* __u8 iProduct; */
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/image/microtek.c 2005-01-07 15:42:28 -08:00
@@ -715,8 +715,8 @@
MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
- (int)dev->descriptor.idProduct,
- (int)dev->descriptor.idVendor );
+ le16_to_cpu(dev->descriptor.idProduct),
+ le16_to_cpu(dev->descriptor.idVendor) );
MTS_DEBUG_GOT_HERE();
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/aiptek.c 2005-01-07 15:42:28 -08:00
@@ -2137,9 +2137,9 @@
aiptek->inputdev.name = "Aiptek";
aiptek->inputdev.phys = aiptek->features.usbPath;
aiptek->inputdev.id.bustype = BUS_USB;
- aiptek->inputdev.id.vendor = usbdev->descriptor.idVendor;
- aiptek->inputdev.id.product = usbdev->descriptor.idProduct;
- aiptek->inputdev.id.version = usbdev->descriptor.bcdDevice;
+ aiptek->inputdev.id.vendor = le16_to_cpu(usbdev->descriptor.idVendor);
+ aiptek->inputdev.id.product = le16_to_cpu(usbdev->descriptor.idProduct);
+ aiptek->inputdev.id.version = le16_to_cpu(usbdev->descriptor.bcdDevice);
aiptek->usbdev = usbdev;
aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
diff -Nru a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
--- a/drivers/usb/input/ati_remote.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/ati_remote.c 2005-01-07 15:42:28 -08:00
@@ -672,9 +672,9 @@
idev->phys = ati_remote->phys;
idev->id.bustype = BUS_USB;
- idev->id.vendor = ati_remote->udev->descriptor.idVendor;
- idev->id.product = ati_remote->udev->descriptor.idProduct;
- idev->id.version = ati_remote->udev->descriptor.bcdDevice;
+ idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor);
+ idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct);
+ idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice);
}
static int ati_remote_initialize(struct ati_remote *ati_remote)
@@ -729,13 +729,6 @@
char path[64];
char *buf = NULL;
- /* See if the offered device matches what we can accept */
- if ((udev->descriptor.idVendor != ATI_REMOTE_VENDOR_ID) ||
- ( (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID) &&
- (udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) &&
- (udev->descriptor.idProduct != MEDION_REMOTE_PRODUCT_ID) ))
- return -ENODEV;
-
/* Allocate and clear an ati_remote struct */
if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
return -ENOMEM;
@@ -803,8 +796,8 @@
if (!strlen(ati_remote->name))
sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
- ati_remote->udev->descriptor.idVendor,
- ati_remote->udev->descriptor.idProduct);
+ le16_to_cpu(ati_remote->udev->descriptor.idVendor),
+ le16_to_cpu(ati_remote->udev->descriptor.idProduct));
/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
retval = ati_remote_initialize(ati_remote);
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/hid-core.c 2005-01-07 15:42:28 -08:00
@@ -1599,8 +1599,8 @@
int n;
for (n = 0; hid_blacklist[n].idVendor; n++)
- if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) &&
- (hid_blacklist[n].idProduct == dev->descriptor.idProduct))
+ if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
+ (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct)))
quirks = hid_blacklist[n].quirks;
if (quirks & HID_QUIRK_IGNORE)
@@ -1724,7 +1724,9 @@
} else if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0) {
snprintf(hid->name, 128, "%s", buf);
} else
- snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
+ snprintf(hid->name, 128, "%04x:%04x",
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
usb_make_path(dev, buf, 64);
snprintf(hid->phys, 64, "%s/input%d", buf,
diff -Nru a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
--- a/drivers/usb/input/hid-ff.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/hid-ff.c 2005-01-07 15:42:28 -08:00
@@ -82,8 +82,8 @@
{
struct hid_ff_initializer *init;
- init = hid_get_ff_init(hid->dev->descriptor.idVendor,
- hid->dev->descriptor.idProduct);
+ init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
+ le16_to_cpu(hid->dev->descriptor.idProduct));
if (!init) {
dbg("hid_ff_init could not find initializer");
diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/hid-input.c 2005-01-07 15:42:28 -08:00
@@ -593,9 +593,9 @@
hidinput->input.phys = hid->phys;
hidinput->input.uniq = hid->uniq;
hidinput->input.id.bustype = BUS_USB;
- hidinput->input.id.vendor = dev->descriptor.idVendor;
- hidinput->input.id.product = dev->descriptor.idProduct;
- hidinput->input.id.version = dev->descriptor.bcdDevice;
+ hidinput->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
hidinput->input.dev = &hid->intf->dev;
}
diff -Nru a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
--- a/drivers/usb/input/hid-lgff.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/hid-lgff.c 2005-01-07 15:42:28 -08:00
@@ -251,8 +251,8 @@
{
struct device_type* dev = devices;
signed short* ff;
- u16 idVendor = hid->dev->descriptor.idVendor;
- u16 idProduct = hid->dev->descriptor.idProduct;
+ u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
+ u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/hiddev.c 2005-01-07 15:42:28 -08:00
@@ -423,9 +423,9 @@
dinfo.busnum = dev->bus->busnum;
dinfo.devnum = dev->devnum;
dinfo.ifnum = hid->ifnum;
- dinfo.vendor = dev->descriptor.idVendor;
- dinfo.product = dev->descriptor.idProduct;
- dinfo.version = dev->descriptor.bcdDevice;
+ dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
+ dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
dinfo.num_applications = hid->maxapplication;
if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
return -EFAULT;
diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
--- a/drivers/usb/input/kbtab.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/kbtab.c 2005-01-07 15:42:28 -08:00
@@ -175,9 +175,9 @@
kbtab->dev.name = "KB Gear Tablet";
kbtab->dev.phys = kbtab->phys;
kbtab->dev.id.bustype = BUS_USB;
- kbtab->dev.id.vendor = dev->descriptor.idVendor;
- kbtab->dev.id.product = dev->descriptor.idProduct;
- kbtab->dev.id.version = dev->descriptor.bcdDevice;
+ kbtab->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ kbtab->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ kbtab->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
kbtab->dev.dev = &intf->dev;
kbtab->usbdev = dev;
diff -Nru a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
--- a/drivers/usb/input/mtouchusb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/mtouchusb.c 2005-01-07 15:42:28 -08:00
@@ -223,9 +223,9 @@
mtouch->input.name = mtouch->name;
mtouch->input.phys = mtouch->phys;
mtouch->input.id.bustype = BUS_USB;
- mtouch->input.id.vendor = udev->descriptor.idVendor;
- mtouch->input.id.product = udev->descriptor.idProduct;
- mtouch->input.id.version = udev->descriptor.bcdDevice;
+ mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+ mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
+ mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
mtouch->input.dev = &intf->dev;
mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/powermate.c 2005-01-07 15:42:28 -08:00
@@ -375,12 +375,13 @@
return -EIO; /* failure */
}
- switch (udev->descriptor.idProduct) {
+ switch (le16_to_cpu(udev->descriptor.idProduct)) {
case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
default:
- pm->input.name = pm_name_soundknob;
- printk(KERN_WARNING "powermate: unknown product id %04x\n", udev->descriptor.idProduct);
+ pm->input.name = pm_name_soundknob;
+ printk(KERN_WARNING "powermate: unknown product id %04x\n",
+ le16_to_cpu(udev->descriptor.idProduct));
}
pm->input.private = pm;
@@ -389,9 +390,9 @@
pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
pm->input.id.bustype = BUS_USB;
- pm->input.id.vendor = udev->descriptor.idVendor;
- pm->input.id.product = udev->descriptor.idProduct;
- pm->input.id.version = udev->descriptor.bcdDevice;
+ pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+ pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
+ pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
pm->input.event = powermate_input_event;
pm->input.dev = &intf->dev;
diff -Nru a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
--- a/drivers/usb/input/touchkitusb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/touchkitusb.c 2005-01-07 15:42:28 -08:00
@@ -211,9 +211,9 @@
touchkit->input.name = touchkit->name;
touchkit->input.phys = touchkit->phys;
touchkit->input.id.bustype = BUS_USB;
- touchkit->input.id.vendor = udev->descriptor.idVendor;
- touchkit->input.id.product = udev->descriptor.idProduct;
- touchkit->input.id.version = udev->descriptor.bcdDevice;
+ touchkit->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+ touchkit->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
+ touchkit->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
touchkit->input.dev = &intf->dev;
touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/usbkbd.c 2005-01-07 15:42:28 -08:00
@@ -296,9 +296,9 @@
kbd->dev.name = kbd->name;
kbd->dev.phys = kbd->phys;
kbd->dev.id.bustype = BUS_USB;
- kbd->dev.id.vendor = dev->descriptor.idVendor;
- kbd->dev.id.product = dev->descriptor.idProduct;
- kbd->dev.id.version = dev->descriptor.bcdDevice;
+ kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ kbd->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
kbd->dev.dev = &iface->dev;
if (!(buf = kmalloc(63, GFP_KERNEL))) {
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/usbmouse.c 2005-01-07 15:42:28 -08:00
@@ -180,9 +180,9 @@
mouse->dev.name = mouse->name;
mouse->dev.phys = mouse->phys;
mouse->dev.id.bustype = BUS_USB;
- mouse->dev.id.vendor = dev->descriptor.idVendor;
- mouse->dev.id.product = dev->descriptor.idProduct;
- mouse->dev.id.version = dev->descriptor.bcdDevice;
+ mouse->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ mouse->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ mouse->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
mouse->dev.dev = &intf->dev;
if (!(buf = kmalloc(63, GFP_KERNEL))) {
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/wacom.c 2005-01-07 15:42:28 -08:00
@@ -692,9 +692,9 @@
wacom->dev.name = wacom->features->name;
wacom->dev.phys = wacom->phys;
wacom->dev.id.bustype = BUS_USB;
- wacom->dev.id.vendor = dev->descriptor.idVendor;
- wacom->dev.id.product = dev->descriptor.idProduct;
- wacom->dev.id.version = dev->descriptor.bcdDevice;
+ wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
wacom->dev.dev = &intf->dev;
wacom->usbdev = dev;
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/input/xpad.c 2005-01-07 15:42:28 -08:00
@@ -226,8 +226,8 @@
int i;
for (i = 0; xpad_device[i].idVendor; i++) {
- if ((udev->descriptor.idVendor == xpad_device[i].idVendor) &&
- (udev->descriptor.idProduct == xpad_device[i].idProduct))
+ if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
+ (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
break;
}
@@ -264,9 +264,9 @@
xpad->udev = udev;
xpad->dev.id.bustype = BUS_USB;
- xpad->dev.id.vendor = udev->descriptor.idVendor;
- xpad->dev.id.product = udev->descriptor.idProduct;
- xpad->dev.id.version = udev->descriptor.bcdDevice;
+ xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+ xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct);
+ xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
xpad->dev.dev = &intf->dev;
xpad->dev.private = xpad;
xpad->dev.name = xpad_device[i].name;
diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/dabusb.c 2005-01-07 15:42:28 -08:00
@@ -724,13 +724,16 @@
pdabusb_t s;
dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
- usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, intf->altsetting->desc.bInterfaceNumber);
+ le16_to_cpu(usbdev->descriptor.idVendor),
+ le16_to_cpu(usbdev->descriptor.idProduct),
+ intf->altsetting->desc.bInterfaceNumber);
/* We don't handle multiple configurations */
if (usbdev->descriptor.bNumConfigurations != 1)
return -ENODEV;
- if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
+ if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
+ le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
return -ENODEV;
@@ -746,7 +749,7 @@
err("reset_configuration failed");
goto reject;
}
- if (usbdev->descriptor.idProduct == 0x2131) {
+ if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
dabusb_loadmem (s, NULL);
goto reject;
}
diff -Nru a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
--- a/drivers/usb/media/ibmcam.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/ibmcam.c 2005-01-07 15:42:28 -08:00
@@ -3659,17 +3659,8 @@
if (dev->descriptor.bNumConfigurations != 1)
return -ENODEV;
- /* Is it an IBM camera? */
- if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
- return -ENODEV;
- if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
- (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
- (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
- (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
- return -ENODEV;
-
/* Check the version/revision */
- switch (dev->descriptor.bcdDevice) {
+ switch (le16_to_cpu(dev->descriptor.bcdDevice)) {
case 0x0002:
if (ifnum != 2)
return -ENODEV;
@@ -3678,8 +3669,8 @@
case 0x030A:
if (ifnum != 0)
return -ENODEV;
- if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
- (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
+ if ((le16_to_cpu(dev->descriptor.idProduct) == NETCAM_PRODUCT_ID) ||
+ (le16_to_cpu(dev->descriptor.idProduct) == VEO_800D_PRODUCT_ID))
model = IBMCAM_MODEL_4;
else
model = IBMCAM_MODEL_2;
@@ -3691,14 +3682,14 @@
break;
default:
err("IBM camera with revision 0x%04x is not supported.",
- dev->descriptor.bcdDevice);
+ le16_to_cpu(dev->descriptor.bcdDevice));
return -ENODEV;
}
/* Print detailed info on what we found so far */
do {
char *brand = NULL;
- switch (dev->descriptor.idProduct) {
+ switch (le16_to_cpu(dev->descriptor.idProduct)) {
case NETCAM_PRODUCT_ID:
brand = "IBM NetCamera";
break;
@@ -3714,7 +3705,7 @@
break;
}
info("%s USB camera found (model %d, rev. 0x%04x)",
- brand, model, dev->descriptor.bcdDevice);
+ brand, model, le16_to_cpu(dev->descriptor.bcdDevice));
} while (0);
/* Validate found interface: must have one ISO endpoint */
diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/konicawc.c 2005-01-07 15:42:28 -08:00
@@ -732,7 +732,7 @@
if (dev->descriptor.bNumConfigurations != 1)
return -ENODEV;
- info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice);
+ info("Konica Webcam (rev. 0x%04x)", le16_to_cpu(dev->descriptor.bcdDevice));
RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
/* Validate found interface: must have one ISO endpoint */
@@ -846,9 +846,9 @@
cam->input.evbit[0] = BIT(EV_KEY);
cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
cam->input.id.bustype = BUS_USB;
- cam->input.id.vendor = dev->descriptor.idVendor;
- cam->input.id.product = dev->descriptor.idProduct;
- cam->input.id.version = dev->descriptor.bcdDevice;
+ cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
input_register_device(&cam->input);
usb_make_path(dev, cam->input_physname, 56);
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/ov511.c 2005-01-07 15:42:28 -08:00
@@ -5825,7 +5825,7 @@
ov->auto_gain = autogain;
ov->auto_exp = autoexp;
- switch (dev->descriptor.idProduct) {
+ switch (le16_to_cpu(dev->descriptor.idProduct)) {
case PROD_OV511:
ov->bridge = BRG_OV511;
ov->bclass = BCL_OV511;
@@ -5843,13 +5843,13 @@
ov->bclass = BCL_OV518;
break;
case PROD_ME2CAM:
- if (dev->descriptor.idVendor != VEND_MATTEL)
+ if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL)
goto error;
ov->bridge = BRG_OV511PLUS;
ov->bclass = BCL_OV511;
break;
default:
- err("Unknown product ID 0x%04x", dev->descriptor.idProduct);
+ err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct));
goto error;
}
diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
--- a/drivers/usb/media/se401.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/se401.c 2005-01-07 15:42:28 -08:00
@@ -1315,20 +1315,20 @@
interface = &intf->cur_altsetting->desc;
/* Is it an se401? */
- if (dev->descriptor.idVendor == 0x03e8 &&
- dev->descriptor.idProduct == 0x0004) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
camera_name="Endpoints/Aox SE401";
- } else if (dev->descriptor.idVendor == 0x0471 &&
- dev->descriptor.idProduct == 0x030b) {
+ } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
camera_name="Philips PCVC665K";
- } else if (dev->descriptor.idVendor == 0x047d &&
- dev->descriptor.idProduct == 0x5001) {
+ } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
camera_name="Kensington VideoCAM 67014";
- } else if (dev->descriptor.idVendor == 0x047d &&
- dev->descriptor.idProduct == 0x5002) {
+ } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
camera_name="Kensington VideoCAM 6701(5/7)";
- } else if (dev->descriptor.idVendor == 0x047d &&
- dev->descriptor.idProduct == 0x5003) {
+ } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
camera_name="Kensington VideoCAM 67016";
button=0;
} else
@@ -1354,7 +1354,7 @@
se401->iface = interface->bInterfaceNumber;
se401->camera_name = camera_name;
- info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
+ info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255);
if (se401_init(se401, button)) {
kfree(se401);
diff -Nru a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
--- a/drivers/usb/media/sn9c102_core.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/sn9c102_core.c 2005-01-07 15:42:28 -08:00
@@ -2496,8 +2496,8 @@
n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
for (i = 0; i < n-1; i++)
- if (udev->descriptor.idVendor==sn9c102_id_table[i].idVendor &&
- udev->descriptor.idProduct==sn9c102_id_table[i].idProduct)
+ if (le16_to_cpu(udev->descriptor.idVendor) == sn9c102_id_table[i].idVendor &&
+ le16_to_cpu(udev->descriptor.idProduct) == sn9c102_id_table[i].idProduct)
break;
if (i == n-1)
return -ENODEV;
diff -Nru a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
--- a/drivers/usb/media/sn9c102_tas5110c1b.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c 2005-01-07 15:42:28 -08:00
@@ -165,9 +165,9 @@
sn9c102_attach_sensor(cam, &tas5110c1b);
/* Sensor detection is based on USB pid/vid */
- if (tas5110c1b.usbdev->descriptor.idProduct != 0x6001 &&
- tas5110c1b.usbdev->descriptor.idProduct != 0x6005 &&
- tas5110c1b.usbdev->descriptor.idProduct != 0x60ab)
+ if (le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6001 &&
+ le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6005 &&
+ le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x60ab)
return -ENODEV;
return 0;
diff -Nru a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
--- a/drivers/usb/media/sn9c102_tas5130d1b.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c 2005-01-07 15:42:28 -08:00
@@ -180,8 +180,8 @@
sn9c102_attach_sensor(cam, &tas5130d1b);
/* Sensor detection is based on USB pid/vid */
- if (tas5130d1b.usbdev->descriptor.idProduct != 0x6025 &&
- tas5130d1b.usbdev->descriptor.idProduct != 0x60aa)
+ if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6025 &&
+ le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x60aa)
return -ENODEV;
return 0;
diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
--- a/drivers/usb/media/stv680.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/stv680.c 2005-01-07 15:42:28 -08:00
@@ -1371,7 +1371,8 @@
interface = &intf->altsetting[0];
/* Is it a STV680? */
- if ((dev->descriptor.idVendor == USB_PENCAM_VENDOR_ID) && (dev->descriptor.idProduct == USB_PENCAM_PRODUCT_ID)) {
+ if ((le16_to_cpu(dev->descriptor.idVendor) == USB_PENCAM_VENDOR_ID) &&
+ (le16_to_cpu(dev->descriptor.idProduct) == USB_PENCAM_PRODUCT_ID)) {
camera_name = "STV0680";
PDEBUG (0, "STV(i): STV0680 camera found.");
} else {
diff -Nru a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c
--- a/drivers/usb/media/ultracam.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/ultracam.c 2005-01-07 15:42:28 -08:00
@@ -524,12 +524,8 @@
if (dev->descriptor.bNumConfigurations != 1)
return -ENODEV;
- /* Is it an IBM camera? */
- if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) ||
- (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID))
- return -ENODEV;
-
- info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice);
+ info("IBM Ultra camera found (rev. 0x%04x)",
+ le16_to_cpu(dev->descriptor.bcdDevice));
/* Validate found interface: must have one ISO endpoint */
nas = intf->num_altsetting;
diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
--- a/drivers/usb/media/vicam.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/vicam.c 2005-01-07 15:42:28 -08:00
@@ -1281,12 +1281,6 @@
const struct usb_endpoint_descriptor *endpoint;
struct vicam_camera *cam;
- /* See if the device offered us matches what we can accept */
- if ((dev->descriptor.idVendor != USB_VICAM_VENDOR_ID) ||
- (dev->descriptor.idProduct != USB_VICAM_PRODUCT_ID)) {
- return -ENODEV;
- }
-
printk(KERN_INFO "ViCam based webcam connected\n");
interface = intf->cur_altsetting;
diff -Nru a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
--- a/drivers/usb/media/w9968cf.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/media/w9968cf.c 2005-01-07 15:42:28 -08:00
@@ -3516,11 +3516,11 @@
u8 sc = 0; /* number of simultaneous cameras */
static unsigned short dev_nr = 0; /* we are handling device number n */
- if (udev->descriptor.idVendor == winbond_id_table[0].idVendor &&
- udev->descriptor.idProduct == winbond_id_table[0].idProduct)
+ if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
+ le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
- else if (udev->descriptor.idVendor == winbond_id_table[1].idVendor &&
- udev->descriptor.idProduct == winbond_id_table[1].idProduct)
+ else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
+ le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
else
return -ENODEV;
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/auerswald.c 2005-01-07 15:42:28 -08:00
@@ -1931,11 +1931,8 @@
int ret;
dbg ("probe: vendor id 0x%x, device id 0x%x",
- usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
-
- /* See if the device offered us matches that we can accept */
- if (usbdev->descriptor.idVendor != ID_AUERSWALD)
- return -ENODEV;
+ le16_to_cpu(usbdev->descriptor.idVendor),
+ le16_to_cpu(usbdev->descriptor.idProduct));
/* we use only the first -and only- interface */
if (intf->altsetting->desc.bInterfaceNumber != 0)
@@ -1969,7 +1966,7 @@
cp->dtindex = intf->minor;
/* Get the usb version of the device */
- cp->version = cp->usbdev->descriptor.bcdDevice;
+ cp->version = le16_to_cpu(cp->usbdev->descriptor.bcdDevice);
dbg ("Version is %X", cp->version);
/* allow some time to settle the device */
diff -Nru a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
--- a/drivers/usb/misc/emi26.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/emi26.c 2005-01-07 15:42:28 -08:00
@@ -213,11 +213,9 @@
struct usb_device *dev = interface_to_usbdev(intf);
info("%s start", __FUNCTION__);
-
- if((dev->descriptor.idVendor == EMI26_VENDOR_ID) && (dev->descriptor.idProduct == EMI26_PRODUCT_ID)) {
- emi26_load_firmware(dev);
- }
-
+
+ emi26_load_firmware(dev);
+
/* do not return the driver context, let real audio driver do that */
return -EIO;
}
diff -Nru a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
--- a/drivers/usb/misc/emi62.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/emi62.c 2005-01-07 15:42:28 -08:00
@@ -255,10 +255,8 @@
info("%s start", __FUNCTION__);
- if((dev->descriptor.idVendor == EMI62_VENDOR_ID) && (dev->descriptor.idProduct == EMI62_PRODUCT_ID)) {
- emi62_load_firmware(dev);
- }
-
+ emi62_load_firmware(dev);
+
/* do not return the driver context, let real audio driver do that */
return -EIO;
}
diff -Nru a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
--- a/drivers/usb/misc/legousbtower.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/legousbtower.c 2005-01-07 15:42:28 -08:00
@@ -859,13 +859,6 @@
info ("udev is NULL.");
}
- /* See if the device offered us matches what we can accept */
- if ((udev->descriptor.idVendor != LEGO_USB_TOWER_VENDOR_ID) ||
- (udev->descriptor.idProduct != LEGO_USB_TOWER_PRODUCT_ID)) {
- return -ENODEV;
- }
-
-
/* allocate memory for our device state and intialize it */
dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
diff -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
--- a/drivers/usb/misc/usblcd.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/usblcd.c 2005-01-07 15:42:28 -08:00
@@ -74,7 +74,7 @@
unsigned long arg)
{
struct lcd_usb_data *lcd = &lcd_instance;
- int i;
+ u16 bcdDevice;
char buf[30];
/* Sanity check to make sure lcd is connected, powered, etc */
@@ -85,9 +85,12 @@
switch (cmd) {
case IOCTL_GET_HARD_VERSION:
- i = (lcd->lcd_dev)->descriptor.bcdDevice;
- sprintf(buf,"%1d%1d.%1d%1d",(i & 0xF000)>>12,(i & 0xF00)>>8,
- (i & 0xF0)>>4,(i & 0xF));
+ bcdDevice = le16_to_cpu((lcd->lcd_dev)->descriptor.bcdDevice);
+ sprintf(buf,"%1d%1d.%1d%1d",
+ (bcdDevice & 0xF000)>>12,
+ (bcdDevice & 0xF00)>>8,
+ (bcdDevice & 0xF0)>>4,
+ (bcdDevice & 0xF));
if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
return -EFAULT;
break;
@@ -258,7 +261,7 @@
int i;
int retval;
- if (dev->descriptor.idProduct != 0x0001 ) {
+ if (le16_to_cpu(dev->descriptor.idProduct) != 0x0001) {
warn(KERN_INFO "USBLCD model not supported.");
return -ENODEV;
}
@@ -268,7 +271,7 @@
return -ENODEV;
}
- i = dev->descriptor.bcdDevice;
+ i = le16_to_cpu(dev->descriptor.bcdDevice);
info("USBLCD Version %1d%1d.%1d%1d found at address %d",
(i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF),
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/usbtest.c 2005-01-07 15:42:28 -08:00
@@ -636,7 +636,7 @@
}
/* and sometimes [9.2.6.6] speed dependent descriptors */
- if (udev->descriptor.bcdUSB == 0x0200) { /* pre-swapped */
+ if (le16_to_cpu(udev->descriptor.bcdUSB) == 0x0200) {
struct usb_qualifier_descriptor *d = NULL;
/* device qualifier [9.6.2] */
@@ -1842,13 +1842,13 @@
/* specify devices by module parameters? */
if (id->match_flags == 0) {
/* vendor match required, product match optional */
- if (!vendor || udev->descriptor.idVendor != (u16)vendor)
+ if (!vendor || le16_to_cpu(udev->descriptor.idVendor) != (u16)vendor)
return -ENODEV;
- if (product && udev->descriptor.idProduct != (u16)product)
+ if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product)
return -ENODEV;
dbg ("matched module params, vend=0x%04x prod=0x%04x",
- udev->descriptor.idVendor,
- udev->descriptor.idProduct);
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
}
#endif
diff -Nru a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
--- a/drivers/usb/misc/uss720.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/misc/uss720.c 2005-01-07 15:42:28 -08:00
@@ -544,7 +544,8 @@
int i;
printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n",
- usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
+ le16_to_cpu(usbdev->descriptor.idVendor),
+ le16_to_cpu(usbdev->descriptor.idProduct));
/* our known interfaces have 3 alternate settings */
if (intf->num_altsetting != 3)
diff -Nru a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
--- a/drivers/usb/net/catc.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/net/catc.c 2005-01-07 15:42:28 -08:00
@@ -800,8 +800,9 @@
}
/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
- if (usbdev->descriptor.idVendor == 0x0423 && usbdev->descriptor.idProduct == 0xa &&
- catc->usbdev->descriptor.bcdDevice == 0x0130 ) {
+ if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 &&
+ le16_to_cpu(usbdev->descriptor.idProduct) == 0xa &&
+ le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) {
dbg("Testing for f5u011");
catc->is_f5u011 = 1;
atomic_set(&catc->recq_sz, 0);
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/net/kaweth.c 2005-01-07 15:42:28 -08:00
@@ -903,9 +903,9 @@
kaweth_dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x",
dev->devnum,
- (int)dev->descriptor.idVendor,
- (int)dev->descriptor.idProduct,
- (int)dev->descriptor.bcdDevice);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct),
+ le16_to_cpu(dev->descriptor.bcdDevice));
kaweth_dbg("Device at %p", dev);
@@ -933,7 +933,7 @@
* downloaded. Don't try to do it again, or we'll hang the device.
*/
- if (dev->descriptor.bcdDevice >> 8) {
+ if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
kaweth_info("Firmware present in device.");
} else {
/* Download the firmware */
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
--- a/drivers/usb/serial/belkin_sa.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/belkin_sa.c 2005-01-07 15:42:28 -08:00
@@ -181,8 +181,8 @@
priv->last_lsr = 0;
priv->last_msr = 0;
/* see comments at top of file */
- priv->bad_flow_control = (dev->descriptor.bcdDevice <= 0x0206) ? 1 : 0;
- info("bcdDevice: %04x, bfc: %d", dev->descriptor.bcdDevice, priv->bad_flow_control);
+ priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
+ info("bcdDevice: %04x, bfc: %d", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control);
init_waitqueue_head(&serial->port[0]->write_wait);
usb_set_serial_port_data(serial->port[0], priv);
diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
--- a/drivers/usb/serial/io_edgeport.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/io_edgeport.c 2005-01-07 15:42:28 -08:00
@@ -659,7 +659,7 @@
memset (product_info, 0, sizeof(struct edgeport_product_info));
- product_info->ProductId = (__u16)(edge_serial->serial->dev->descriptor.idProduct & ~ION_DEVICE_ID_80251_NETCHIP);
+ product_info->ProductId = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);
product_info->NumPorts = edge_serial->manuf_descriptor.NumPorts;
product_info->ProdInfoVer = 0;
@@ -675,7 +675,7 @@
memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate));
// check if this is 2nd generation hardware
- if (edge_serial->serial->dev->descriptor.idProduct & ION_DEVICE_ID_80251_NETCHIP) {
+ if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) {
product_info->FirmwareMajorVersion = OperationalCodeImageVersion_GEN2.MajorVersion;
product_info->FirmwareMinorVersion = OperationalCodeImageVersion_GEN2.MinorVersion;
product_info->FirmwareBuildNumber = cpu_to_le16(OperationalCodeImageVersion_GEN2.BuildNumber);
diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
--- a/drivers/usb/serial/io_ti.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/io_ti.c 2005-01-07 15:42:28 -08:00
@@ -1342,9 +1342,9 @@
if (status)
return status;
- if (serial->serial->dev->descriptor.idVendor != USB_VENDOR_ID_ION) {
+ if (le16_to_cpu(serial->serial->dev->descriptor.idVendor) != USB_VENDOR_ID_ION) {
dbg ("%s - VID = 0x%x", __FUNCTION__,
- serial->serial->dev->descriptor.idVendor);
+ le16_to_cpu(serial->serial->dev->descriptor.idVendor));
serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
goto StayInBootMode;
}
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/keyspan.c 2005-01-07 15:42:28 -08:00
@@ -1174,16 +1174,16 @@
char *fw_name;
dbg("Keyspan startup version %04x product %04x",
- serial->dev->descriptor.bcdDevice,
- serial->dev->descriptor.idProduct);
+ le16_to_cpu(serial->dev->descriptor.bcdDevice),
+ le16_to_cpu(serial->dev->descriptor.idProduct));
- if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
+ if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000) != 0x8000) {
dbg("Firmware already loaded. Quitting.");
return(1);
}
/* Select firmware image on the basis of idProduct */
- switch (serial->dev->descriptor.idProduct) {
+ switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
case keyspan_usa28_pre_product_id:
record = &keyspan_usa28_firmware[0];
fw_name = "USA28";
@@ -2248,10 +2248,10 @@
dbg("%s", __FUNCTION__);
for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
- if (d_details->product_id == serial->dev->descriptor.idProduct)
+ if (d_details->product_id == le16_to_cpu(serial->dev->descriptor.idProduct))
break;
if (d_details == NULL) {
- dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, serial->dev->descriptor.idProduct);
+ dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, le16_to_cpu(serial->dev->descriptor.idProduct));
return 1;
}
diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
--- a/drivers/usb/serial/keyspan_pda.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/keyspan_pda.c 2005-01-07 15:42:28 -08:00
@@ -713,12 +713,12 @@
response = ezusb_set_reset(serial, 1);
#ifdef KEYSPAN
- if (serial->dev->descriptor.idVendor == KEYSPAN_VENDOR_ID)
+ if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
record = &keyspan_pda_firmware[0];
#endif
#ifdef XIRCOM
- if ((serial->dev->descriptor.idVendor == XIRCOM_VENDOR_ID) ||
- (serial->dev->descriptor.idVendor == ENTREGRA_VENDOR_ID))
+ if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
+ (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
record = &xircom_pgs_firmware[0];
#endif
if (record == NULL) {
diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
--- a/drivers/usb/serial/kobil_sct.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/kobil_sct.c 2005-01-07 15:42:28 -08:00
@@ -155,7 +155,7 @@
priv->filled = 0;
priv->cur_pos = 0;
- priv->device_type = serial->product;
+ priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
priv->line_state = 0;
switch (priv->device_type){
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/mct_u232.c 2005-01-07 15:42:28 -08:00
@@ -173,9 +173,10 @@
* we do not know how to support. We ignore them for the moment.
* XXX Rate-limit the error message, it's user triggerable.
*/
-static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
- if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
- || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value)
+{
+ if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
+ || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
switch (value) {
case B300: return 0x01;
case B600: return 0x02; /* this one not tested */
@@ -403,7 +404,7 @@
* it seems to be able to accept only 16 bytes (and that's what
* SniffUSB says too...)
*/
- if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
+ if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)
port->bulk_out_size = 16;
/* Do a defined restart: the normal serial device seems to
diff -Nru a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
--- a/drivers/usb/serial/ti_usb_3410_5052.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/ti_usb_3410_5052.c 2005-01-07 15:42:28 -08:00
@@ -407,7 +407,10 @@
int i;
- dbg("%s - product 0x%4X, num configurations %d, configuration value %d", __FUNCTION__, dev->descriptor.idProduct, dev->descriptor.bNumConfigurations, dev->actconfig->desc.bConfigurationValue);
+ dbg("%s - product 0x%4X, num configurations %d, configuration value %d",
+ __FUNCTION__, le16_to_cpu(dev->descriptor.idProduct),
+ dev->descriptor.bNumConfigurations,
+ dev->actconfig->desc.bConfigurationValue);
/* create device structure */
tdev = kmalloc(sizeof(struct ti_device), GFP_KERNEL);
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/usb-serial.c 2005-01-07 15:42:28 -08:00
@@ -721,7 +721,9 @@
if (serial->type->owner)
length += sprintf (page+length, " module:%s", module_name(serial->type->owner));
length += sprintf (page+length, " name:\"%s\"", serial->type->name);
- length += sprintf (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product);
+ length += sprintf (page+length, " vendor:%04x product:%04x",
+ le16_to_cpu(serial->dev->descriptor.idVendor),
+ le16_to_cpu(serial->dev->descriptor.idProduct));
length += sprintf (page+length, " num_ports:%d", serial->num_ports);
length += sprintf (page+length, " port:%d", i - serial->minor + 1);
@@ -834,8 +836,6 @@
serial->dev = usb_get_dev(dev);
serial->type = type;
serial->interface = interface;
- serial->vendor = dev->descriptor.idVendor;
- serial->product = dev->descriptor.idProduct;
kref_init(&serial->kref);
return serial;
@@ -959,10 +959,10 @@
#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
/* BEGIN HORRIBLE HACK FOR PL2303 */
/* this is needed due to the looney way its endpoints are set up */
- if (((dev->descriptor.idVendor == PL2303_VENDOR_ID) &&
- (dev->descriptor.idProduct == PL2303_PRODUCT_ID)) ||
- ((dev->descriptor.idVendor == ATEN_VENDOR_ID) &&
- (dev->descriptor.idProduct == ATEN_PRODUCT_ID))) {
+ if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
+ (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
+ ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
+ (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID))) {
if (interface != dev->actconfig->interface[0]) {
/* check out the endpoints of the other interface*/
iface_desc = dev->actconfig->interface[0]->cur_altsetting;
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/usb-serial.h 2005-01-07 15:42:28 -08:00
@@ -148,8 +148,6 @@
* @num_interrupt_out: number of interrupt out endpoints we have
* @num_bulk_in: number of bulk in endpoints we have
* @num_bulk_out: number of bulk out endpoints we have
- * @vendor: vendor id of this device
- * @product: product id of this device
* @port: array of struct usb_serial_port structures for the different ports.
* @private: place to put any driver specific information that is needed. The
* usb-serial driver is required to manage this data, the usb-serial core
@@ -167,8 +165,6 @@
char num_interrupt_out;
char num_bulk_in;
char num_bulk_out;
- __u16 vendor;
- __u16 product;
struct usb_serial_port * port[MAX_NUM_PORTS];
struct kref kref;
void * private;
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/serial/visor.c 2005-01-07 15:42:28 -08:00
@@ -926,8 +926,8 @@
/* Only do this endpoint hack for the Handspring devices with
* interrupt in endpoints, which for now are the Treo devices. */
- if (!((serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) ||
- (serial->dev->descriptor.idVendor == KYOCERA_VENDOR_ID)) ||
+ if (!((le16_to_cpu(serial->dev->descriptor.idVendor) == HANDSPRING_VENDOR_ID) ||
+ (le16_to_cpu(serial->dev->descriptor.idVendor) == KYOCERA_VENDOR_ID)) ||
(serial->num_interrupt_in == 0))
goto generic_startup;
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/storage/scsiglue.c 2005-01-07 15:42:28 -08:00
@@ -118,7 +118,7 @@
* works okay and that's what Windows does. But we'll be
* conservative; people can always use the sysfs interface to
* increase max_sectors. */
- if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS &&
+ if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS &&
sdev->request_queue->max_sectors > 64)
blk_queue_max_sectors(sdev->request_queue, 64);
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/storage/transport.c 2005-01-07 15:42:28 -08:00
@@ -994,7 +994,7 @@
/* Genesys Logic interface chips need a 100us delay between the
* command phase and the data phase. Some devices need a little
* more than that, probably because of clock rate inaccuracies. */
- if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS)
+ if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS)
udelay(110);
if (transfer_length) {
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c 2005-01-07 15:42:28 -08:00
+++ b/drivers/usb/storage/usb.c 2005-01-07 15:42:28 -08:00
@@ -263,16 +263,17 @@
available from the device."). */
memset(data+8,0,28);
} else {
+ u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
memcpy(data+8, us->unusual_dev->vendorName,
strlen(us->unusual_dev->vendorName) > 8 ? 8 :
strlen(us->unusual_dev->vendorName));
memcpy(data+16, us->unusual_dev->productName,
strlen(us->unusual_dev->productName) > 16 ? 16 :
strlen(us->unusual_dev->productName));
- data[32] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>12) & 0x0F);
- data[33] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>8) & 0x0F);
- data[34] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>4) & 0x0F);
- data[35] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice) & 0x0F);
+ data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
+ data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
+ data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
+ data[35] = 0x30 + ((bcdDevice) & 0x0F);
}
usb_stor_set_xfer_buf(data, data_len, us->srb);
@@ -436,9 +437,9 @@
us->pusb_intf = intf;
us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
US_DEBUGP("Vendor: 0x%04x, Product: 0x%04x, Revision: 0x%04x\n",
- us->pusb_dev->descriptor.idVendor,
- us->pusb_dev->descriptor.idProduct,
- us->pusb_dev->descriptor.bcdDevice);
+ le16_to_cpu(us->pusb_dev->descriptor.idVendor),
+ le16_to_cpu(us->pusb_dev->descriptor.idProduct),
+ le16_to_cpu(us->pusb_dev->descriptor.bcdDevice));
US_DEBUGP("Interface Subclass: 0x%02x, Protocol: 0x%02x\n",
intf->cur_altsetting->desc.bInterfaceSubClass,
intf->cur_altsetting->desc.bInterfaceProtocol);
@@ -507,8 +508,9 @@
" has %s in unusual_devs.h\n"
" Please send a copy of this message to "
"<[email protected]>\n",
- ddesc->idVendor, ddesc->idProduct,
- ddesc->bcdDevice,
+ le16_to_cpu(ddesc->idVendor),
+ le16_to_cpu(ddesc->idProduct),
+ le16_to_cpu(ddesc->bcdDevice),
idesc->bInterfaceSubClass,
idesc->bInterfaceProtocol,
msgs[msg]);
diff -Nru a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
--- a/include/linux/usb_ch9.h 2005-01-07 15:42:28 -08:00
+++ b/include/linux/usb_ch9.h 2005-01-07 15:42:28 -08:00
@@ -156,14 +156,14 @@
__u8 bLength;
__u8 bDescriptorType;
- __u16 bcdUSB;
+ __le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
- __u16 idVendor;
- __u16 idProduct;
- __u16 bcdDevice;
+ __le16 idVendor;
+ __le16 idProduct;
+ __le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
@@ -297,7 +297,7 @@
__u8 bLength;
__u8 bDescriptorType;
- __u16 bcdUSB;
+ __le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c 2005-01-07 15:42:28 -08:00
+++ b/sound/usb/usbaudio.c 2005-01-07 15:42:28 -08:00
@@ -2176,13 +2176,13 @@
static int is_big_endian_format(struct usb_device *dev, struct audioformat *fp)
{
/* M-Audio */
- if (dev->descriptor.idVendor == 0x0763) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763) {
/* Quattro: captured data only */
- if (dev->descriptor.idProduct == 0x2001 &&
+ if (le16_to_cpu(dev->descriptor.idProduct) == 0x2001 &&
fp->endpoint & USB_DIR_IN)
return 1;
/* Audiophile USB */
- if (dev->descriptor.idProduct == 0x2003)
+ if (le16_to_cpu(dev->descriptor.idProduct) == 0x2003)
return 1;
}
return 0;
@@ -2246,7 +2246,8 @@
break;
case USB_AUDIO_FORMAT_PCM8:
/* Dallas DS4201 workaround */
- if (dev->descriptor.idVendor == 0x04fa && dev->descriptor.idProduct == 0x4201)
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x4201)
pcm_format = SNDRV_PCM_FORMAT_S8;
else
pcm_format = SNDRV_PCM_FORMAT_U8;
@@ -2414,7 +2415,8 @@
/* extigy apparently supports sample rates other than 48k
* but not in ordinary way. so we enable only 48k atm.
*/
- if (dev->descriptor.idVendor == 0x041e && dev->descriptor.idProduct == 0x3000) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x3000) {
if (fmt[3] == USB_FORMAT_TYPE_I &&
stream == SNDRV_PCM_STREAM_PLAYBACK &&
fp->rates != SNDRV_PCM_RATE_48000)
@@ -2517,8 +2519,8 @@
/* some quirks for attributes here */
/* workaround for AudioTrak Optoplay */
- if (dev->descriptor.idVendor == 0x0a92 &&
- dev->descriptor.idProduct == 0x0053) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x0a92 &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0053) {
/* Optoplay sets the sample rate attribute although
* it seems not supporting it in fact.
*/
@@ -2526,8 +2528,8 @@
}
/* workaround for M-Audio Audiophile USB */
- if (dev->descriptor.idVendor == 0x0763 &&
- dev->descriptor.idProduct == 0x2003) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763 &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x2003) {
/* doesn't set the sample rate attribute, but supports it */
fp->attributes |= EP_CS_ATTR_SAMPLE_RATE;
}
@@ -2536,11 +2538,11 @@
* plantronics headset and Griffin iMic have set adaptive-in
* although it's really not...
*/
- if ((dev->descriptor.idVendor == 0x047f &&
- dev->descriptor.idProduct == 0x0ca1) ||
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x047f &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x0ca1) ||
/* Griffin iMic (note that there is an older model 77d:223) */
- (dev->descriptor.idVendor == 0x077d &&
- dev->descriptor.idProduct == 0x07af)) {
+ (le16_to_cpu(dev->descriptor.idVendor) == 0x077d &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x07af)) {
fp->ep_attr &= ~EP_ATTR_MASK;
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
fp->ep_attr |= EP_ATTR_ADAPTIVE;
@@ -2788,7 +2790,7 @@
.type = QUIRK_MIDI_FIXED_ENDPOINT,
.data = &ua25_ep
};
- if (chip->dev->descriptor.idProduct == 0x002b)
+ if (le16_to_cpu(chip->dev->descriptor.idProduct) == 0x002b)
return snd_usb_create_midi_interface(chip, iface,
&ua700_quirk);
else
@@ -3000,7 +3002,9 @@
{
snd_usb_audio_t *chip = entry->private_data;
if (! chip->shutdown)
- snd_iprintf(buffer, "%04x:%04x\n", chip->dev->descriptor.idVendor, chip->dev->descriptor.idProduct);
+ snd_iprintf(buffer, "%04x:%04x\n",
+ le16_to_cpu(chip->dev->descriptor.idVendor),
+ le16_to_cpu(chip->dev->descriptor.idProduct));
}
static void snd_usb_audio_create_proc(snd_usb_audio_t *chip)
@@ -3081,7 +3085,8 @@
strcpy(card->driver, "USB-Audio");
sprintf(component, "USB%04x:%04x",
- dev->descriptor.idVendor, dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
snd_component_add(card, component);
/* retrieve the device string as shortname */
@@ -3093,7 +3098,8 @@
card->shortname, sizeof(card->shortname)) <= 0) {
/* no name available from anywhere, so use ID */
sprintf(card->shortname, "USB Device %#04x:%#04x",
- dev->descriptor.idVendor, dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
}
}
@@ -3160,7 +3166,8 @@
/* SB Extigy needs special boot-up sequence */
/* if more models come, this will go to the quirk list. */
- if (dev->descriptor.idVendor == 0x041e && dev->descriptor.idProduct == 0x3000) {
+ if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x3000) {
if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
goto __err_val;
config = dev->actconfig;
@@ -3194,8 +3201,8 @@
}
for (i = 0; i < SNDRV_CARDS; i++)
if (enable[i] && ! usb_chip[i] &&
- (vid[i] == -1 || vid[i] == dev->descriptor.idVendor) &&
- (pid[i] == -1 || pid[i] == dev->descriptor.idProduct)) {
+ (vid[i] == -1 || vid[i] == le16_to_cpu(dev->descriptor.idVendor)) &&
+ (pid[i] == -1 || pid[i] == le16_to_cpu(dev->descriptor.idProduct))) {
if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
goto __error;
}
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c 2005-01-07 15:42:28 -08:00
+++ b/sound/usb/usbmidi.c 2005-01-07 15:42:28 -08:00
@@ -521,7 +521,7 @@
struct usb_host_interface *hostif;
struct usb_interface_descriptor* intfd;
- if (umidi->chip->dev->descriptor.idVendor != 0x0582)
+ if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) != 0x0582)
return NULL;
intf = umidi->iface;
if (!intf || intf->num_altsetting != 2)
@@ -839,8 +839,8 @@
/* TODO: read port name from jack descriptor */
name_format = "%s MIDI %d";
- vendor = umidi->chip->dev->descriptor.idVendor;
- product = umidi->chip->dev->descriptor.idProduct;
+ vendor = le16_to_cpu(umidi->chip->dev->descriptor.idVendor);
+ product = le16_to_cpu(umidi->chip->dev->descriptor.idProduct);
for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) {
if (snd_usbmidi_port_names[i].vendor == vendor &&
snd_usbmidi_port_names[i].product == product &&
diff -Nru a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
--- a/sound/usb/usbmixer.c 2005-01-07 15:42:28 -08:00
+++ b/sound/usb/usbmixer.c 2005-01-07 15:42:28 -08:00
@@ -1490,12 +1490,12 @@
state.buffer = hostif->extra;
state.buflen = hostif->extralen;
state.ctrlif = ctrlif;
- state.vendor = dev->idVendor;
- state.product = dev->idProduct;
+ state.vendor = le16_to_cpu(dev->idVendor);
+ state.product = le16_to_cpu(dev->idProduct);
/* check the mapping table */
for (map = usbmix_ctl_maps; map->vendor; map++) {
- if (map->vendor == dev->idVendor && map->product == dev->idProduct) {
+ if (map->vendor == le16_to_cpu(dev->idVendor) && map->product == le16_to_cpu(dev->idProduct)) {
state.map = map->map;
chip->ignore_ctl_error = map->ignore_ctl_error;
break;
diff -Nru a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
--- a/sound/usb/usx2y/usX2Yhwdep.c 2005-01-07 15:42:28 -08:00
+++ b/sound/usb/usx2y/usX2Yhwdep.c 2005-01-07 15:42:28 -08:00
@@ -133,7 +133,7 @@
};
int id = -1;
- switch (((usX2Ydev_t*)hw->private_data)->chip.dev->descriptor.idProduct) {
+ switch (le16_to_cpu(((usX2Ydev_t*)hw->private_data)->chip.dev->descriptor.idProduct)) {
case USB_ID_US122:
id = USX2Y_TYPE_122;
break;
@@ -185,7 +185,7 @@
};
struct usb_device *dev = usX2Y(card)->chip.dev;
struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
- snd_usb_audio_quirk_t *quirk = dev->descriptor.idProduct == USB_ID_US428 ? &quirk_2 : &quirk_1;
+ snd_usb_audio_quirk_t *quirk = le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? &quirk_2 : &quirk_1;
snd_printdd("usX2Y_create_usbmidi \n");
return snd_usb_create_midi_interface(&usX2Y(card)->chip, iface, quirk);
diff -Nru a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
--- a/sound/usb/usx2y/usbusx2y.c 2005-01-07 15:42:28 -08:00
+++ b/sound/usb/usx2y/usbusx2y.c 2005-01-07 15:42:28 -08:00
@@ -331,7 +331,8 @@
sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
card->shortname,
- device->descriptor.idVendor, device->descriptor.idProduct,
+ le16_to_cpu(device->descriptor.idVendor),
+ le16_to_cpu(device->descriptor.idProduct),
0,//us428(card)->usbmidi.ifnum,
usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum
);
@@ -344,10 +345,10 @@
{
int err;
snd_card_t* card;
- if (device->descriptor.idVendor != 0x1604 ||
- (device->descriptor.idProduct != USB_ID_US122 &&
- device->descriptor.idProduct != USB_ID_US224 &&
- device->descriptor.idProduct != USB_ID_US428) ||
+ if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
+ (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
+ le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
+ le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428) ||
!(card = usX2Y_create_card(device)))
return NULL;
if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
diff -Nru a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
--- a/sound/usb/usx2y/usbusx2yaudio.c 2005-01-07 15:42:28 -08:00
+++ b/sound/usb/usx2y/usbusx2yaudio.c 2005-01-07 15:42:28 -08:00
@@ -1023,10 +1023,10 @@
if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
return err;
- if (usX2Y(card)->chip.dev->descriptor.idProduct == USB_ID_US428)
+ if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) == USB_ID_US428)
if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
return err;
- if (usX2Y(card)->chip.dev->descriptor.idProduct != USB_ID_US122)
+ if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) != USB_ID_US122)
err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
return err;
}
ChangeSet 1.1938.439.47, 2005/01/06 16:39:32-08:00, [email protected]
[PATCH] fix oops when reading resourceN files in sysfs
On Thursday, January 6, 2005 12:25 pm, Jesse Barnes wrote:
> [Sorry about the bogus reply, I don't have the original message.]
>
> That shouldn't happen. Maybe you were running an old version of the tree
> or an old version of my sysfs mmap patch? When I do a 'bk pull' of
> gregkh's latest usb tree into a recent Linus tree, I get an -EINVAL, not an
> oops. An earlier version of my patch had this bug though, so maybe that's
> what you're seeing?
Ugg. How about this?
Zero out newly allocated bin_attributes for legacy I/O, memory and resource
files since we won't fill in all of the file operation methods. This will
allow the checks in bin.c for the existence of a method to work properly
instead of checking garbage memory.
Signed-off-by: Jesse Barnes <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/pci/pci-sysfs.c | 1 +
drivers/pci/probe.c | 1 +
2 files changed, 2 insertions(+)
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c 2005-01-07 15:38:33 -08:00
+++ b/drivers/pci/pci-sysfs.c 2005-01-07 15:38:33 -08:00
@@ -295,6 +295,7 @@
res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
if (res_attr) {
+ memset(res_attr, 0, sizeof(*res_attr) + 10);
pdev->res_attr[i] = res_attr;
/* Allocated above after the res_attr struct */
res_attr->attr.name = (char *)(res_attr + 1);
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c 2005-01-07 15:38:33 -08:00
+++ b/drivers/pci/probe.c 2005-01-07 15:38:33 -08:00
@@ -41,6 +41,7 @@
b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2,
GFP_ATOMIC);
if (b->legacy_io) {
+ memset(b->legacy_io, 0, sizeof(struct bin_attribute) * 2);
b->legacy_io->attr.name = "legacy_io";
b->legacy_io->size = 0xffff;
b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
ChangeSet 1.1938.446.2, 2004/12/15 14:12:32-08:00, [email protected]
[PATCH] USB: serial driver for TI USB 3410/5052 chips (1/3)
* New USB serial driver for devices based on the TI USB
3410 and 5052 chips. (1/3)
* Changed to use circ_buf.h.
Signed-off-by: Al Borchers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/Kconfig | 10
drivers/usb/serial/Makefile | 1
drivers/usb/serial/ti_usb_3410_5052.c | 1839 ++++++++++++++++++++++++++++++++++
drivers/usb/serial/ti_usb_3410_5052.h | 224 ++++
4 files changed, 2074 insertions(+)
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig 2005-01-07 15:51:18 -08:00
+++ b/drivers/usb/serial/Kconfig 2005-01-07 15:51:18 -08:00
@@ -380,6 +380,16 @@
bool "USB Secure Encapsulated Driver - Padded"
depends on USB_SERIAL_SAFE
+config USB_SERIAL_TI
+ tristate "USB TI 3410/5052 Serial Driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use the TI USB 3410 or 5052
+ serial devices.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ti_usb_3410_5052.
+
config USB_SERIAL_CYBERJACK
tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
diff -Nru a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
--- a/drivers/usb/serial/Makefile 2005-01-07 15:51:18 -08:00
+++ b/drivers/usb/serial/Makefile 2005-01-07 15:51:18 -08:00
@@ -30,6 +30,7 @@
obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
+obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o
diff -Nru a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_usb_3410_5052.c 2005-01-07 15:51:18 -08:00
@@ -0,0 +1,1839 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 3410/5052 USB Serial Driver
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This driver is based on the Linux io_ti driver, which is
+ * Copyright (C) 2000-2002 Inside Out Networks
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman
+ *
+ * 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.
+ *
+ * For questions or problems with this driver, contact Texas Instruments
+ * technical support, or Al Borchers <[email protected]>, or
+ * Peter Berger <[email protected]>.
+ *
+ * This driver needs this hotplug script in /etc/hotplug/usb/ti_usb_3410_5052
+ * or in /etc/hotplug.d/usb/ti_usb_3410_5052.hotplug to set the device
+ * configuration.
+ *
+ * #!/bin/bash
+ *
+ * BOOT_CONFIG=1
+ * ACTIVE_CONFIG=2
+ *
+ * if [[ "$ACTION" != "add" ]]
+ * then
+ * exit
+ * fi
+ *
+ * CONFIG_PATH=/sys${DEVPATH%/?*}/bConfigurationValue
+ *
+ * if [[ 0`cat $CONFIG_PATH` -ne $BOOT_CONFIG ]]
+ * then
+ * exit
+ * fi
+ *
+ * PRODUCT=${PRODUCT%/?*} # delete version
+ * VENDOR_ID=`printf "%d" 0x${PRODUCT%/?*}`
+ * PRODUCT_ID=`printf "%d" 0x${PRODUCT#*?/}`
+ *
+ * PARAM_PATH=/sys/module/ti_usb_3410_5052/parameters
+ *
+ * function scan() {
+ * s=$1
+ * shift
+ * for i
+ * do
+ * if [[ $s -eq $i ]]
+ * then
+ * return 0
+ * fi
+ * done
+ * return 1
+ * }
+ *
+ * IFS=$IFS,
+ *
+ * if (scan $VENDOR_ID 1105 `cat $PARAM_PATH/vendor_3410` &&
+ * scan $PRODUCT_ID 13328 `cat $PARAM_PATH/product_3410`) ||
+ * (scan $VENDOR_ID 1105 `cat $PARAM_PATH/vendor_5052` &&
+ * scan $PRODUCT_ID 20562 20818 20570 20575 `cat $PARAM_PATH/product_5052`)
+ * then
+ * echo $ACTIVE_CONFIG > $CONFIG_PATH
+ * fi
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/ioctl.h>
+#include <linux/serial.h>
+#include <linux/circ_buf.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <linux/usb.h>
+
+#include "usb-serial.h"
+#include "ti_usb_3410_5052.h"
+#include "ti_fw_3410.h" /* firmware image for 3410 */
+#include "ti_fw_5052.h" /* firmware image for 5052 */
+
+
+/* Defines */
+
+#define TI_DRIVER_VERSION "v0.9"
+#define TI_DRIVER_AUTHOR "Al Borchers <[email protected]>"
+#define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver"
+
+#define TI_FIRMWARE_BUF_SIZE 16284
+
+#define TI_WRITE_BUF_SIZE 1024
+
+#define TI_TRANSFER_TIMEOUT 2
+
+#define TI_DEFAULT_LOW_LATENCY 0
+#define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */
+
+/* supported setserial flags */
+#define TI_SET_SERIAL_FLAGS (ASYNC_LOW_LATENCY)
+
+/* read urb states */
+#define TI_READ_URB_RUNNING 0
+#define TI_READ_URB_STOPPING 1
+#define TI_READ_URB_STOPPED 2
+
+#define TI_EXTRA_VID_PID_COUNT 5
+
+
+/* Structures */
+
+struct ti_port {
+ int tp_is_open;
+ __u8 tp_msr;
+ __u8 tp_lsr;
+ __u8 tp_shadow_mcr;
+ __u8 tp_uart_mode; /* 232 or 485 modes */
+ unsigned int tp_uart_base_addr;
+ int tp_flags;
+ int tp_closing_wait;/* in .01 secs */
+ struct async_icount tp_icount;
+ wait_queue_head_t tp_msr_wait; /* wait for msr change */
+ wait_queue_head_t tp_write_wait;
+ struct ti_device *tp_tdev;
+ struct usb_serial_port *tp_port;
+ spinlock_t tp_lock;
+ int tp_read_urb_state;
+ int tp_write_urb_in_use;
+ struct circ_buf *tp_write_buf;
+};
+
+struct ti_device {
+ struct semaphore td_open_close_sem;
+ int td_open_port_count;
+ struct usb_serial *td_serial;
+ int td_is_3410;
+ int td_urb_error;
+};
+
+
+/* Function Declarations */
+
+static int ti_startup(struct usb_serial *serial);
+static void ti_shutdown(struct usb_serial *serial);
+static int ti_open(struct usb_serial_port *port, struct file *file);
+static void ti_close(struct usb_serial_port *port, struct file *file);
+static int ti_write(struct usb_serial_port *port, const unsigned char *data,
+ int count);
+static int ti_write_room(struct usb_serial_port *port);
+static int ti_chars_in_buffer(struct usb_serial_port *port);
+static void ti_throttle(struct usb_serial_port *port);
+static void ti_unthrottle(struct usb_serial_port *port);
+static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
+static void ti_set_termios(struct usb_serial_port *port,
+ struct termios *old_termios);
+static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
+static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int set, unsigned int clear);
+static void ti_break(struct usb_serial_port *port, int break_state);
+static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs);
+static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs);
+static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs);
+
+static void ti_recv(struct device *dev, struct tty_struct *tty,
+ unsigned char *data, int length);
+static void ti_send(struct ti_port *tport);
+static int ti_set_mcr(struct ti_port *tport, unsigned int mcr);
+static int ti_get_lsr(struct ti_port *tport);
+static int ti_get_serial_info(struct ti_port *tport,
+ struct serial_struct __user *ret_arg);
+static int ti_set_serial_info(struct ti_port *tport,
+ struct serial_struct *new_arg);
+static void ti_handle_new_msr(struct ti_port *tport, __u8 msr);
+
+static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush);
+
+static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty);
+static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty);
+
+static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
+ __u16 moduleid, __u16 value, __u8 *data, int size);
+static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
+ __u16 moduleid, __u16 value, __u8 *data, int size);
+
+static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
+ __u8 mask, __u8 byte);
+
+static int ti_download_firmware(struct ti_device *tdev,
+ unsigned char *firmware, unsigned int firmware_size);
+
+/* circular buffer */
+static struct circ_buf *ti_buf_alloc(void);
+static inline void ti_buf_free(struct circ_buf *cb);
+static inline void ti_buf_clear(struct circ_buf *cb);
+static inline int ti_buf_data_avail(struct circ_buf *cb);
+static inline int ti_buf_space_avail(struct circ_buf *cb);
+static int ti_buf_put(struct circ_buf *cb, const char *buf, int count);
+static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
+
+
+/* Data */
+
+/* module parameters */
+static int debug;
+static int low_latency = TI_DEFAULT_LOW_LATENCY;
+static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
+static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
+static int vendor_3410_count;
+static ushort product_3410[TI_EXTRA_VID_PID_COUNT];
+static int product_3410_count;
+static ushort vendor_5052[TI_EXTRA_VID_PID_COUNT];
+static int vendor_5052_count;
+static ushort product_5052[TI_EXTRA_VID_PID_COUNT];
+static int product_5052_count;
+
+/* supported devices */
+/* the array dimension is the number of default entries plus */
+/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
+/* null entry */
+static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
+ { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+};
+
+static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
+ { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+};
+
+static struct usb_device_id ti_id_table_combined[] = {
+ { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
+ { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+ { }
+};
+
+static struct usb_driver ti_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "ti_usb_3410_5052",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = ti_id_table_combined,
+};
+
+static struct usb_serial_device_type ti_1port_device = {
+ .owner = THIS_MODULE,
+ .name = "TI USB 3410 1 port adapter",
+ .id_table = ti_id_table_3410,
+ .num_interrupt_in = 1,
+ .num_bulk_in = 1,
+ .num_bulk_out = 1,
+ .num_ports = 1,
+ .attach = ti_startup,
+ .shutdown = ti_shutdown,
+ .open = ti_open,
+ .close = ti_close,
+ .write = ti_write,
+ .write_room = ti_write_room,
+ .chars_in_buffer = ti_chars_in_buffer,
+ .throttle = ti_throttle,
+ .unthrottle = ti_unthrottle,
+ .ioctl = ti_ioctl,
+ .set_termios = ti_set_termios,
+ .tiocmget = ti_tiocmget,
+ .tiocmset = ti_tiocmset,
+ .break_ctl = ti_break,
+ .read_int_callback = ti_interrupt_callback,
+ .read_bulk_callback = ti_bulk_in_callback,
+ .write_bulk_callback = ti_bulk_out_callback,
+};
+
+static struct usb_serial_device_type ti_2port_device = {
+ .owner = THIS_MODULE,
+ .name = "TI USB 5052 2 port adapter",
+ .id_table = ti_id_table_5052,
+ .num_interrupt_in = 1,
+ .num_bulk_in = 2,
+ .num_bulk_out = 2,
+ .num_ports = 2,
+ .attach = ti_startup,
+ .shutdown = ti_shutdown,
+ .open = ti_open,
+ .close = ti_close,
+ .write = ti_write,
+ .write_room = ti_write_room,
+ .chars_in_buffer = ti_chars_in_buffer,
+ .throttle = ti_throttle,
+ .unthrottle = ti_unthrottle,
+ .ioctl = ti_ioctl,
+ .set_termios = ti_set_termios,
+ .tiocmget = ti_tiocmget,
+ .tiocmset = ti_tiocmset,
+ .break_ctl = ti_break,
+ .read_int_callback = ti_interrupt_callback,
+ .read_bulk_callback = ti_bulk_in_callback,
+ .write_bulk_callback = ti_bulk_out_callback,
+};
+
+
+/* Module */
+
+MODULE_AUTHOR(TI_DRIVER_AUTHOR);
+MODULE_DESCRIPTION(TI_DRIVER_DESC);
+MODULE_VERSION(TI_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
+
+module_param(low_latency, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(low_latency, "TTY low_latency flag, 0=off, 1=on, default is off");
+
+module_param(closing_wait, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain in close, in .01 secs, default is 4000");
+
+module_param_array(vendor_3410, ushort, &vendor_3410_count, S_IRUGO);
+MODULE_PARM_DESC(vendor_3410, "Vendor ids for 3410 based devices, 1-5 short integers");
+module_param_array(product_3410, ushort, &product_3410_count, S_IRUGO);
+MODULE_PARM_DESC(product_3410, "Product ids for 3410 based devices, 1-5 short integers");
+module_param_array(vendor_5052, ushort, &vendor_5052_count, S_IRUGO);
+MODULE_PARM_DESC(vendor_5052, "Vendor ids for 5052 based devices, 1-5 short integers");
+module_param_array(product_5052, ushort, &product_5052_count, S_IRUGO);
+MODULE_PARM_DESC(product_5052, "Product ids for 5052 based devices, 1-5 short integers");
+
+MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
+
+
+/* Functions */
+
+static int __init ti_init(void)
+{
+ int i,j;
+ int ret;
+
+
+ /* insert extra vendor and product ids */
+ j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id)
+ - TI_EXTRA_VID_PID_COUNT - 1;
+ for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) {
+ ti_id_table_3410[j].idVendor = vendor_3410[i];
+ ti_id_table_3410[j].idProduct = product_3410[i];
+ ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ }
+ j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id)
+ - TI_EXTRA_VID_PID_COUNT - 1;
+ for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) {
+ ti_id_table_5052[j].idVendor = vendor_5052[i];
+ ti_id_table_5052[j].idProduct = product_5052[i];
+ ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ }
+
+ ret = usb_serial_register(&ti_1port_device);
+ if (ret)
+ goto failed_1port;
+ ret = usb_serial_register(&ti_2port_device);
+ if (ret)
+ goto failed_2port;
+
+ ret = usb_register(&ti_usb_driver);
+ if (ret)
+ goto failed_usb;
+
+ info(TI_DRIVER_DESC " " TI_DRIVER_VERSION);
+
+ return 0;
+
+failed_usb:
+ usb_serial_deregister(&ti_2port_device);
+failed_2port:
+ usb_serial_deregister(&ti_1port_device);
+failed_1port:
+ return ret;
+}
+
+
+static void __exit ti_exit(void)
+{
+ usb_serial_deregister(&ti_1port_device);
+ usb_serial_deregister(&ti_2port_device);
+ usb_deregister(&ti_usb_driver);
+}
+
+
+module_init(ti_init);
+module_exit(ti_exit);
+
+
+static int ti_startup(struct usb_serial *serial)
+{
+ struct ti_device *tdev;
+ struct ti_port *tport;
+ struct usb_device *dev = serial->dev;
+ int status;
+ int i;
+
+
+ dbg("%s - product 0x%4X, num configurations %d, configuration value %d", __FUNCTION__, dev->descriptor.idProduct, dev->descriptor.bNumConfigurations, dev->actconfig->desc.bConfigurationValue);
+
+ /* create device structure */
+ tdev = kmalloc(sizeof(struct ti_device), GFP_KERNEL);
+ if (tdev == NULL) {
+ dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ memset(tdev, 0, sizeof(struct ti_device));
+ sema_init(&tdev->td_open_close_sem, 1);
+ tdev->td_serial = serial;
+ usb_set_serial_data(serial, tdev);
+
+ /* determine device type */
+ if (usb_match_id(serial->interface, ti_id_table_3410))
+ tdev->td_is_3410 = 1;
+ dbg("%s - device type is %s", __FUNCTION__, tdev->td_is_3410 ? "3410" : "5052");
+
+ /* if we have only 1 configuration, download firmware */
+ if (dev->descriptor.bNumConfigurations == 1) {
+
+ if (tdev->td_is_3410)
+ status = ti_download_firmware(tdev, ti_fw_3410,
+ sizeof(ti_fw_3410));
+ else
+ status = ti_download_firmware(tdev, ti_fw_5052,
+ sizeof(ti_fw_5052));
+ if (status)
+ goto free_tdev;
+
+ /* 3410 must be reset, 5052 resets itself */
+ if (tdev->td_is_3410) {
+ msleep_interruptible(100);
+ usb_reset_device(dev);
+ }
+
+ status = -ENODEV;
+ goto free_tdev;
+ }
+
+ /* the second configuration must be set (in sysfs by hotplug script) */
+ if (dev->actconfig->desc.bConfigurationValue == TI_BOOT_CONFIG) {
+ status = -ENODEV;
+ goto free_tdev;
+ }
+
+ /* set up port structures */
+ for (i = 0; i < serial->num_ports; ++i) {
+ tport = kmalloc(sizeof(struct ti_port), GFP_KERNEL);
+ if (tport == NULL) {
+ dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+ status = -ENOMEM;
+ goto free_tports;
+ }
+ memset(tport, 0, sizeof(struct ti_port));
+ spin_lock_init(&tport->tp_lock);
+ tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
+ tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
+ tport->tp_closing_wait = closing_wait;
+ init_waitqueue_head(&tport->tp_msr_wait);
+ init_waitqueue_head(&tport->tp_write_wait);
+ tport->tp_write_buf = ti_buf_alloc();
+ if (tport->tp_write_buf == NULL) {
+ dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+ kfree(tport);
+ status = -ENOMEM;
+ goto free_tports;
+ }
+ tport->tp_port = serial->port[i];
+ tport->tp_tdev = tdev;
+ usb_set_serial_port_data(serial->port[i], tport);
+ tport->tp_uart_mode = 0; /* default is RS232 */
+ }
+
+ return 0;
+
+free_tports:
+ for (--i; i>=0; --i) {
+ tport = usb_get_serial_port_data(serial->port[i]);
+ ti_buf_free(tport->tp_write_buf);
+ kfree(tport);
+ usb_set_serial_port_data(serial->port[i], NULL);
+ }
+free_tdev:
+ kfree(tdev);
+ usb_set_serial_data(serial, NULL);
+ return status;
+}
+
+
+static void ti_shutdown(struct usb_serial *serial)
+{
+ int i;
+ struct ti_device *tdev = usb_get_serial_data(serial);
+ struct ti_port *tport;
+
+ dbg("%s", __FUNCTION__);
+
+ for (i=0; i < serial->num_ports; ++i) {
+ tport = usb_get_serial_port_data(serial->port[i]);
+ if (tport) {
+ ti_buf_free(tport->tp_write_buf);
+ kfree(tport);
+ usb_set_serial_port_data(serial->port[i], NULL);
+ }
+ }
+
+ if (tdev)
+ kfree(tdev);
+ usb_set_serial_data(serial, NULL);
+}
+
+
+static int ti_open(struct usb_serial_port *port, struct file *file)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ struct ti_device *tdev;
+ struct usb_device *dev;
+ struct urb *urb;
+ int port_number;
+ int status;
+ __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS |
+ TI_PIPE_TIMEOUT_ENABLE |
+ (TI_TRANSFER_TIMEOUT << 2));
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
+ dev = port->serial->dev;
+ tdev = tport->tp_tdev;
+
+ /* only one open on any port on a device at a time */
+ if (down_interruptible(&tdev->td_open_close_sem))
+ return -ERESTARTSYS;
+
+ if (port->tty)
+ port->tty->low_latency =
+ (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+ port_number = port->number - port->serial->minor;
+
+ memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
+
+ tport->tp_msr = 0;
+ tport->tp_shadow_mcr |= (TI_MCR_RTS | TI_MCR_DTR);
+
+ /* start interrupt urb the first time a port is opened on this device */
+ if (tdev->td_open_port_count == 0) {
+ dbg("%s - start interrupt in urb", __FUNCTION__);
+ urb = tdev->td_serial->port[0]->interrupt_in_urb;
+ if (!urb) {
+ dev_err(&port->dev, "%s - no interrupt urb\n", __FUNCTION__);
+ status = -EINVAL;
+ goto up_sem;
+ }
+ urb->complete = ti_interrupt_callback;
+ urb->context = tdev;
+ urb->dev = dev;
+ status = usb_submit_urb(urb, GFP_KERNEL);
+ if (status) {
+ dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __FUNCTION__, status);
+ goto up_sem;
+ }
+ }
+
+ ti_set_termios(port, NULL);
+
+ dbg("%s - sending TI_OPEN_PORT", __FUNCTION__);
+ status = ti_command_out_sync(tdev, TI_OPEN_PORT,
+ (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
+ if (status) {
+ dev_err(&port->dev, "%s - cannot send open command, %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+
+ dbg("%s - sending TI_START_PORT", __FUNCTION__);
+ status = ti_command_out_sync(tdev, TI_START_PORT,
+ (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
+ if (status) {
+ dev_err(&port->dev, "%s - cannot send start command, %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+
+ dbg("%s - sending TI_PURGE_PORT", __FUNCTION__);
+ status = ti_command_out_sync(tdev, TI_PURGE_PORT,
+ (__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0);
+ if (status) {
+ dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+ status = ti_command_out_sync(tdev, TI_PURGE_PORT,
+ (__u8)(TI_UART1_PORT + port_number), TI_PURGE_OUTPUT, NULL, 0);
+ if (status) {
+ dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+
+ /* reset the data toggle on the bulk endpoints to work around bug in
+ * host controllers where things get out of sync some times */
+ usb_clear_halt(dev, port->write_urb->pipe);
+ usb_clear_halt(dev, port->read_urb->pipe);
+
+ ti_set_termios(port, NULL);
+
+ dbg("%s - sending TI_OPEN_PORT (2)", __FUNCTION__);
+ status = ti_command_out_sync(tdev, TI_OPEN_PORT,
+ (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
+ if (status) {
+ dev_err(&port->dev, "%s - cannot send open command (2), %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+
+ dbg("%s - sending TI_START_PORT (2)", __FUNCTION__);
+ status = ti_command_out_sync(tdev, TI_START_PORT,
+ (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
+ if (status) {
+ dev_err(&port->dev, "%s - cannot send start command (2), %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+
+ /* start read urb */
+ dbg("%s - start read urb", __FUNCTION__);
+ urb = port->read_urb;
+ if (!urb) {
+ dev_err(&port->dev, "%s - no read urb\n", __FUNCTION__);
+ status = -EINVAL;
+ goto unlink_int_urb;
+ }
+ tport->tp_read_urb_state = TI_READ_URB_RUNNING;
+ urb->complete = ti_bulk_in_callback;
+ urb->context = tport;
+ urb->dev = dev;
+ status = usb_submit_urb(urb, GFP_KERNEL);
+ if (status) {
+ dev_err(&port->dev, "%s - submit read urb failed, %d\n", __FUNCTION__, status);
+ goto unlink_int_urb;
+ }
+
+ tport->tp_is_open = 1;
+ ++tdev->td_open_port_count;
+
+ goto up_sem;
+
+unlink_int_urb:
+ if (tdev->td_open_port_count == 0)
+ usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
+up_sem:
+ up(&tdev->td_open_close_sem);
+ dbg("%s - exit %d", __FUNCTION__, status);
+ return status;
+}
+
+
+static void ti_close(struct usb_serial_port *port, struct file *file)
+{
+ struct ti_device *tdev;
+ struct ti_port *tport;
+ int port_number;
+ int status;
+ int do_up;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ tdev = usb_get_serial_data(port->serial);
+ tport = usb_get_serial_port_data(port);
+ if (tdev == NULL || tport == NULL)
+ return;
+
+ tport->tp_is_open = 0;
+
+ ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 1);
+
+ usb_kill_urb(port->read_urb);
+ usb_kill_urb(port->write_urb);
+ tport->tp_write_urb_in_use = 0;
+
+ port_number = port->number - port->serial->minor;
+
+ dbg("%s - sending TI_CLOSE_PORT", __FUNCTION__);
+ status = ti_command_out_sync(tdev, TI_CLOSE_PORT,
+ (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
+ if (status)
+ dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __FUNCTION__, status);
+
+ /* if down is interrupted, continue anyway */
+ do_up = !down_interruptible(&tdev->td_open_close_sem);
+ --tport->tp_tdev->td_open_port_count;
+ if (tport->tp_tdev->td_open_port_count <= 0) {
+ /* last port is closed, shut down interrupt urb */
+ usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
+ tport->tp_tdev->td_open_port_count = 0;
+ }
+ if (do_up)
+ up(&tdev->td_open_close_sem);
+
+ dbg("%s - exit", __FUNCTION__);
+}
+
+
+static int ti_write(struct usb_serial_port *port, const unsigned char *data,
+ int count)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (count == 0) {
+ dbg("%s - write request of 0 bytes", __FUNCTION__);
+ return 0;
+ }
+
+ if (tport == NULL || !tport->tp_is_open)
+ return -ENODEV;
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+ count = ti_buf_put(tport->tp_write_buf, data, count);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ ti_send(tport);
+
+ return count;
+}
+
+
+static int ti_write_room(struct usb_serial_port *port)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ int room = 0;
+ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+ room = ti_buf_space_avail(tport->tp_write_buf);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ dbg("%s - returns %d", __FUNCTION__, room);
+ return room;
+}
+
+
+static int ti_chars_in_buffer(struct usb_serial_port *port)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ int chars = 0;
+ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+ chars = ti_buf_data_avail(tport->tp_write_buf);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ dbg("%s - returns %d", __FUNCTION__, chars);
+ return chars;
+}
+
+
+static void ti_throttle(struct usb_serial_port *port)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ struct tty_struct *tty;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return;
+
+ tty = port->tty;
+ if (!tty) {
+ dbg("%s - no tty", __FUNCTION__);
+ return;
+ }
+
+ if (I_IXOFF(tty) || C_CRTSCTS(tty))
+ ti_stop_read(tport, tty);
+
+}
+
+
+static void ti_unthrottle(struct usb_serial_port *port)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ struct tty_struct *tty;
+ int status;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return;
+
+ tty = port->tty;
+ if (!tty) {
+ dbg("%s - no tty", __FUNCTION__);
+ return;
+ }
+
+ if (I_IXOFF(tty) || C_CRTSCTS(tty)) {
+ status = ti_restart_read(tport, tty);
+ if (status)
+ dev_err(&port->dev, "%s - cannot restart read, %d\n", __FUNCTION__, status);
+ }
+}
+
+
+static int ti_ioctl(struct usb_serial_port *port, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ struct async_icount cnow;
+ struct async_icount cprev;
+
+ dbg("%s - port %d, cmd = 0x%04X", __FUNCTION__, port->number, cmd);
+
+ if (tport == NULL)
+ return -ENODEV;
+
+ switch (cmd) {
+ case TIOCGSERIAL:
+ dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number);
+ return ti_get_serial_info(tport, (struct serial_struct __user *)arg);
+ break;
+
+ case TIOCSSERIAL:
+ dbg("%s - (%d) TIOCSSERIAL", __FUNCTION__, port->number);
+ return ti_set_serial_info(tport, (struct serial_struct *)arg);
+ break;
+
+ case TIOCMIWAIT:
+ dbg("%s - (%d) TIOCMIWAIT", __FUNCTION__, port->number);
+ cprev = tport->tp_icount;
+ while (1) {
+ interruptible_sleep_on(&tport->tp_msr_wait);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ cnow = tport->tp_icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+ return 0;
+ }
+ cprev = cnow;
+ }
+ break;
+
+ case TIOCGICOUNT:
+ dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, tport->tp_icount.rx, tport->tp_icount.tx);
+ if (copy_to_user((void __user *)arg, &tport->tp_icount, sizeof(tport->tp_icount)))
+ return -EFAULT;
+ return 0;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+
+static void ti_set_termios(struct usb_serial_port *port,
+ struct termios *old_termios)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ struct tty_struct *tty = port->tty;
+ struct ti_uart_config *config;
+ tcflag_t cflag,iflag;
+ int baud;
+ int status;
+ int port_number = port->number - port->serial->minor;
+ unsigned int mcr;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (!tty || !tty->termios) {
+ dbg("%s - no tty or termios", __FUNCTION__);
+ return;
+ }
+
+ cflag = tty->termios->c_cflag;
+ iflag = tty->termios->c_iflag;
+
+ if (old_termios && cflag == old_termios->c_cflag
+ && iflag == old_termios->c_iflag) {
+ dbg("%s - nothing to change", __FUNCTION__);
+ return;
+ }
+
+ dbg("%s - clfag %08x, iflag %08x", __FUNCTION__, cflag, iflag);
+
+ if (old_termios)
+ dbg("%s - old clfag %08x, old iflag %08x", __FUNCTION__, old_termios->c_cflag, old_termios->c_iflag);
+
+ if (tport == NULL)
+ return;
+
+ config = kmalloc(sizeof(*config), GFP_KERNEL);
+ if (!config) {
+ dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__);
+ return;
+ }
+
+ config->wFlags = 0;
+
+ /* these flags must be set */
+ config->wFlags |= TI_UART_ENABLE_MS_INTS;
+ config->wFlags |= TI_UART_ENABLE_AUTO_START_DMA;
+ config->bUartMode = (__u8)(tport->tp_uart_mode);
+
+ switch (cflag & CSIZE) {
+ case CS5:
+ config->bDataBits = TI_UART_5_DATA_BITS;
+ break;
+ case CS6:
+ config->bDataBits = TI_UART_6_DATA_BITS;
+ break;
+ case CS7:
+ config->bDataBits = TI_UART_7_DATA_BITS;
+ break;
+ default:
+ case CS8:
+ config->bDataBits = TI_UART_8_DATA_BITS;
+ break;
+ }
+
+ if (cflag & PARENB) {
+ if (cflag & PARODD) {
+ config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING;
+ config->bParity = TI_UART_ODD_PARITY;
+ } else {
+ config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING;
+ config->bParity = TI_UART_EVEN_PARITY;
+ }
+ } else {
+ config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING;
+ config->bParity = TI_UART_NO_PARITY;
+ }
+
+ if (cflag & CSTOPB)
+ config->bStopBits = TI_UART_2_STOP_BITS;
+ else
+ config->bStopBits = TI_UART_1_STOP_BITS;
+
+ if (cflag & CRTSCTS) {
+ /* RTS flow control must be off to drop RTS for baud rate B0 */
+ if ((cflag & CBAUD) != B0)
+ config->wFlags |= TI_UART_ENABLE_RTS_IN;
+ config->wFlags |= TI_UART_ENABLE_CTS_OUT;
+ } else {
+ tty->hw_stopped = 0;
+ ti_restart_read(tport, tty);
+ }
+
+ if (I_IXOFF(tty) || I_IXON(tty)) {
+ config->cXon = START_CHAR(tty);
+ config->cXoff = STOP_CHAR(tty);
+
+ if (I_IXOFF(tty))
+ config->wFlags |= TI_UART_ENABLE_X_IN;
+ else
+ ti_restart_read(tport, tty);
+
+ if (I_IXON(tty))
+ config->wFlags |= TI_UART_ENABLE_X_OUT;
+ }
+
+ baud = tty_get_baud_rate(tty);
+ if (!baud) baud = 9600;
+ if (tport->tp_tdev->td_is_3410)
+ config->wBaudRate = (__u16)((923077 + baud/2) / baud);
+ else
+ config->wBaudRate = (__u16)((461538 + baud/2) / baud);
+
+ dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d",
+ __FUNCTION__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode);
+
+ cpu_to_be16s(&config->wBaudRate);
+ cpu_to_be16s(&config->wFlags);
+
+ status = ti_command_out_sync(tport->tp_tdev, TI_SET_CONFIG,
+ (__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config,
+ sizeof(*config));
+ if (status)
+ dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __FUNCTION__, port_number, status);
+
+ /* SET_CONFIG asserts RTS and DTR, reset them correctly */
+ mcr = tport->tp_shadow_mcr;
+ /* if baud rate is B0, clear RTS and DTR */
+ if ((cflag & CBAUD) == B0)
+ mcr &= ~(TI_MCR_DTR | TI_MCR_RTS);
+ status = ti_set_mcr(tport, mcr);
+ if (status)
+ dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __FUNCTION__, port_number, status);
+
+ kfree(config);
+}
+
+
+static int ti_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ unsigned int result;
+ unsigned int msr;
+ unsigned int mcr;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
+ msr = tport->tp_msr;
+ mcr = tport->tp_shadow_mcr;
+
+ result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0)
+ | ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0)
+ | ((mcr & TI_MCR_LOOP) ? TIOCM_LOOP : 0)
+ | ((msr & TI_MSR_CTS) ? TIOCM_CTS : 0)
+ | ((msr & TI_MSR_CD) ? TIOCM_CAR : 0)
+ | ((msr & TI_MSR_RI) ? TIOCM_RI : 0)
+ | ((msr & TI_MSR_DSR) ? TIOCM_DSR : 0);
+
+ dbg("%s - 0x%04X", __FUNCTION__, result);
+
+ return result;
+}
+
+
+static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ unsigned int mcr;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
+ mcr = tport->tp_shadow_mcr;
+
+ if (set & TIOCM_RTS)
+ mcr |= TI_MCR_RTS;
+ if (set & TIOCM_DTR)
+ mcr |= TI_MCR_DTR;
+ if (set & TIOCM_LOOP)
+ mcr |= TI_MCR_LOOP;
+
+ if (clear & TIOCM_RTS)
+ mcr &= ~TI_MCR_RTS;
+ if (clear & TIOCM_DTR)
+ mcr &= ~TI_MCR_DTR;
+ if (clear & TIOCM_LOOP)
+ mcr &= ~TI_MCR_LOOP;
+
+ return ti_set_mcr(tport, mcr);
+}
+
+
+static void ti_break(struct usb_serial_port *port, int break_state)
+{
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ int status;
+
+ dbg("%s - state = %d", __FUNCTION__, break_state);
+
+ if (tport == NULL)
+ return;
+
+ ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 0);
+
+ status = ti_write_byte(tport->tp_tdev,
+ tport->tp_uart_base_addr + TI_UART_OFFSET_LCR,
+ TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0);
+
+ if (status)
+ dbg("%s - error setting break, %d", __FUNCTION__, status);
+}
+
+
+static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct ti_device *tdev = (struct ti_device *)urb->context;
+ struct usb_serial_port *port;
+ struct usb_serial *serial = tdev->td_serial;
+ struct ti_port *tport;
+ struct device *dev = &urb->dev->dev;
+ unsigned char *data = urb->transfer_buffer;
+ int length = urb->actual_length;
+ int port_number;
+ int function;
+ int status;
+ __u8 msr;
+
+ dbg("%s", __FUNCTION__);
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+ tdev->td_urb_error = 1;
+ return;
+ default:
+ dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);
+ tdev->td_urb_error = 1;
+ goto exit;
+ }
+
+ if (length != 2) {
+ dbg("%s - bad packet size, %d", __FUNCTION__, length);
+ goto exit;
+ }
+
+ if (data[0] == TI_CODE_HARDWARE_ERROR) {
+ dev_err(dev, "%s - hardware error, %d\n", __FUNCTION__, data[1]);
+ goto exit;
+ }
+
+ port_number = TI_GET_PORT_FROM_CODE(data[0]);
+ function = TI_GET_FUNC_FROM_CODE(data[0]);
+
+ dbg("%s - port_number %d, function %d, data 0x%02X", __FUNCTION__, port_number, function, data[1]);
+
+ if (port_number >= serial->num_ports) {
+ dev_err(dev, "%s - bad port number, %d\n", __FUNCTION__, port_number);
+ goto exit;
+ }
+
+ port = serial->port[port_number];
+
+ tport = usb_get_serial_port_data(port);
+ if (!tport)
+ goto exit;
+
+ switch (function) {
+ case TI_CODE_DATA_ERROR:
+ dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __FUNCTION__, port_number, data[1]);
+ break;
+
+ case TI_CODE_MODEM_STATUS:
+ msr = data[1];
+ dbg("%s - port %d, msr 0x%02X", __FUNCTION__, port_number, msr);
+ ti_handle_new_msr(tport, msr);
+ break;
+
+ default:
+ dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __FUNCTION__, data[1]);
+ break;
+ }
+
+exit:
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status)
+ dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", __FUNCTION__, status);
+}
+
+
+static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct ti_port *tport = (struct ti_port *)urb->context;
+ struct usb_serial_port *port = tport->tp_port;
+ struct device *dev = &urb->dev->dev;
+ int status = 0;
+
+ dbg("%s", __FUNCTION__);
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+ tport->tp_tdev->td_urb_error = 1;
+ wake_up_interruptible(&tport->tp_write_wait);
+ return;
+ default:
+ dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status );
+ tport->tp_tdev->td_urb_error = 1;
+ wake_up_interruptible(&tport->tp_write_wait);
+ }
+
+ if (urb->status == -EPIPE)
+ goto exit;
+
+ if (urb->status) {
+ dev_err(dev, "%s - stopping read!\n", __FUNCTION__);
+ return;
+ }
+
+ if (port->tty && urb->actual_length) {
+ usb_serial_debug_data(debug, dev, __FUNCTION__,
+ urb->actual_length, urb->transfer_buffer);
+
+ if (!tport->tp_is_open)
+ dbg("%s - port closed, dropping data", __FUNCTION__);
+ else
+ ti_recv(&urb->dev->dev, port->tty, urb->transfer_buffer,
+ urb->actual_length);
+
+ spin_lock(&tport->tp_lock);
+ tport->tp_icount.rx += urb->actual_length;
+ spin_unlock(&tport->tp_lock);
+ }
+
+exit:
+ /* continue to read unless stopping */
+ spin_lock(&tport->tp_lock);
+ if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) {
+ urb->dev = port->serial->dev;
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ } else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) {
+ tport->tp_read_urb_state = TI_READ_URB_STOPPED;
+ }
+ spin_unlock(&tport->tp_lock);
+ if (status)
+ dev_err(dev, "%s - resubmit read urb failed, %d\n", __FUNCTION__, status);
+}
+
+
+static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct ti_port *tport = (struct ti_port *)urb->context;
+ struct usb_serial_port *port = tport->tp_port;
+ struct device *dev = &urb->dev->dev;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ tport->tp_write_urb_in_use = 0;
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+ tport->tp_tdev->td_urb_error = 1;
+ wake_up_interruptible(&tport->tp_write_wait);
+ return;
+ default:
+ dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);
+ tport->tp_tdev->td_urb_error = 1;
+ wake_up_interruptible(&tport->tp_write_wait);
+ }
+
+ /* send any buffered data */
+ ti_send(tport);
+}
+
+
+static void ti_recv(struct device *dev, struct tty_struct *tty,
+ unsigned char *data, int length)
+{
+ int cnt;
+
+ do {
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ tty_flip_buffer_push(tty);
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length);
+ return;
+ }
+ }
+ cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);
+ memcpy(tty->flip.char_buf_ptr, data, cnt);
+ memset(tty->flip.flag_buf_ptr, 0, cnt);
+ tty->flip.char_buf_ptr += cnt;
+ tty->flip.flag_buf_ptr += cnt;
+ tty->flip.count += cnt;
+ data += cnt;
+ length -= cnt;
+ } while (length > 0);
+
+ tty_flip_buffer_push(tty);
+}
+
+
+static void ti_send(struct ti_port *tport)
+{
+ int count, result;
+ struct usb_serial_port *port = tport->tp_port;
+ struct tty_struct *tty = port->tty;
+ unsigned long flags;
+
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+
+ if (tport->tp_write_urb_in_use) {
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ return;
+ }
+
+ count = ti_buf_get(tport->tp_write_buf,
+ port->write_urb->transfer_buffer,
+ port->bulk_out_size);
+
+ if (count == 0) {
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ return;
+ }
+
+ tport->tp_write_urb_in_use = 1;
+
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);
+
+ usb_fill_bulk_urb(port->write_urb, port->serial->dev,
+ usb_sndbulkpipe(port->serial->dev,
+ port->bulk_out_endpointAddress),
+ port->write_urb->transfer_buffer, count,
+ ti_bulk_out_callback, tport);
+
+ result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&port->dev, "%s - submit write urb failed, %d\n", __FUNCTION__, result);
+ tport->tp_write_urb_in_use = 0;
+ /* TODO: reschedule ti_send */
+ } else {
+ spin_lock_irqsave(&tport->tp_lock, flags);
+ tport->tp_icount.tx += count;
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ }
+
+ /* more room in the buffer for new writes, wakeup */
+ if (tty)
+ tty_wakeup(tty);
+ wake_up_interruptible(&tport->tp_write_wait);
+}
+
+
+static int ti_set_mcr(struct ti_port *tport, unsigned int mcr)
+{
+ int status;
+
+ status = ti_write_byte(tport->tp_tdev,
+ tport->tp_uart_base_addr + TI_UART_OFFSET_MCR,
+ TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr);
+
+ if (!status)
+ tport->tp_shadow_mcr = mcr;
+
+ return status;
+}
+
+
+static int ti_get_lsr(struct ti_port *tport)
+{
+ int size,status;
+ struct ti_device *tdev = tport->tp_tdev;
+ struct usb_serial_port *port = tport->tp_port;
+ int port_number = port->number - port->serial->minor;
+ struct ti_port_status *data;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ size = sizeof(struct ti_port_status);
+ data = kmalloc(size, GFP_KERNEL);
+ if (!data) {
+ dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS,
+ (__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size);
+ if (status) {
+ dev_err(&port->dev, "%s - get port status command failed, %d\n", __FUNCTION__, status);
+ goto free_data;
+ }
+
+ dbg("%s - lsr 0x%02X", __FUNCTION__, data->bLSR);
+
+ tport->tp_lsr = data->bLSR;
+
+free_data:
+ kfree(data);
+ return status;
+}
+
+
+static int ti_get_serial_info(struct ti_port *tport,
+ struct serial_struct __user *ret_arg)
+{
+ struct usb_serial_port *port = tport->tp_port;
+ struct serial_struct ret_serial;
+
+ if (!ret_arg)
+ return -EFAULT;
+
+ memset(&ret_serial, 0, sizeof(ret_serial));
+
+ ret_serial.type = PORT_16550A;
+ ret_serial.line = port->serial->minor;
+ ret_serial.port = port->number - port->serial->minor;
+ ret_serial.flags = tport->tp_flags;
+ ret_serial.xmit_fifo_size = TI_WRITE_BUF_SIZE;
+ ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800;
+ ret_serial.closing_wait = tport->tp_closing_wait;
+
+ if (copy_to_user(ret_arg, &ret_serial, sizeof(*ret_arg)))
+ return -EFAULT;
+
+ return 0;
+}
+
+
+static int ti_set_serial_info(struct ti_port *tport,
+ struct serial_struct *new_arg)
+{
+ struct usb_serial_port *port = tport->tp_port;
+ struct serial_struct new_serial;
+
+ if (copy_from_user(&new_serial, new_arg, sizeof(new_serial)))
+ return -EFAULT;
+
+ tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
+ if (port->tty)
+ port->tty->low_latency =
+ (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ tport->tp_closing_wait = new_serial.closing_wait;
+
+ return 0;
+}
+
+
+static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
+{
+ struct async_icount *icount;
+ struct tty_struct *tty;
+ unsigned long flags;
+
+ dbg("%s - msr 0x%02X", __FUNCTION__, msr);
+
+ if (msr & TI_MSR_DELTA_MASK) {
+ spin_lock_irqsave(&tport->tp_lock, flags);
+ icount = &tport->tp_icount;
+ if (msr & TI_MSR_DELTA_CTS)
+ icount->cts++;
+ if (msr & TI_MSR_DELTA_DSR)
+ icount->dsr++;
+ if (msr & TI_MSR_DELTA_CD)
+ icount->dcd++;
+ if (msr & TI_MSR_DELTA_RI)
+ icount->rng++;
+ wake_up_interruptible(&tport->tp_msr_wait);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ }
+
+ tport->tp_msr = msr & TI_MSR_MASK;
+
+ /* handle CTS flow control */
+ tty = tport->tp_port->tty;
+ if (tty && C_CRTSCTS(tty)) {
+ if (msr & TI_MSR_CTS) {
+ tty->hw_stopped = 0;
+ tty_wakeup(tty);
+ } else {
+ tty->hw_stopped = 1;
+ }
+ }
+}
+
+
+static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush)
+{
+ struct ti_device *tdev = tport->tp_tdev;
+ struct usb_serial_port *port = tport->tp_port;
+ wait_queue_t wait;
+ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+
+ /* wait for data to drain from the buffer */
+ tdev->td_urb_error = 0;
+ init_waitqueue_entry(&wait, current);
+ add_wait_queue(&tport->tp_write_wait, &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (ti_buf_data_avail(tport->tp_write_buf) == 0
+ || timeout == 0 || signal_pending(current)
+ || tdev->td_urb_error
+ || !usb_get_intfdata(port->serial->interface)) /* disconnect */
+ break;
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ timeout = schedule_timeout(timeout);
+ spin_lock_irqsave(&tport->tp_lock, flags);
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&tport->tp_write_wait, &wait);
+
+ /* flush any remaining data in the buffer */
+ if (flush)
+ ti_buf_clear(tport->tp_write_buf);
+
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ /* wait for data to drain from the device */
+ /* wait for empty tx register, plus 20 ms */
+ timeout += jiffies;
+ tport->tp_lsr &= ~TI_LSR_TX_EMPTY;
+ while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
+ && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error
+ && usb_get_intfdata(port->serial->interface)) { /* not disconnected */
+ if (ti_get_lsr(tport))
+ break;
+ msleep_interruptible(20);
+ }
+}
+
+
+static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+
+ if (tport->tp_read_urb_state == TI_READ_URB_RUNNING)
+ tport->tp_read_urb_state = TI_READ_URB_STOPPING;
+
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+}
+
+
+static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty)
+{
+ struct urb *urb;
+ int status = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tport->tp_lock, flags);
+
+ if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) {
+ urb = tport->tp_port->read_urb;
+ urb->complete = ti_bulk_in_callback;
+ urb->context = tport;
+ urb->dev = tport->tp_port->serial->dev;
+ status = usb_submit_urb(urb, GFP_KERNEL);
+ }
+ tport->tp_read_urb_state = TI_READ_URB_RUNNING;
+
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ return status;
+}
+
+
+static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
+ __u16 moduleid, __u16 value, __u8 *data, int size)
+{
+ int status;
+
+ status = usb_control_msg(tdev->td_serial->dev,
+ usb_sndctrlpipe(tdev->td_serial->dev, 0), command,
+ (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
+ value, moduleid, data, size, HZ);
+
+ if (status == size)
+ status = 0;
+
+ if (status > 0)
+ status = -ECOMM;
+
+ return status;
+}
+
+
+static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
+ __u16 moduleid, __u16 value, __u8 *data, int size)
+{
+ int status;
+
+ status = usb_control_msg(tdev->td_serial->dev,
+ usb_rcvctrlpipe(tdev->td_serial->dev, 0), command,
+ (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN),
+ value, moduleid, data, size, HZ);
+
+ if (status == size)
+ status = 0;
+
+ if (status > 0)
+ status = -ECOMM;
+
+ return status;
+}
+
+
+static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
+ __u8 mask, __u8 byte)
+{
+ int status;
+ unsigned int size;
+ struct ti_write_data_bytes *data;
+ struct device *dev = &tdev->td_serial->dev->dev;
+
+ dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __FUNCTION__, addr, mask, byte);
+
+ size = sizeof(struct ti_write_data_bytes) + 2;
+ data = kmalloc(size, GFP_KERNEL);
+ if (!data) {
+ dev_err(dev, "%s - out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ data->bAddrType = TI_RW_DATA_ADDR_XDATA;
+ data->bDataType = TI_RW_DATA_BYTE;
+ data->bDataCounter = 1;
+ data->wBaseAddrHi = cpu_to_be16(addr>>16);
+ data->wBaseAddrLo = cpu_to_be16(addr);
+ data->bData[0] = mask;
+ data->bData[1] = byte;
+
+ status = ti_command_out_sync(tdev, TI_WRITE_DATA, TI_RAM_PORT, 0,
+ (__u8 *)data, size);
+
+ if (status < 0)
+ dev_err(dev, "%s - failed, %d\n", __FUNCTION__, status);
+
+ kfree(data);
+
+ return status;
+}
+
+
+static int ti_download_firmware(struct ti_device *tdev,
+ unsigned char *firmware, unsigned int firmware_size)
+{
+ int status = 0;
+ int buffer_size;
+ int pos;
+ int len;
+ int done;
+ __u8 cs = 0;
+ __u8 *buffer;
+ struct usb_device *dev = tdev->td_serial->dev;
+ struct ti_firmware_header *header;
+ unsigned int pipe = usb_sndbulkpipe(dev,
+ tdev->td_serial->port[0]->bulk_out_endpointAddress);
+
+
+ buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!buffer) {
+ dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ memcpy(buffer, firmware, firmware_size);
+ memset(buffer+firmware_size, 0xff, buffer_size-firmware_size);
+
+ for(pos = sizeof(struct ti_firmware_header); pos < buffer_size; pos++)
+ cs = (__u8)(cs + buffer[pos]);
+
+ header = (struct ti_firmware_header *)buffer;
+ header->wLength = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_firmware_header)));
+ header->bCheckSum = cs;
+
+ dbg("%s - downloading firmware", __FUNCTION__);
+ for (pos = 0; pos < buffer_size; pos += done) {
+ len = min(buffer_size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);
+ status = usb_bulk_msg(dev, pipe, buffer+pos, len, &done, HZ);
+ if (status)
+ break;
+ }
+
+ kfree(buffer);
+
+ if (status) {
+ dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __FUNCTION__, status);
+ return status;
+ }
+
+ dbg("%s - download successful", __FUNCTION__);
+
+ return 0;
+}
+
+
+/* Circular Buffer Functions */
+
+/*
+ * ti_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+
+static struct circ_buf *ti_buf_alloc(void)
+{
+ struct circ_buf *cb;
+
+ cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
+ if (cb == NULL)
+ return NULL;
+
+ cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL);
+ if (cb->buf == NULL) {
+ kfree(cb);
+ return NULL;
+ }
+
+ ti_buf_clear(cb);
+
+ return cb;
+}
+
+
+/*
+ * ti_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+
+static inline void ti_buf_free(struct circ_buf *cb)
+{
+ kfree(cb->buf);
+ kfree(cb);
+}
+
+
+/*
+ * ti_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+
+static inline void ti_buf_clear(struct circ_buf *cb)
+{
+ cb->head = cb->tail = 0;
+}
+
+
+/*
+ * ti_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+
+static inline int ti_buf_data_avail(struct circ_buf *cb)
+{
+ return CIRC_CNT(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+}
+
+
+/*
+ * ti_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+
+static inline int ti_buf_space_avail(struct circ_buf *cb)
+{
+ return CIRC_SPACE(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+}
+
+
+/*
+ * ti_buf_put
+ *
+ * Copy data data from a user buffer and put it into the circular buffer.
+ * Restrict to the amount of space available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static int ti_buf_put(struct circ_buf *cb, const char *buf, int count)
+{
+ int c, ret = 0;
+
+ while (1) {
+ c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
+ if (count < c)
+ c = count;
+ if (c <= 0)
+ break;
+ memcpy(cb->buf + cb->head, buf, c);
+ cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1);
+ buf += c;
+ count -= c;
+ ret += c;
+ }
+
+ return ret;
+}
+
+
+/*
+ * ti_buf_get
+ *
+ * Get data from the circular buffer and copy to the given buffer.
+ * Restrict to the amount of data available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static int ti_buf_get(struct circ_buf *cb, char *buf, int count)
+{
+ int c, ret = 0;
+
+ while (1) {
+ c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
+ if (count < c)
+ c = count;
+ if (c <= 0)
+ break;
+ memcpy(buf, cb->buf + cb->tail, c);
+ cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1);
+ buf += c;
+ count -= c;
+ ret += c;
+ }
+
+ return ret;
+}
diff -Nru a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_usb_3410_5052.h 2005-01-07 15:51:18 -08:00
@@ -0,0 +1,224 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 3410/5052 USB Serial Driver Header
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This driver is based on the Linux io_ti driver, which is
+ * Copyright (C) 2000-2002 Inside Out Networks
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman
+ *
+ * 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.
+ *
+ * For questions or problems with this driver, contact Texas Instruments
+ * technical support, or Al Borchers <[email protected]>, or
+ * Peter Berger <[email protected]>.
+ */
+
+#ifndef _TI_3410_5052_H_
+#define _TI_3410_5052_H_
+
+/* Configuration ids */
+#define TI_BOOT_CONFIG 1
+#define TI_ACTIVE_CONFIG 2
+
+/* Vendor and product ids */
+#define TI_VENDOR_ID 0x0451
+#define TI_3410_PRODUCT_ID 0x3410
+#define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */
+#define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */
+#define TI_5052_EEPROM_PRODUCT_ID 0x505A /* EEPROM, no firmware */
+#define TI_5052_FIRMWARE_PRODUCT_ID 0x505F /* firmware is running */
+
+/* Commands */
+#define TI_GET_VERSION 0x01
+#define TI_GET_PORT_STATUS 0x02
+#define TI_GET_PORT_DEV_INFO 0x03
+#define TI_GET_CONFIG 0x04
+#define TI_SET_CONFIG 0x05
+#define TI_OPEN_PORT 0x06
+#define TI_CLOSE_PORT 0x07
+#define TI_START_PORT 0x08
+#define TI_STOP_PORT 0x09
+#define TI_TEST_PORT 0x0A
+#define TI_PURGE_PORT 0x0B
+#define TI_RESET_EXT_DEVICE 0x0C
+#define TI_WRITE_DATA 0x80
+#define TI_READ_DATA 0x81
+#define TI_REQ_TYPE_CLASS 0x82
+
+/* Module identifiers */
+#define TI_I2C_PORT 0x01
+#define TI_IEEE1284_PORT 0x02
+#define TI_UART1_PORT 0x03
+#define TI_UART2_PORT 0x04
+#define TI_RAM_PORT 0x05
+
+/* Modem status */
+#define TI_MSR_DELTA_CTS 0x01
+#define TI_MSR_DELTA_DSR 0x02
+#define TI_MSR_DELTA_RI 0x04
+#define TI_MSR_DELTA_CD 0x08
+#define TI_MSR_CTS 0x10
+#define TI_MSR_DSR 0x20
+#define TI_MSR_RI 0x40
+#define TI_MSR_CD 0x80
+#define TI_MSR_DELTA_MASK 0x0F
+#define TI_MSR_MASK 0xF0
+
+/* Line status */
+#define TI_LSR_OVERRUN_ERROR 0x01
+#define TI_LSR_PARITY_ERROR 0x02
+#define TI_LSR_FRAMING_ERROR 0x04
+#define TI_LSR_BREAK 0x08
+#define TI_LSR_ERROR 0x0F
+#define TI_LSR_RX_FULL 0x10
+#define TI_LSR_TX_EMPTY 0x20
+
+/* Line control */
+#define TI_LCR_BREAK 0x40
+
+/* Modem control */
+#define TI_MCR_LOOP 0x04
+#define TI_MCR_DTR 0x10
+#define TI_MCR_RTS 0x20
+
+/* Mask settings */
+#define TI_UART_ENABLE_RTS_IN 0x0001
+#define TI_UART_DISABLE_RTS 0x0002
+#define TI_UART_ENABLE_PARITY_CHECKING 0x0008
+#define TI_UART_ENABLE_DSR_OUT 0x0010
+#define TI_UART_ENABLE_CTS_OUT 0x0020
+#define TI_UART_ENABLE_X_OUT 0x0040
+#define TI_UART_ENABLE_XA_OUT 0x0080
+#define TI_UART_ENABLE_X_IN 0x0100
+#define TI_UART_ENABLE_DTR_IN 0x0800
+#define TI_UART_DISABLE_DTR 0x1000
+#define TI_UART_ENABLE_MS_INTS 0x2000
+#define TI_UART_ENABLE_AUTO_START_DMA 0x4000
+
+/* Parity */
+#define TI_UART_NO_PARITY 0x00
+#define TI_UART_ODD_PARITY 0x01
+#define TI_UART_EVEN_PARITY 0x02
+#define TI_UART_MARK_PARITY 0x03
+#define TI_UART_SPACE_PARITY 0x04
+
+/* Stop bits */
+#define TI_UART_1_STOP_BITS 0x00
+#define TI_UART_1_5_STOP_BITS 0x01
+#define TI_UART_2_STOP_BITS 0x02
+
+/* Bits per character */
+#define TI_UART_5_DATA_BITS 0x00
+#define TI_UART_6_DATA_BITS 0x01
+#define TI_UART_7_DATA_BITS 0x02
+#define TI_UART_8_DATA_BITS 0x03
+
+/* 232/485 modes */
+#define TI_UART_232 0x00
+#define TI_UART_485_RECEIVER_DISABLED 0x01
+#define TI_UART_485_RECEIVER_ENABLED 0x02
+
+/* Pipe transfer mode and timeout */
+#define TI_PIPE_MODE_CONTINOUS 0x01
+#define TI_PIPE_MODE_MASK 0x03
+#define TI_PIPE_TIMEOUT_MASK 0x7C
+#define TI_PIPE_TIMEOUT_ENABLE 0x80
+
+/* Config struct */
+struct ti_uart_config {
+ __u16 wBaudRate;
+ __u16 wFlags;
+ __u8 bDataBits;
+ __u8 bParity;
+ __u8 bStopBits;
+ char cXon;
+ char cXoff;
+ __u8 bUartMode;
+} __attribute__((packed));
+
+/* Get port status */
+struct ti_port_status {
+ __u8 bCmdCode;
+ __u8 bModuleId;
+ __u8 bErrorCode;
+ __u8 bMSR;
+ __u8 bLSR;
+} __attribute__((packed));
+
+/* Purge modes */
+#define TI_PURGE_OUTPUT 0x00
+#define TI_PURGE_INPUT 0x80
+
+/* Read/Write data */
+#define TI_RW_DATA_ADDR_SFR 0x10
+#define TI_RW_DATA_ADDR_IDATA 0x20
+#define TI_RW_DATA_ADDR_XDATA 0x30
+#define TI_RW_DATA_ADDR_CODE 0x40
+#define TI_RW_DATA_ADDR_GPIO 0x50
+#define TI_RW_DATA_ADDR_I2C 0x60
+#define TI_RW_DATA_ADDR_FLASH 0x70
+#define TI_RW_DATA_ADDR_DSP 0x80
+
+#define TI_RW_DATA_UNSPECIFIED 0x00
+#define TI_RW_DATA_BYTE 0x01
+#define TI_RW_DATA_WORD 0x02
+#define TI_RW_DATA_DOUBLE_WORD 0x04
+
+struct ti_write_data_bytes {
+ __u8 bAddrType;
+ __u8 bDataType;
+ __u8 bDataCounter;
+ __be16 wBaseAddrHi;
+ __be16 wBaseAddrLo;
+ __u8 bData[0];
+} __attribute__((packed));
+
+struct ti_read_data_request {
+ __u8 bAddrType;
+ __u8 bDataType;
+ __u8 bDataCounter;
+ __be16 wBaseAddrHi;
+ __be16 wBaseAddrLo;
+} __attribute__((packed));
+
+struct ti_read_data_bytes {
+ __u8 bCmdCode;
+ __u8 bModuleId;
+ __u8 bErrorCode;
+ __u8 bData[0];
+} __attribute__((packed));
+
+/* Interrupt struct */
+struct ti_interrupt {
+ __u8 bICode;
+ __u8 bIInfo;
+} __attribute__((packed));
+
+/* Interrupt codes */
+#define TI_GET_PORT_FROM_CODE(c) (((c) >> 4) - 3)
+#define TI_GET_FUNC_FROM_CODE(c) ((c) & 0x0f)
+#define TI_CODE_HARDWARE_ERROR 0xFF
+#define TI_CODE_DATA_ERROR 0x03
+#define TI_CODE_MODEM_STATUS 0x04
+
+/* Download firmware max packet size */
+#define TI_DOWNLOAD_MAX_PACKET_SIZE 64
+
+/* Firmware image header */
+struct ti_firmware_header {
+ __le16 wLength;
+ __u8 bCheckSum;
+} __attribute__((packed));
+
+/* UART addresses */
+#define TI_UART1_BASE_ADDR 0xFFA0 /* UART 1 base address */
+#define TI_UART2_BASE_ADDR 0xFFB0 /* UART 2 base address */
+#define TI_UART_OFFSET_LCR 0x0002 /* UART MCR register offset */
+#define TI_UART_OFFSET_MCR 0x0004 /* UART MCR register offset */
+
+#endif /* _TI_3410_5052_H_ */
ChangeSet 1.1938.444.17, 2004/12/21 10:01:15-08:00, [email protected]
USB: explicitly mark the endianness of some visor data fields.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/serial/visor.c | 4 +---
drivers/usb/serial/visor.h | 6 +++---
2 files changed, 4 insertions(+), 6 deletions(-)
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c 2005-01-07 15:41:55 -08:00
+++ b/drivers/usb/serial/visor.c 2005-01-07 15:41:55 -08:00
@@ -734,9 +734,7 @@
if (retval == sizeof(*connection_info)) {
connection_info = (struct visor_connection_info *)transfer_buffer;
- le16_to_cpus(&connection_info->num_ports);
- num_ports = connection_info->num_ports;
-
+ num_ports = le16_to_cpu(connection_info->num_ports);
for (i = 0; i < num_ports; ++i) {
switch (connection_info->connections[i].port_function_id) {
case VISOR_FUNCTION_GENERIC:
diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
--- a/drivers/usb/serial/visor.h 2005-01-07 15:41:55 -08:00
+++ b/drivers/usb/serial/visor.h 2005-01-07 15:41:55 -08:00
@@ -89,7 +89,7 @@
* VISOR_GET_CONNECTION_INFORMATION returns data in the following format
****************************************************************************/
struct visor_connection_info {
- __u16 num_ports;
+ __le16 num_ports;
struct {
__u8 port_function_id;
__u8 port;
@@ -135,12 +135,12 @@
struct palm_ext_connection_info {
__u8 num_ports;
__u8 endpoint_numbers_different;
- __u16 reserved1;
+ __le16 reserved1;
struct {
__u32 port_function_id;
__u8 port;
__u8 end_point_info;
- __u16 reserved;
+ __le16 reserved;
} connections[2];
};
ChangeSet 1.1938.444.24, 2004/12/21 11:20:03-08:00, [email protected]
[PATCH] USB: additional device id for kaweth driver
thanks to Magnus an additional device id.
Signed-Off-By: Oliver Neukum <[email protected]>
drivers/usb/net/kaweth.c | 1 +
1 files changed, 1 insertion(+)
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c 2005-01-07 15:41:01 -08:00
+++ b/drivers/usb/net/kaweth.c 2005-01-07 15:41:01 -08:00
@@ -160,6 +160,7 @@
{ USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */
{ USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */
{ USB_DEVICE(0x1485, 0x0001) }, /* Silicom U2E */
+ { USB_DEVICE(0x1485, 0x0002) }, /* Psion Dacom Gold Port Ethernet */
{ USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
{ USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
{ USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
ChangeSet 1.1938.444.21, 2004/12/21 10:36:52-08:00, [email protected]
[PATCH] module sysfs: module parameters reimplemented using attr group
Reimplement parameter attributes using attribute group.
This makes more sense, for, while they reside in a separate
subdirectory, they belong to the ownig module and their
lifetime exactly equals the lifetime of the owning module,
and it's simpler.
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
include/linux/module.h | 4 -
kernel/params.c | 179 ++++++++++++++-----------------------------------
2 files changed, 56 insertions(+), 127 deletions(-)
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h 2005-01-07 15:41:24 -08:00
+++ b/include/linux/module.h 2005-01-07 15:41:24 -08:00
@@ -238,7 +238,7 @@
struct module_sect_attr attrs[0];
};
-struct param_kobject;
+struct module_param_attrs;
struct module
{
@@ -252,7 +252,7 @@
/* Sysfs stuff. */
struct module_kobject mkobj;
- struct param_kobject *params_kobject;
+ struct module_param_attrs *param_attrs;
/* Exported symbols */
const struct kernel_symbol *syms;
diff -Nru a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c 2005-01-07 15:41:24 -08:00
+++ b/kernel/params.c 2005-01-07 15:41:24 -08:00
@@ -357,26 +357,23 @@
struct param_attribute
{
- struct attribute attr;
+ struct module_attribute mattr;
struct kernel_param *param;
};
-struct param_kobject
+struct module_param_attrs
{
- struct kobject kobj;
-
- unsigned int num_attributes;
- struct param_attribute attr[0];
+ struct attribute_group grp;
+ struct param_attribute attrs[0];
};
-#define to_param_attr(n) container_of(n, struct param_attribute, attr);
+#define to_param_attr(n) container_of(n, struct param_attribute, mattr);
-static ssize_t param_attr_show(struct kobject *kobj,
- struct attribute *attr,
- char *buf)
+static ssize_t param_attr_show(struct module_attribute *mattr,
+ struct module *mod, char *buf)
{
int count;
- struct param_attribute *attribute = to_param_attr(attr);
+ struct param_attribute *attribute = to_param_attr(mattr);
if (!attribute->param->get)
return -EPERM;
@@ -390,12 +387,12 @@
}
/* sysfs always hands a nul-terminated string in buf. We rely on that. */
-static ssize_t param_attr_store(struct kobject *kobj,
- struct attribute *attr,
+static ssize_t param_attr_store(struct module_attribute *mattr,
+ struct module *owner,
const char *buf, size_t len)
{
int err;
- struct param_attribute *attribute = to_param_attr(attr);
+ struct param_attribute *attribute = to_param_attr(mattr);
if (!attribute->param->set)
return -EPERM;
@@ -406,27 +403,6 @@
return err;
}
-
-static struct sysfs_ops param_sysfs_ops = {
- .show = param_attr_show,
- .store = param_attr_store,
-};
-
-static void param_kobj_release(struct kobject *kobj)
-{
- kfree(container_of(kobj, struct param_kobject, kobj));
-}
-
-static struct kobj_type param_ktype = {
- .sysfs_ops = ¶m_sysfs_ops,
- .release = ¶m_kobj_release,
-};
-
-static struct kset param_kset = {
- .subsys = &module_subsys,
- .ktype = ¶m_ktype,
-};
-
#ifdef CONFIG_MODULES
#define __modinit
#else
@@ -434,54 +410,6 @@
#endif
/*
- * param_add_attribute - actually adds an parameter to sysfs
- * @mod: owner of parameter
- * @pk: param_kobject the attribute shall be assigned to.
- * One per module, one per KBUILD_MODNAME.
- * @kp: kernel_param to be added
- * @skip: offset where the parameter name start in kp->name.
- * Needed for built-in modules
- *
- * Fill in data into appropriate &pk->attr[], and create sysfs file.
- */
-static __modinit int param_add_attribute(struct module *mod,
- struct param_kobject *pk,
- struct kernel_param *kp,
- unsigned int skip)
-{
- struct param_attribute *a;
- int err;
-
- a = &pk->attr[pk->num_attributes];
- a->attr.name = (char *) &kp->name[skip];
- a->attr.owner = mod;
- a->attr.mode = kp->perm;
- a->param = kp;
- err = sysfs_create_file(&pk->kobj, &a->attr);
- if (!err)
- pk->num_attributes++;
- return err;
-}
-
-/*
- * param_sysfs_remove - remove sysfs support for one module or KBUILD_MODNAME
- * @pk: struct param_kobject which is to be removed
- *
- * Called when an error in registration occurs or a module is removed
- * from the system.
- */
-static __modinit void param_sysfs_remove(struct param_kobject *pk)
-{
- unsigned int i;
- for (i = 0; i < pk->num_attributes; i++)
- sysfs_remove_file(&pk->kobj,&pk->attr[i].attr);
-
- /* Calls param_kobj_release */
- kobject_unregister(&pk->kobj);
-}
-
-
-/*
* param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
* @mk: struct module_kobject (contains parent kobject)
* @kparam: array of struct kernel_param, the actual parameter definitions
@@ -492,15 +420,17 @@
* in sysfs. A pointer to the param_kobject is returned on success,
* NULL if there's no parameter to export, or other ERR_PTR(err).
*/
-static __modinit struct param_kobject *
+static __modinit struct module_param_attrs *
param_sysfs_setup(struct module_kobject *mk,
struct kernel_param *kparam,
unsigned int num_params,
unsigned int name_skip)
{
- struct param_kobject *pk;
+ struct module_param_attrs *mp;
unsigned int valid_attrs = 0;
- unsigned int i;
+ unsigned int i, size[2];
+ struct param_attribute *pattr;
+ struct attribute **gattr;
int err;
for (i=0; i<num_params; i++) {
@@ -511,42 +441,39 @@
if (!valid_attrs)
return NULL;
- pk = kmalloc(sizeof(struct param_kobject)
- + sizeof(struct param_attribute) * valid_attrs,
- GFP_KERNEL);
- if (!pk)
+ size[0] = ALIGN(sizeof(*mp) +
+ valid_attrs * sizeof(mp->attrs[0]),
+ sizeof(mp->grp.attrs[0]));
+ size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]);
+
+ mp = kmalloc(size[0] + size[1], GFP_KERNEL);
+ if (!mp)
return ERR_PTR(-ENOMEM);
- memset(pk, 0, sizeof(struct param_kobject)
- + sizeof(struct param_attribute) * valid_attrs);
- err = kobject_set_name(&pk->kobj, "parameters");
- if (err)
- goto out;
-
- pk->kobj.kset = ¶m_kset;
- pk->kobj.parent = &mk->kobj;
- err = kobject_register(&pk->kobj);
- if (err)
- goto out;
+ mp->grp.name = "parameters";
+ mp->grp.attrs = (void *)mp + size[0];
+ pattr = &mp->attrs[0];
+ gattr = &mp->grp.attrs[0];
for (i = 0; i < num_params; i++) {
- if (kparam[i].perm) {
- err = param_add_attribute(mk->mod, pk,
- &kparam[i], name_skip);
- if (err)
- goto out_unreg;
+ struct kernel_param *kp = &kparam[i];
+ if (kp->perm) {
+ pattr->param = kp;
+ pattr->mattr.show = param_attr_show;
+ pattr->mattr.store = param_attr_store;
+ pattr->mattr.attr.name = (char *)&kp->name[name_skip];
+ pattr->mattr.attr.owner = mk->mod;
+ pattr->mattr.attr.mode = kp->perm;
+ *(gattr++) = &(pattr++)->mattr.attr;
}
}
+ *gattr = NULL;
- return pk;
-
-out_unreg:
- param_sysfs_remove(pk);
- return ERR_PTR(err);
-
-out:
- kfree(pk);
- return ERR_PTR(err);
+ if ((err = sysfs_create_group(&mk->kobj, &mp->grp))) {
+ kfree(mp);
+ return ERR_PTR(err);
+ }
+ return mp;
}
@@ -565,13 +492,13 @@
struct kernel_param *kparam,
unsigned int num_params)
{
- struct param_kobject *pk;
+ struct module_param_attrs *mp;
- pk = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0);
- if (IS_ERR(pk))
- return PTR_ERR(pk);
+ mp = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0);
+ if (IS_ERR(mp))
+ return PTR_ERR(mp);
- mod->params_kobject = pk;
+ mod->param_attrs = mp;
return 0;
}
@@ -584,9 +511,13 @@
*/
void module_param_sysfs_remove(struct module *mod)
{
- if (mod->params_kobject) {
- param_sysfs_remove(mod->params_kobject);
- mod->params_kobject = NULL;
+ if (mod->param_attrs) {
+ sysfs_remove_group(&mod->mkobj.kobj,
+ &mod->param_attrs->grp);
+ /* We are positive that no one is using any param
+ * attrs at this point. Deallocate immediately. */
+ kfree(mod->param_attrs);
+ mod->param_attrs = NULL;
}
}
#endif
@@ -724,8 +655,6 @@
static int __init param_sysfs_init(void)
{
subsystem_register(&module_subsys);
- kobject_set_name(¶m_kset.kobj, "parameters");
- kset_init(¶m_kset);
param_sysfs_builtin();
ChangeSet 1.1938.444.12, 2004/12/20 15:17:05-08:00, [email protected]
Merge kroah.com:/home/greg/linux/BK/driver-2.6
into kroah.com:/home/greg/linux/BK/usb-2.6
drivers/usb/host/uhci-hcd.c | 60 ++++++++++++++------------------------------
drivers/usb/host/uhci-hcd.h | 6 +---
2 files changed, 22 insertions(+), 44 deletions(-)
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c 2005-01-07 15:42:36 -08:00
+++ b/drivers/usb/host/uhci-hcd.c 2005-01-07 15:42:36 -08:00
@@ -46,7 +46,7 @@
#include <linux/unistd.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
#include <linux/pm.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
@@ -74,7 +74,7 @@
* debug = 0, no debugging messages
* debug = 1, dump failed URB's except for stalls
* debug = 2, dump all failed URB's (including stalls)
- * show all queues in /proc/driver/uhci/[pci_addr]
+ * show all queues in /debug/uhci/[pci_addr]
* debug = 3, show all TD's in URB's when dumping
*/
#ifdef DEBUG
@@ -1929,12 +1929,10 @@
uhci->fl = NULL;
}
-#ifdef CONFIG_PROC_FS
- if (uhci->proc_entry) {
- remove_proc_entry(uhci->hcd.self.bus_name, uhci_proc_root);
- uhci->proc_entry = NULL;
+ if (uhci->dentry) {
+ debugfs_remove(uhci->dentry);
+ uhci->dentry = NULL;
}
-#endif
}
static int uhci_reset(struct usb_hcd *hcd)
@@ -1974,25 +1972,17 @@
unsigned io_size;
dma_addr_t dma_handle;
struct usb_device *udev;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *ent;
-#endif
+ struct dentry *dentry;
io_size = pci_resource_len(to_pci_dev(uhci_dev(uhci)), hcd->region);
-#ifdef CONFIG_PROC_FS
- ent = create_proc_entry(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
- if (!ent) {
- dev_err(uhci_dev(uhci), "couldn't create uhci proc entry\n");
+ dentry = debugfs_create_file(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, &uhci_debug_operations);
+ if (!dentry) {
+ dev_err(uhci_dev(uhci), "couldn't create uhci debugfs entry\n");
retval = -ENOMEM;
- goto err_create_proc_entry;
+ goto err_create_debug_entry;
}
-
- ent->data = uhci;
- ent->proc_fops = &uhci_proc_operations;
- ent->size = 0;
- uhci->proc_entry = ent;
-#endif
+ uhci->dentry = dentry;
uhci->fsbr = 0;
uhci->fsbrtimeout = 0;
@@ -2194,13 +2184,10 @@
uhci->fl = NULL;
err_alloc_fl:
-#ifdef CONFIG_PROC_FS
- remove_proc_entry(hcd->self.bus_name, uhci_proc_root);
- uhci->proc_entry = NULL;
-
-err_create_proc_entry:
-#endif
+ debugfs_remove(uhci->dentry);
+ uhci->dentry = NULL;
+err_create_debug_entry:
return retval;
}
@@ -2363,11 +2350,9 @@
goto errbuf_failed;
}
-#ifdef CONFIG_PROC_FS
- uhci_proc_root = create_proc_entry("driver/uhci", S_IFDIR, NULL);
- if (!uhci_proc_root)
- goto proc_failed;
-#endif
+ uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
+ if (!uhci_debugfs_root)
+ goto debug_failed;
uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
sizeof(struct urb_priv), 0, 0, NULL, NULL);
@@ -2385,12 +2370,9 @@
warn("not all urb_priv's were freed!");
up_failed:
+ debugfs_remove(uhci_debugfs_root);
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("driver/uhci", NULL);
-
-proc_failed:
-#endif
+debug_failed:
if (errbuf)
kfree(errbuf);
@@ -2406,9 +2388,7 @@
if (kmem_cache_destroy(uhci_up_cachep))
warn("not all urb_priv's were freed!");
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("driver/uhci", NULL);
-#endif
+ debugfs_remove(uhci_debugfs_root);
if (errbuf)
kfree(errbuf);
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h 2005-01-07 15:42:36 -08:00
+++ b/drivers/usb/host/uhci-hcd.h 2005-01-07 15:42:36 -08:00
@@ -322,10 +322,8 @@
*/
struct uhci_hcd {
-#ifdef CONFIG_PROC_FS
- /* procfs */
- struct proc_dir_entry *proc_entry;
-#endif
+ /* debugfs */
+ struct dentry *dentry;
/* Grabbed from PCI */
unsigned long io_addr;
ChangeSet 1.1938.444.30, 2004/12/21 22:43:19-08:00, [email protected]
debugfs: add /sys/kernel/debug mount point for people to mount debugfs on.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
fs/debugfs/inode.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletion(-)
diff -Nru a/fs/debugfs/inode.c b/fs/debugfs/inode.c
--- a/fs/debugfs/inode.c 2005-01-07 15:40:16 -08:00
+++ b/fs/debugfs/inode.c 2005-01-07 15:40:16 -08:00
@@ -298,15 +298,28 @@
}
EXPORT_SYMBOL_GPL(debugfs_remove);
+static decl_subsys(debug, NULL, NULL);
+
static int __init debugfs_init(void)
{
- return register_filesystem(&debug_fs_type);
+ int retval;
+
+ kset_set_kset_s(&debug_subsys, kernel_subsys);
+ retval = subsystem_register(&debug_subsys);
+ if (retval)
+ return retval;
+
+ retval = register_filesystem(&debug_fs_type);
+ if (retval)
+ subsystem_unregister(&debug_subsys);
+ return retval;
}
static void __exit debugfs_exit(void)
{
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
unregister_filesystem(&debug_fs_type);
+ subsystem_unregister(&debug_subsys);
}
core_initcall(debugfs_init);
ChangeSet 1.1938.446.6, 2004/12/15 14:26:09-08:00, [email protected]
[PATCH] USB Storage: support 'bulk32' devices
This patch implements support for what we call "bulk32" devices. These are
devices that use the BBB transport mechanism with the slight modification
that the CBW is padded to 32 bytes (instead of the standard 31 bytes).
Signed-off-by: Theodore Kilgore <[email protected]>
Signed-off-by: Phil Dibowitz <[email protected]>
Signed-off-by: Matthew Dharm <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/storage/transport.c | 9 ++++++++-
drivers/usb/storage/unusual_devs.h | 24 ++++++++++++++++++++++++
drivers/usb/storage/usb.h | 1 +
3 files changed, 33 insertions(+), 1 deletion(-)
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c 2005-01-07 15:50:46 -08:00
+++ b/drivers/usb/storage/transport.c 2005-01-07 15:50:46 -08:00
@@ -954,6 +954,13 @@
int result;
int fake_sense = 0;
unsigned int cswlen;
+ unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
+
+ /* Take care of BULK32 devices; set extra byte to 0 */
+ if ( unlikely(us->flags & US_FL_BULK32)) {
+ cbwlen = 32;
+ us->iobuf[31] = 0;
+ }
/* set up the command wrapper */
bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -976,7 +983,7 @@
(bcb->Lun >> 4), (bcb->Lun & 0x0F),
bcb->Length);
result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
- bcb, US_BULK_CB_WRAP_LEN, NULL);
+ bcb, cbwlen, NULL);
US_DEBUGP("Bulk command transfer result=%d\n", result);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h 2005-01-07 15:50:46 -08:00
+++ b/drivers/usb/storage/unusual_devs.h 2005-01-07 15:50:46 -08:00
@@ -249,6 +249,17 @@
"CD-RW Device",
US_SC_8020, US_PR_CB, NULL, 0),
+/* Entry and supporting patch by Theodore Kilgore <[email protected]>.
+ * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
+ * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
+ */
+
+UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100,
+ "Kobian Mercury",
+ "Binocam DCB-132",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_BULK32),
+
/* Reported by Bob Sass <[email protected]> -- only rev 1.33 tested */
UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133,
"Belkin",
@@ -714,6 +725,19 @@
"Digimax 410",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY),
+
+/* Entry and supporting patch by Theodore Kilgore <[email protected]>.
+ * Flag will support Bulk devices which use a standards-violating 32-byte
+ * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
+ * Grandtech GT892x chip, which request "Proprietary SCSI Bulk" support.
+ */
+
+UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110,
+ "Grandtech",
+ "DC2MEGA",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_BULK32),
+
/* Aiptek PocketCAM 3Mega
* Nicolas DUPEUX <[email protected]>
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h 2005-01-07 15:50:46 -08:00
+++ b/drivers/usb/storage/usb.h 2005-01-07 15:50:46 -08:00
@@ -74,6 +74,7 @@
#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs faking */
#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */
#define US_FL_IGNORE_RESIDUE 0x00000100 /* reported residue is wrong */
+#define US_FL_BULK32 0x00000200 /* Uses 32-byte CBW length */
/* Dynamic flag definitions: used in set_bit() etc. */
#define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */
ChangeSet 1.1938.439.56, 2005/01/07 10:29:46-08:00, [email protected]
[PATCH] USB: ehci "hc died" on startup (chip bug workaround)
This fixes OSDL bugid #3056 for at least some users, where the EHCI
driver gets a "fatal error" IRQ on startup ... only on certain boards,
starting with the 2.6.6 or 2.6.7 kernels. These IRQs normally indicate
that an invalid DMA address got passed to the controller, or something
equally nasty and unrecoverable.
But it turns out that some of these controllers (at least ALI and Intel)
are lying. They're issuing these IRQs without stopping, contrary to the
EHCI spec ... so these IRQs can be recovered from. Thanks to Christian
Iversen for noticing that his ALI controller would continue operating,
which was the first real break in this annoying case.
This patch tests for these bogus IRQs, and ignores them ... working around
what's clearly a chip bug. It's not clear why we started triggering that
bug, but at least EHCI is now usable on boards exhibiting this problem.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ehci-hcd.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c 2005-01-07 15:34:45 -08:00
+++ b/drivers/usb/host/ehci-hcd.c 2005-01-07 15:34:45 -08:00
@@ -883,13 +883,20 @@
/* PCI errors [4.15.2.4] */
if (unlikely ((status & STS_FATAL) != 0)) {
- ehci_err (ehci, "fatal error\n");
+ /* bogus "fatal" IRQs appear on some chips... why? */
+ status = readl (&ehci->regs->status);
+ dbg_cmd (ehci, "fatal", readl (&ehci->regs->command));
+ dbg_status (ehci, "fatal", status);
+ if (status & STS_HALT) {
+ ehci_err (ehci, "fatal error\n");
dead:
- ehci_reset (ehci);
- /* generic layer kills/unlinks all urbs, then
- * uses ehci_stop to clean up the rest
- */
- bh = 1;
+ ehci_reset (ehci);
+ writel (0, &ehci->regs->configured_flag);
+ /* generic layer kills/unlinks all urbs, then
+ * uses ehci_stop to clean up the rest
+ */
+ bh = 1;
+ }
}
if (bh)
ChangeSet 1.1938.444.31, 2004/12/22 09:51:50-08:00, [email protected]
[PATCH] usb atm: macro consolidation, fixes debugging problem
Hi Greg, the recent reorganisation of the speedtouch driver broke the logic
that turns on debugging output in speedtch.c and usb_atm.c when DEBUG or
CONFIG_USB_DEBUG is set. This patch fixes things up, and moves duplicated
debugging code into the header file.
Signed-off-by: Duncan Sands <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/atm/speedtch.c | 20 --------------------
drivers/usb/atm/usb_atm.c | 17 -----------------
drivers/usb/atm/usb_atm.h | 19 ++++++++++++++++++-
3 files changed, 18 insertions(+), 38 deletions(-)
diff -Nru a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
--- a/drivers/usb/atm/speedtch.c 2005-01-07 15:40:08 -08:00
+++ b/drivers/usb/atm/speedtch.c 2005-01-07 15:40:08 -08:00
@@ -44,28 +44,8 @@
#include "usb_atm.h"
-/*
-#define DEBUG
-#define VERBOSE_DEBUG
-*/
-
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-# define DEBUG
-#endif
-
-#include <linux/usb.h>
-
#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
# define USE_FW_LOADER
-#endif
-
-#ifdef VERBOSE_DEBUG
-static int udsl_print_packet(const unsigned char *data, int len);
-#define PACKETDEBUG(arg...) udsl_print_packet (arg)
-#define vdbg(arg...) dbg (arg)
-#else
-#define PACKETDEBUG(arg...)
-#define vdbg(arg...)
#endif
#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <[email protected]>"
diff -Nru a/drivers/usb/atm/usb_atm.c b/drivers/usb/atm/usb_atm.c
--- a/drivers/usb/atm/usb_atm.c 2005-01-07 15:40:08 -08:00
+++ b/drivers/usb/atm/usb_atm.c 2005-01-07 15:40:08 -08:00
@@ -83,23 +83,6 @@
#include "usb_atm.h"
-/*
-#define DEBUG
-#define VERBOSE_DEBUG
-*/
-
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-# define DEBUG
-#endif
-
-#include <linux/usb.h>
-
-#ifdef DEBUG
-#define UDSL_ASSERT(x) BUG_ON(!(x))
-#else
-#define UDSL_ASSERT(x) do { if (!(x)) warn("failed assertion '" #x "' at line %d", __LINE__); } while(0)
-#endif
-
#ifdef VERBOSE_DEBUG
static int udsl_print_packet(const unsigned char *data, int len);
#define PACKETDEBUG(arg...) udsl_print_packet (arg)
diff -Nru a/drivers/usb/atm/usb_atm.h b/drivers/usb/atm/usb_atm.h
--- a/drivers/usb/atm/usb_atm.h 2005-01-07 15:40:08 -08:00
+++ b/drivers/usb/atm/usb_atm.h 2005-01-07 15:40:08 -08:00
@@ -21,12 +21,29 @@
*
******************************************************************************/
+#include <linux/config.h>
#include <linux/list.h>
-#include <linux/usb.h>
#include <linux/kref.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <asm/semaphore.h>
+
+/*
+#define DEBUG
+#define VERBOSE_DEBUG
+*/
+
+#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
+# define DEBUG
+#endif
+
+#include <linux/usb.h>
+
+#ifdef DEBUG
+#define UDSL_ASSERT(x) BUG_ON(!(x))
+#else
+#define UDSL_ASSERT(x) do { if (!(x)) warn("failed assertion '" #x "' at line %d", __LINE__); } while(0)
+#endif
#define UDSL_MAX_RCV_URBS 4
#define UDSL_MAX_SND_URBS 4
ChangeSet 1.1938.444.25, 2004/12/21 11:20:39-08:00, [email protected]
[PATCH] USB: ohci build tweaks
Resolves some build glitches that snuck into OHCI.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/ohci-hcd.c | 13 ++-----------
1 files changed, 2 insertions(+), 11 deletions(-)
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c 2005-01-07 15:40:54 -08:00
+++ b/drivers/usb/host/ohci-hcd.c 2005-01-07 15:40:54 -08:00
@@ -416,7 +416,6 @@
static int ohci_init (struct ohci_hcd *ohci)
{
- u32 temp;
int ret;
disable (ohci);
@@ -427,6 +426,8 @@
/* SMM owns the HC? not for long! */
if (!no_handshake && ohci_readl (ohci,
&ohci->regs->control) & OHCI_CTRL_IR) {
+ u32 temp;
+
ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
/* this timeout is arbitrary. we make it long, so systems
@@ -902,14 +903,4 @@
|| defined (CONFIG_PXA27x) \
)
#error "missing bus glue for ohci-hcd"
-#endif
-
-#if !defined(HAVE_HNP) && defined(CONFIG_USB_OTG)
-
-#warning non-OTG configuration, too many HCDs
-
-static void start_hnp(struct ohci_hcd *ohci)
-{
- /* "can't happen" */
-}
#endif
ChangeSet 1.1938.439.43, 2004/12/22 15:48:48-08:00, [email protected]
Merge kroah.com:/home/greg/linux/BK/bleed-2.6
into kroah.com:/home/greg/linux/BK/usb-2.6
MAINTAINERS | 6 ++++++
drivers/usb/core/devio.c | 13 ++++++-------
drivers/usb/host/ehci-hub.c | 12 ++++++------
drivers/usb/host/ohci-hub.c | 2 +-
4 files changed, 19 insertions(+), 14 deletions(-)
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS 2005-01-07 15:39:45 -08:00
+++ b/MAINTAINERS 2005-01-07 15:39:45 -08:00
@@ -328,6 +328,12 @@
W: http://julien.lerouge.free.fr
S: Maintained
+ATA OVER ETHERNET DRIVER
+P: Ed L. Cashin
+M: [email protected]
+W: http://www.coraid.com/support/linux
+S: Supported
+
ATM
P: Chas Williams
M: [email protected]
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c 2005-01-07 15:39:45 -08:00
+++ b/drivers/usb/core/devio.c 2005-01-07 15:39:45 -08:00
@@ -523,13 +523,12 @@
usb_lock_device(dev);
list_del_init(&ps->list);
-
- if (connected(dev)) {
- for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed); ifnum++)
- if (test_bit(ifnum, &ps->ifclaimed))
- releaseintf(ps, ifnum);
- destroy_all_async(ps);
+ for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
+ ifnum++) {
+ if (test_bit(ifnum, &ps->ifclaimed))
+ releaseintf(ps, ifnum);
}
+ destroy_all_async(ps);
usb_unlock_device(dev);
usb_put_dev(dev);
ps->dev = NULL;
@@ -1034,7 +1033,7 @@
int ret;
add_wait_queue(&ps->wait, &wait);
- while (connected(dev)) {
+ for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
if ((as = async_getcompleted(ps)))
break;
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c 2005-01-07 15:39:45 -08:00
+++ b/drivers/usb/host/ehci-hub.c 2005-01-07 15:39:45 -08:00
@@ -44,7 +44,7 @@
/* stop schedules, clean any completed work */
if (HCD_IS_RUNNING(hcd->state)) {
ehci_quiesce (ehci);
- ehci->hcd.state = USB_STATE_QUIESCING;
+ hcd->state = USB_STATE_QUIESCING;
}
ehci->command = readl (&ehci->regs->command);
if (ehci->reclaim)
@@ -59,7 +59,7 @@
if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
t2 |= PORT_SUSPEND;
- if (ehci->hcd.remote_wakeup)
+ if (hcd->remote_wakeup)
t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
else
t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -73,7 +73,7 @@
/* turn off now-idle HC */
ehci_halt (ehci);
- ehci->hcd.state = HCD_STATE_SUSPENDED;
+ hcd->state = HCD_STATE_SUSPENDED;
ehci->next_statechange = jiffies + msecs_to_jiffies(10);
spin_unlock_irq (&ehci->lock);
@@ -145,7 +145,7 @@
}
ehci->next_statechange = jiffies + msecs_to_jiffies(5);
- ehci->hcd.state = USB_STATE_RUNNING;
+ hcd->state = USB_STATE_RUNNING;
/* Now we can safely re-enable irqs */
if (intr_enable)
@@ -212,7 +212,7 @@
unsigned long flags;
/* if !USB_SUSPEND, root hub timers won't get shut down ... */
- if (!HCD_IS_RUNNING(ehci->hcd.state))
+ if (!HCD_IS_RUNNING(hcd->state))
return 0;
/* init status to no-changes */
@@ -499,7 +499,7 @@
if ((temp & PORT_PE) == 0
|| (temp & PORT_RESET) != 0)
goto error;
- if (ehci->hcd.remote_wakeup)
+ if (hcd->remote_wakeup)
temp |= PORT_WAKE_BITS;
writel (temp | PORT_SUSPEND,
&ehci->regs->port_status [wIndex]);
diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c 2005-01-07 15:39:45 -08:00
+++ b/drivers/usb/host/ohci-hub.c 2005-01-07 15:39:45 -08:00
@@ -304,7 +304,7 @@
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports, i, changed = 0, length = 1;
- int can_suspend = 1;
+ int can_suspend = hcd->can_wakeup;
unsigned long flags;
spin_lock_irqsave (&ohci->lock, flags);
ChangeSet 1.1938.444.15, 2004/12/20 17:15:36-08:00, [email protected]
USB: change wMaxPacketSize field in struct usb_config_descriptor to be __le16
Yet another step in the quest to get all USB data structures to be native
endian.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
arch/mips/au1000/common/usbdev.c | 2 -
drivers/bluetooth/bfusb.c | 2 -
drivers/bluetooth/hci_usb.c | 10 +++----
drivers/char/watchdog/pcwd_usb.c | 2 -
drivers/isdn/hisax/hfc_usb.c | 8 ++---
drivers/isdn/hisax/st5481_b.c | 2 -
drivers/isdn/hisax/st5481_d.c | 2 -
drivers/isdn/hisax/st5481_usb.c | 4 +-
drivers/media/dvb/b2c2/b2c2-usb-core.c | 2 -
drivers/net/irda/irda-usb.c | 2 -
drivers/usb/class/audio.c | 2 -
drivers/usb/class/bluetty.c | 6 ++--
drivers/usb/class/cdc-acm.c | 6 ++--
drivers/usb/core/config.c | 1
drivers/usb/core/devices.c | 4 +-
drivers/usb/core/hcd.c | 6 ++--
drivers/usb/core/hub.c | 10 +++----
drivers/usb/gadget/dummy_hcd.c | 4 +-
drivers/usb/gadget/file_storage.c | 2 -
drivers/usb/host/hc_crisv10.c | 4 +-
drivers/usb/host/ohci-q.c | 4 +-
drivers/usb/image/mdc800.c | 45 +++++++++++++++++++++++++++++----
drivers/usb/input/ati_remote.c | 2 -
drivers/usb/media/ibmcam.c | 4 +-
drivers/usb/media/konicawc.c | 10 +++----
drivers/usb/media/ov511.c | 2 -
drivers/usb/media/ultracam.c | 8 ++---
drivers/usb/misc/auerswald.c | 2 -
drivers/usb/misc/legousbtower.c | 4 +-
drivers/usb/misc/usbtest.c | 6 ++--
drivers/usb/serial/usb-serial.c | 8 ++---
drivers/usb/usb-skeleton.c | 2 -
drivers/w1/dscore.c | 2 -
include/linux/usb.h | 2 -
include/linux/usb_ch9.h | 2 -
sound/usb/usbaudio.c | 8 ++---
sound/usb/usx2y/usbusx2yaudio.c | 4 +-
37 files changed, 115 insertions(+), 81 deletions(-)
diff -Nru a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
--- a/arch/mips/au1000/common/usbdev.c 2005-01-07 15:42:11 -08:00
+++ b/arch/mips/au1000/common/usbdev.c 2005-01-07 15:42:11 -08:00
@@ -1398,7 +1398,7 @@
epd->bEndpointAddress |= (u8)ep->address;
ep->direction = epd->bEndpointAddress & 0x80;
ep->type = epd->bmAttributes & 0x03;
- ep->max_pkt_size = epd->wMaxPacketSize;
+ ep->max_pkt_size = le16_to_cpu(epd->wMaxPacketSize);
spin_lock_init(&ep->lock);
ep->desc = epd;
ep->reg = &ep_reg[ep->address];
diff -Nru a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
--- a/drivers/bluetooth/bfusb.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/bluetooth/bfusb.c 2005-01-07 15:42:11 -08:00
@@ -678,7 +678,7 @@
bfusb->udev = udev;
bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;
bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
- bfusb->bulk_pkt_size = bulk_out_ep->desc.wMaxPacketSize;
+ bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
rwlock_init(&bfusb->lock);
diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
--- a/drivers/bluetooth/hci_usb.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/bluetooth/hci_usb.c 2005-01-07 15:42:11 -08:00
@@ -193,7 +193,7 @@
BT_DBG("%s", husb->hdev->name);
- size = husb->intr_in_ep->desc.wMaxPacketSize;
+ size = le16_to_cpu(husb->intr_in_ep->desc.wMaxPacketSize);
buf = kmalloc(size, GFP_ATOMIC);
if (!buf)
@@ -268,7 +268,7 @@
int err, mtu, size;
void *buf;
- mtu = husb->isoc_in_ep->desc.wMaxPacketSize;
+ mtu = le16_to_cpu(husb->isoc_in_ep->desc.wMaxPacketSize);
size = mtu * HCI_MAX_ISOC_FRAMES;
buf = kmalloc(size, GFP_ATOMIC);
@@ -525,7 +525,7 @@
urb->transfer_buffer = skb->data;
urb->transfer_buffer_length = skb->len;
- __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->desc.wMaxPacketSize);
+ __fill_isoc_desc(urb, skb->len, le16_to_cpu(husb->isoc_out_ep->desc.wMaxPacketSize));
_urb->priv = skb;
return __tx_submit(husb, _urb);
@@ -897,10 +897,10 @@
switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_ISOC:
- if (ep->desc.wMaxPacketSize < size ||
+ if (le16_to_cpu(ep->desc.wMaxPacketSize) < size ||
uif->desc.bAlternateSetting != isoc)
break;
- size = ep->desc.wMaxPacketSize;
+ size = le16_to_cpu(ep->desc.wMaxPacketSize);
isoc_alts = uif->desc.bAlternateSetting;
diff -Nru a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
--- a/drivers/char/watchdog/pcwd_usb.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/char/watchdog/pcwd_usb.c 2005-01-07 15:42:11 -08:00
@@ -615,7 +615,7 @@
usb_pcwd->udev = udev;
usb_pcwd->interface = interface;
usb_pcwd->interface_number = iface_desc->desc.bInterfaceNumber;
- usb_pcwd->intr_size = (endpoint->wMaxPacketSize > 8 ? endpoint->wMaxPacketSize : 8);
+ usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8);
/* set up the memory buffer's */
if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, SLAB_ATOMIC, &usb_pcwd->intr_dma))) {
diff -Nru a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
--- a/drivers/isdn/hisax/hfc_usb.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/isdn/hisax/hfc_usb.c 2005-01-07 15:42:11 -08:00
@@ -1492,7 +1492,7 @@
case USB_ENDPOINT_XFER_INT:
context->fifos[cidx].pipe = usb_rcvintpipe(dev, ep->desc.bEndpointAddress);
context->fifos[cidx].usb_transfer_mode = USB_INT;
- packet_size = ep->desc.wMaxPacketSize; // remember max packet size
+ packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size
#ifdef VERBOSE_USB_DEBUG
printk (KERN_INFO "HFC-USB: Interrupt-In Endpoint found %d ms(idx:%d cidx:%d)!\n",
ep->desc.bInterval, idx, cidx);
@@ -1504,7 +1504,7 @@
else
context->fifos[cidx].pipe = usb_sndbulkpipe(dev, ep->desc.bEndpointAddress);
context->fifos[cidx].usb_transfer_mode = USB_BULK;
- packet_size = ep->desc.wMaxPacketSize; // remember max packet size
+ packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size
#ifdef VERBOSE_USB_DEBUG
printk (KERN_INFO "HFC-USB: Bulk Endpoint found (idx:%d cidx:%d)!\n",
idx, cidx);
@@ -1516,7 +1516,7 @@
else
context->fifos[cidx].pipe = usb_sndisocpipe(dev, ep->desc.bEndpointAddress);
context->fifos[cidx].usb_transfer_mode = USB_ISOC;
- iso_packet_size = ep->desc.wMaxPacketSize; // remember max packet size
+ iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size
#ifdef VERBOSE_USB_DEBUG
printk (KERN_INFO "HFC-USB: ISO Endpoint found (idx:%d cidx:%d)!\n",
idx, cidx);
@@ -1529,7 +1529,7 @@
if (context->fifos[cidx].pipe) {
context->fifos[cidx].fifonum = cidx;
context->fifos[cidx].hfc = context;
- context->fifos[cidx].usb_packet_maxlen = ep->desc.wMaxPacketSize;
+ context->fifos[cidx].usb_packet_maxlen = le16_to_cpu(ep->desc.wMaxPacketSize);
context->fifos[cidx].intervall = ep->desc.bInterval;
context->fifos[cidx].skbuff = NULL;
#ifdef VERBOSE_USB_DEBUG
diff -Nru a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
--- a/drivers/isdn/hisax/st5481_b.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/isdn/hisax/st5481_b.c 2005-01-07 15:42:11 -08:00
@@ -274,7 +274,7 @@
endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2];
DBG(4,"endpoint address=%02x,packet size=%d",
- endpoint->desc.bEndpointAddress, endpoint->desc.wMaxPacketSize);
+ endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
// Allocate memory for 8000bytes/sec + extra bytes if underrun
return st5481_setup_isocpipes(b_out->urb, dev,
diff -Nru a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
--- a/drivers/isdn/hisax/st5481_d.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/isdn/hisax/st5481_d.c 2005-01-07 15:42:11 -08:00
@@ -669,7 +669,7 @@
endpoint = &altsetting->endpoint[EP_D_OUT-1];
DBG(2,"endpoint address=%02x,packet size=%d",
- endpoint->desc.bEndpointAddress, endpoint->desc.wMaxPacketSize);
+ endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
return st5481_setup_isocpipes(d_out->urb, dev,
usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress),
diff -Nru a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
--- a/drivers/isdn/hisax/st5481_usb.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/isdn/hisax/st5481_usb.c 2005-01-07 15:42:11 -08:00
@@ -268,8 +268,8 @@
}
// The descriptor is wrong for some early samples of the ST5481 chip
- altsetting->endpoint[3].desc.wMaxPacketSize = 32;
- altsetting->endpoint[4].desc.wMaxPacketSize = 32;
+ altsetting->endpoint[3].desc.wMaxPacketSize = __constant_cpu_to_le16(32);
+ altsetting->endpoint[4].desc.wMaxPacketSize = __constant_cpu_to_le16(32);
// Use alternative setting 3 on interface 0 to have 2B+D
if ((status = usb_set_interface (dev, 0, 3)) < 0) {
diff -Nru a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c
--- a/drivers/media/dvb/b2c2/b2c2-usb-core.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/media/dvb/b2c2/b2c2-usb-core.c 2005-01-07 15:42:11 -08:00
@@ -370,7 +370,7 @@
static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
{
- u16 frame_size = b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize;
+ u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
int buffer_offset = 0;
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/net/irda/irda-usb.c 2005-01-07 15:42:11 -08:00
@@ -1220,7 +1220,7 @@
ep = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
dir = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK;
attr = endpoint[i].desc.bmAttributes;
- psize = endpoint[i].desc.wMaxPacketSize;
+ psize = le16_to_cpu(endpoint[i].desc.wMaxPacketSize);
/* Is it a bulk endpoint ??? */
if(attr == USB_ENDPOINT_XFER_BULK) {
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/class/audio.c 2005-01-07 15:42:11 -08:00
@@ -3717,7 +3717,7 @@
if (alt->desc.bNumEndpoints > 0) {
/* Check all endpoints; should they all have a bandwidth of 0 ? */
for (k = 0; k < alt->desc.bNumEndpoints; k++) {
- if (alt->endpoint[k].desc.wMaxPacketSize > 0) {
+ if (le16_to_cpu(alt->endpoint[k].desc.wMaxPacketSize) > 0) {
printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u endpoint %d does not have 0 bandwidth at alt[0]\n", dev->devnum, ctrlif, k);
break;
}
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/class/bluetty.c 2005-01-07 15:42:11 -08:00
@@ -1086,7 +1086,7 @@
err("No free urbs available");
goto probe_error;
}
- bluetooth->bulk_in_buffer_size = buffer_size = endpoint->wMaxPacketSize;
+ bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress;
bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
if (!bluetooth->bulk_in_buffer) {
@@ -1098,7 +1098,7 @@
endpoint = bulk_out_endpoint[0];
bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress;
- bluetooth->bulk_out_buffer_size = endpoint->wMaxPacketSize * 2;
+ bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
endpoint = interrupt_in_endpoint[0];
bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -1106,7 +1106,7 @@
err("No free urbs available");
goto probe_error;
}
- bluetooth->interrupt_in_buffer_size = buffer_size = endpoint->wMaxPacketSize;
+ bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
bluetooth->interrupt_in_interval = endpoint->bInterval;
bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/class/cdc-acm.c 2005-01-07 15:42:11 -08:00
@@ -657,9 +657,9 @@
}
memset(acm, 0, sizeof(struct acm));
- ctrlsize = epctrl->wMaxPacketSize;
- readsize = epread->wMaxPacketSize;
- acm->writesize = epwrite->wMaxPacketSize;
+ ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
+ readsize = le16_to_cpu(epread->wMaxPacketSize);
+ acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
acm->control = control_interface;
acm->data = data_interface;
acm->minor = minor;
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- a/drivers/usb/core/config.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/core/config.c 2005-01-07 15:42:11 -08:00
@@ -87,7 +87,6 @@
++ifp->desc.bNumEndpoints;
memcpy(&endpoint->desc, d, n);
- le16_to_cpus(&endpoint->desc.wMaxPacketSize);
INIT_LIST_HEAD(&endpoint->urb_list);
/* Skip over any Class Specific or Vendor Specific descriptors;
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/core/devices.c 2005-01-07 15:42:11 -08:00
@@ -180,7 +180,7 @@
in = (desc->bEndpointAddress & USB_DIR_IN);
dir = in ? 'I' : 'O';
if (speed == USB_SPEED_HIGH) {
- switch (desc->wMaxPacketSize & (0x03 << 11)) {
+ switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) {
case 1 << 11: bandwidth = 2; break;
case 2 << 11: bandwidth = 3; break;
}
@@ -227,7 +227,7 @@
start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
desc->bmAttributes, type,
- (desc->wMaxPacketSize & 0x07ff) * bandwidth,
+ (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * bandwidth,
interval, unit);
return start;
}
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/core/hcd.c 2005-01-07 15:42:11 -08:00
@@ -208,7 +208,7 @@
0x05, /* __u8 ep_bDescriptorType; Endpoint */
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* __u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+ 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
0xff /* __u8 ep_bInterval; (255ms -- usb 2.0 spec) */
};
@@ -255,7 +255,7 @@
0x05, /* __u8 ep_bDescriptorType; Endpoint */
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* __u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+ 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */
};
@@ -809,7 +809,7 @@
down (&usb_bus_list_lock);
usb_dev->bus->root_hub = usb_dev;
- usb_dev->ep0.desc.wMaxPacketSize = 64;
+ usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) {
usb_dev->bus->root_hub = NULL;
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/core/hub.c 2005-01-07 15:42:11 -08:00
@@ -2119,17 +2119,17 @@
*/
switch (udev->speed) {
case USB_SPEED_HIGH: /* fixed at 64 */
- udev->ep0.desc.wMaxPacketSize = 64;
+ udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
break;
case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
/* to determine the ep0 maxpacket size, try to read
* the device descriptor to get bMaxPacketSize0 and
* then correct our initial guess.
*/
- udev->ep0.desc.wMaxPacketSize = 64;
+ udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
break;
case USB_SPEED_LOW: /* fixed at 8 */
- udev->ep0.desc.wMaxPacketSize = 8;
+ udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
break;
default:
goto fail;
@@ -2263,7 +2263,7 @@
goto fail;
i = udev->descriptor.bMaxPacketSize0;
- if (udev->ep0.desc.wMaxPacketSize != i) {
+ if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
if (udev->speed != USB_SPEED_FULL ||
!(i == 8 || i == 16 || i == 32 || i == 64)) {
dev_err(&udev->dev, "ep0 maxpacket = %d\n", i);
@@ -2271,7 +2271,7 @@
goto fail;
}
dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
- udev->ep0.desc.wMaxPacketSize = i;
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
ep0_reinit(udev);
}
diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/gadget/dummy_hcd.c 2005-01-07 15:42:11 -08:00
@@ -247,7 +247,7 @@
dum = ep_to_dummy (ep);
if (!dum->driver || !is_enabled (dum))
return -ESHUTDOWN;
- max = desc->wMaxPacketSize & 0x3ff;
+ max = le16_to_cpu(desc->wMaxPacketSize) & 0x3ff;
/* drivers must not request bad settings, since lower levels
* (hardware or its drivers) may not check. some endpoints
@@ -1025,7 +1025,7 @@
int tmp;
/* high bandwidth mode */
- tmp = ep->desc->wMaxPacketSize;
+ tmp = le16_to_cpu(ep->desc->wMaxPacketSize);
tmp = le16_to_cpu (tmp);
tmp = (tmp >> 11) & 0x03;
tmp *= 8 /* applies to entire frame */;
diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
--- a/drivers/usb/gadget/file_storage.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/gadget/file_storage.c 2005-01-07 15:42:11 -08:00
@@ -3132,7 +3132,7 @@
if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
goto reset;
fsg->bulk_out_enabled = 1;
- fsg->bulk_out_maxpacket = d->wMaxPacketSize;
+ fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
if (transport_is_cbi()) {
d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
diff -Nru a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
--- a/drivers/usb/host/hc_crisv10.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/host/hc_crisv10.c 2005-01-07 15:42:11 -08:00
@@ -160,7 +160,7 @@
0x05, /* __u8 ep_bDescriptorType; Endpoint */
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* __u8 ep_bmAttributes; Interrupt */
- 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */
+ 0x08, /* __le16 ep_wMaxPacketSize; 8 Bytes */
0x00,
0xff /* __u8 ep_bInterval; 255 ms */
};
@@ -4528,7 +4528,7 @@
usb_rh->speed = USB_SPEED_FULL;
usb_rh->devnum = 1;
hc->bus->devnum_next = 2;
- usb_rh->ep0.desc.wMaxPacketSize = 64;
+ usb_rh->ep0.desc.wMaxPacketSize = __const_cpu_to_le16(64);
usb_get_device_descriptor(usb_rh, USB_DT_DEVICE_SIZE);
usb_new_device(usb_rh);
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/host/ohci-q.c 2005-01-07 15:42:11 -08:00
@@ -433,7 +433,7 @@
ed->type = usb_pipetype(pipe);
info |= (ep->desc.bEndpointAddress & ~USB_DIR_IN) << 7;
- info |= ep->desc.wMaxPacketSize << 16;
+ info |= le16_to_cpu(ep->desc.wMaxPacketSize) << 16;
if (udev->speed == USB_SPEED_LOW)
info |= ED_LOWSPEED;
/* only control transfers store pids in tds */
@@ -449,7 +449,7 @@
ed->load = usb_calc_bus_time (
udev->speed, !is_out,
ed->type == PIPE_ISOCHRONOUS,
- ep->desc.wMaxPacketSize)
+ le16_to_cpu(ep->desc.wMaxPacketSize))
/ 1000;
}
}
diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/image/mdc800.c 2005-01-07 15:42:11 -08:00
@@ -182,12 +182,47 @@
/* Specification of the Endpoints */
static struct usb_endpoint_descriptor mdc800_ed [4] =
{
- { 0,0, 0x01, 0x02, 8, 0,0,0 },
- { 0,0, 0x82, 0x03, 8, 0,0,0 },
- { 0,0, 0x03, 0x02, 64, 0,0,0 },
- { 0,0, 0x84, 0x02, 64, 0,0,0 }
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x01,
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x82,
+ .bmAttributes = 0x03,
+ .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x03,
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x84,
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
};
-
/* The Variable used by the driver */
static struct mdc800_data* mdc800;
diff -Nru a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
--- a/drivers/usb/input/ati_remote.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/input/ati_remote.c 2005-01-07 15:42:11 -08:00
@@ -756,7 +756,7 @@
retval = -ENODEV;
goto error;
}
- if (ati_remote->endpoint_in->wMaxPacketSize == 0) {
+ if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) {
err("%s: endpoint_in message size==0? \n", __FUNCTION__);
retval = -ENODEV;
goto error;
diff -Nru a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
--- a/drivers/usb/media/ibmcam.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/media/ibmcam.c 2005-01-07 15:42:11 -08:00
@@ -3743,7 +3743,7 @@
err("Interface %d. has ISO OUT endpoint!", ifnum);
return -ENODEV;
}
- if (endpoint->wMaxPacketSize == 0) {
+ if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
if (inactInterface < 0)
inactInterface = i;
else {
@@ -3753,7 +3753,7 @@
} else {
if (actInterface < 0) {
actInterface = i;
- maxPS = endpoint->wMaxPacketSize;
+ maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
if (debug > 0)
info("Active setting=%d. maxPS=%d.", i, maxPS);
} else
diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/media/konicawc.c 2005-01-07 15:42:11 -08:00
@@ -390,7 +390,7 @@
spd_to_iface[cam->speed]);
if (!interface)
return -ENXIO;
- pktsz = interface->endpoint[1].desc.wMaxPacketSize;
+ pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize);
DEBUG(1, "pktsz = %d", pktsz);
if (!CAMERA_IS_OPERATIONAL(uvd)) {
err("Camera is not operational");
@@ -756,7 +756,7 @@
}
endpoint = &interface->endpoint[1].desc;
DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
- endpoint->bEndpointAddress, endpoint->wMaxPacketSize);
+ endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize));
if (video_ep == 0)
video_ep = endpoint->bEndpointAddress;
else if (video_ep != endpoint->bEndpointAddress) {
@@ -773,7 +773,7 @@
interface->desc.bInterfaceNumber);
return -ENODEV;
}
- if (endpoint->wMaxPacketSize == 0) {
+ if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
if (inactInterface < 0)
inactInterface = i;
else {
@@ -786,8 +786,8 @@
actInterface = i;
}
}
- if(endpoint->wMaxPacketSize > maxPS)
- maxPS = endpoint->wMaxPacketSize;
+ if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS)
+ maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
}
if(actInterface == -1) {
err("Cant find required endpoint");
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/media/ov511.c 2005-01-07 15:42:11 -08:00
@@ -5596,7 +5596,7 @@
if (ifp) {
alt = usb_altnum_to_altsetting(ifp, 7);
if (alt)
- mxps = alt->endpoint[0].desc.wMaxPacketSize;
+ mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
}
/* Some OV518s have packet numbering by default, some don't */
diff -Nru a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c
--- a/drivers/usb/media/ultracam.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/media/ultracam.c 2005-01-07 15:42:11 -08:00
@@ -565,7 +565,7 @@
interface->desc.bInterfaceNumber);
return -ENODEV;
}
- if (endpoint->wMaxPacketSize == 0) {
+ if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
if (inactInterface < 0)
inactInterface = i;
else {
@@ -575,15 +575,15 @@
} else {
if (actInterface < 0) {
actInterface = i;
- maxPS = endpoint->wMaxPacketSize;
+ maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
if (debug > 0)
info("Active setting=%d. maxPS=%d.", i, maxPS);
} else {
/* Got another active alt. setting */
- if (maxPS < endpoint->wMaxPacketSize) {
+ if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) {
/* This one is better! */
actInterface = i;
- maxPS = endpoint->wMaxPacketSize;
+ maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
if (debug > 0) {
info("Even better ctive setting=%d. maxPS=%d.",
i, maxPS);
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/misc/auerswald.c 2005-01-07 15:42:11 -08:00
@@ -1132,7 +1132,7 @@
ret = -EFAULT;
goto intoend;
}
- irqsize = ep->desc.wMaxPacketSize;
+ irqsize = le16_to_cpu(ep->desc.wMaxPacketSize);
cp->irqsize = irqsize;
/* allocate the urb and data buffer */
diff -Nru a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
--- a/drivers/usb/misc/legousbtower.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/misc/legousbtower.c 2005-01-07 15:42:11 -08:00
@@ -405,7 +405,7 @@
dev->udev,
usb_rcvintpipe(dev->udev, dev->interrupt_in_endpoint->bEndpointAddress),
dev->interrupt_in_buffer,
- dev->interrupt_in_endpoint->wMaxPacketSize,
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
tower_interrupt_in_callback,
dev,
dev->interrupt_in_interval);
@@ -924,7 +924,7 @@
err("Couldn't allocate read_buffer");
goto error;
}
- dev->interrupt_in_buffer = kmalloc (dev->interrupt_in_endpoint->wMaxPacketSize, GFP_KERNEL);
+ dev->interrupt_in_buffer = kmalloc (le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
err("Couldn't allocate interrupt_in_buffer");
goto error;
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/misc/usbtest.c 2005-01-07 15:42:11 -08:00
@@ -1371,8 +1371,8 @@
if (bytes < 0 || !desc)
return NULL;
- maxp = 0x7ff & desc->wMaxPacketSize;
- maxp *= 1 + (0x3 & (desc->wMaxPacketSize >> 11));
+ maxp = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
+ maxp *= 1 + (0x3 & (le16_to_cpu(desc->wMaxPacketSize) >> 11));
packets = (bytes + maxp - 1) / maxp;
urb = usb_alloc_urb (packets, SLAB_KERNEL);
@@ -1432,7 +1432,7 @@
"... iso period %d %sframes, wMaxPacket %04x\n",
1 << (desc->bInterval - 1),
(udev->speed == USB_SPEED_HIGH) ? "micro" : "",
- desc->wMaxPacketSize);
+ le16_to_cpu(desc->wMaxPacketSize));
for (i = 0; i < param->sglen; i++) {
urbs [i] = iso_alloc_urb (udev, pipe, desc,
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/serial/usb-serial.c 2005-01-07 15:42:11 -08:00
@@ -1060,7 +1060,7 @@
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
}
- buffer_size = endpoint->wMaxPacketSize;
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->bulk_in_size = buffer_size;
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1084,7 +1084,7 @@
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
}
- buffer_size = endpoint->wMaxPacketSize;
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->bulk_out_size = buffer_size;
port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1109,7 +1109,7 @@
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
}
- buffer_size = endpoint->wMaxPacketSize;
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
if (!port->interrupt_in_buffer) {
@@ -1136,7 +1136,7 @@
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
}
- buffer_size = endpoint->wMaxPacketSize;
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->interrupt_out_size = buffer_size;
port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;
port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/usb/usb-skeleton.c 2005-01-07 15:42:11 -08:00
@@ -260,7 +260,7 @@
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_BULK)) {
/* we found a bulk in endpoint */
- buffer_size = endpoint->wMaxPacketSize;
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
dev->bulk_in_size = buffer_size;
dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
diff -Nru a/drivers/w1/dscore.c b/drivers/w1/dscore.c
--- a/drivers/w1/dscore.c 2005-01-07 15:42:11 -08:00
+++ b/drivers/w1/dscore.c 2005-01-07 15:42:11 -08:00
@@ -676,7 +676,7 @@
ds_dev->ep[i+1] = endpoint->bEndpointAddress;
printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
- i, endpoint->bEndpointAddress, endpoint->wMaxPacketSize,
+ i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
}
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h 2005-01-07 15:42:11 -08:00
+++ b/include/linux/usb.h 2005-01-07 15:42:11 -08:00
@@ -1125,7 +1125,7 @@
return 0;
/* NOTE: only 0x07ff bits are for packet size... */
- return ep->desc.wMaxPacketSize;
+ return le16_to_cpu(ep->desc.wMaxPacketSize);
}
/* -------------------------------------------------------------------------- */
diff -Nru a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
--- a/include/linux/usb_ch9.h 2005-01-07 15:42:11 -08:00
+++ b/include/linux/usb_ch9.h 2005-01-07 15:42:11 -08:00
@@ -264,7 +264,7 @@
__u8 bEndpointAddress;
__u8 bmAttributes;
- __u16 wMaxPacketSize;
+ __le16 wMaxPacketSize;
__u8 bInterval;
// NOTE: these two are _only_ in audio endpoints.
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c 2005-01-07 15:42:11 -08:00
+++ b/sound/usb/usbaudio.c 2005-01-07 15:42:11 -08:00
@@ -2450,7 +2450,7 @@
(altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING &&
altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
altsd->bNumEndpoints < 1 ||
- get_endpoint(alts, 0)->wMaxPacketSize == 0)
+ le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
continue;
/* must be isochronous */
if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
@@ -2513,7 +2513,7 @@
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
/* FIXME: decode wMaxPacketSize of high bandwith endpoints */
- fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+ fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
fp->attributes = csep[3];
/* some quirks for attributes here */
@@ -2809,7 +2809,7 @@
fp->iface = altsd->bInterfaceNumber;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
- fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+ fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
switch (fp->maxpacksize) {
case 0x120:
@@ -2875,7 +2875,7 @@
fp->iface = altsd->bInterfaceNumber;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
- fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+ fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
stream = (fp->endpoint & USB_DIR_IN)
diff -Nru a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
--- a/sound/usb/usx2y/usbusx2yaudio.c 2005-01-07 15:42:11 -08:00
+++ b/sound/usb/usx2y/usbusx2yaudio.c 2005-01-07 15:42:11 -08:00
@@ -458,7 +458,7 @@
ep = dev->ep_out[subs->endpoint];
if (!ep)
return -EINVAL;
- subs->maxpacksize = ep->desc.wMaxPacketSize;
+ subs->maxpacksize = le16_to_cpu(ep->desc.wMaxPacketSize);
if (NULL == subs->tmpbuf) {
subs->tmpbuf = kcalloc(NRPACKS, subs->maxpacksize, GFP_KERNEL);
if (NULL == subs->tmpbuf) {
@@ -471,7 +471,7 @@
ep = dev->ep_in[subs->endpoint];
if (!ep)
return -EINVAL;
- subs->maxpacksize = ep->desc.wMaxPacketSize;
+ subs->maxpacksize = le16_to_cpu(ep->desc.wMaxPacketSize);
}
/* allocate and initialize data urbs */
ChangeSet 1.1938.444.11, 2004/12/17 15:12:52-08:00, [email protected]
[PATCH] sysfs: Allocate sysfs_dirent structures from their own slab.
* Andrew Morton ([email protected]) wrote:
> That's all well and good, but sysfs_new_dirent() should be using a
> standalone slab cache for allocating sysfs_dirent instances. That way, we
> use 36 bytes for each one rather than 64.
Reasonable, here's a patch (lightly tested). Without, size-64 looks
like so:
size-64 4064 4108 76 52 1 : tunables 32 16 8 : slabdata 79 79 0 : globalstat 4263 4079 79 0 0 0 84 0 : cpustat 15986 337 12286 3
And with:
size-64 1196 1196 76 52 1 : tunables 32 16 8 : slabdata 23 23 0 : globalstat 1297 1196 23 0 0 0 84 0 : cpustat 12418 108 11349 1
sysfs_dir_cache 2862 2916 48 81 1 : tunables 32 16 8 : slabdata 36 36 0 : globalstat 2931 2874 36 0 0 0 113 0 : cpustat 2756 216 110 0
Allocate sysfs_dirent structures from their own slab.
Signed-off-by: Chris Wright <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
fs/sysfs/dir.c | 2 +-
fs/sysfs/mount.c | 17 +++++++++++++++--
fs/sysfs/sysfs.h | 3 ++-
3 files changed, 18 insertions(+), 4 deletions(-)
diff -Nru a/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- a/fs/sysfs/dir.c 2005-01-07 15:45:26 -08:00
+++ b/fs/sysfs/dir.c 2005-01-07 15:45:26 -08:00
@@ -36,7 +36,7 @@
{
struct sysfs_dirent * sd;
- sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+ sd = kmem_cache_alloc(sysfs_dir_cachep, GFP_KERNEL);
if (!sd)
return NULL;
diff -Nru a/fs/sysfs/mount.c b/fs/sysfs/mount.c
--- a/fs/sysfs/mount.c 2005-01-07 15:45:26 -08:00
+++ b/fs/sysfs/mount.c 2005-01-07 15:45:26 -08:00
@@ -16,6 +16,7 @@
struct vfsmount *sysfs_mount;
struct super_block * sysfs_sb = NULL;
+kmem_cache_t *sysfs_dir_cachep;
static struct super_operations sysfs_ops = {
.statfs = simple_statfs,
@@ -76,7 +77,13 @@
int __init sysfs_init(void)
{
- int err;
+ int err = -ENOMEM;
+
+ sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
+ sizeof(struct sysfs_dirent),
+ 0, 0, NULL, NULL);
+ if (!sysfs_dir_cachep)
+ goto out;
err = register_filesystem(&sysfs_fs_type);
if (!err) {
@@ -85,7 +92,13 @@
printk(KERN_ERR "sysfs: could not mount!\n");
err = PTR_ERR(sysfs_mount);
sysfs_mount = NULL;
+ goto out_err;
}
- }
+ } else
+ goto out_err;
+out:
return err;
+out_err:
+ kmem_cache_destroy(sysfs_dir_cachep);
+ goto out;
}
diff -Nru a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
--- a/fs/sysfs/sysfs.h 2005-01-07 15:45:26 -08:00
+++ b/fs/sysfs/sysfs.h 2005-01-07 15:45:26 -08:00
@@ -1,5 +1,6 @@
extern struct vfsmount * sysfs_mount;
+extern kmem_cache_t *sysfs_dir_cachep;
extern struct inode * sysfs_new_inode(mode_t mode);
extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
@@ -74,7 +75,7 @@
kobject_put(sl->target_kobj);
kfree(sl);
}
- kfree(sd);
+ kmem_cache_free(sysfs_dir_cachep, sd);
}
static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
ChangeSet 1.1938.446.26, 2004/12/15 16:37:38-08:00, [email protected]
[PATCH] USB: UHCI and HCD API change (14/15)
UHCI changes to match the updated HCD glue calls. Since it's handed the
relevant endpoint queue on a silver platter, the driver no longer needs
to search anything to find the queue entries.
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/host/uhci-hcd.c | 39 +++++----------------------------------
1 files changed, 5 insertions(+), 34 deletions(-)
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c 2005-01-07 15:48:04 -08:00
+++ b/drivers/usb/host/uhci-hcd.c 2005-01-07 15:48:04 -08:00
@@ -1255,7 +1255,9 @@
return NULL;
}
-static int uhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, int mem_flags)
+static int uhci_urb_enqueue(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep,
+ struct urb *urb, int mem_flags)
{
int ret;
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -2293,44 +2295,13 @@
return &uhci->hcd;
}
-/* Are there any URBs for a particular device/endpoint on a given list? */
-static int urbs_for_ep_list(struct list_head *head,
- struct hcd_dev *hdev, int ep)
-{
- struct urb_priv *urbp;
-
- list_for_each_entry(urbp, head, urb_list) {
- struct urb *urb = urbp->urb;
-
- if (hdev == urb->dev->hcpriv && ep ==
- (usb_pipeendpoint(urb->pipe) |
- usb_pipein(urb->pipe)))
- return 1;
- }
- return 0;
-}
-
-/* Are there any URBs for a particular device/endpoint? */
-static int urbs_for_ep(struct uhci_hcd *uhci, struct hcd_dev *hdev, int ep)
-{
- int rc;
-
- spin_lock_irq(&uhci->schedule_lock);
- rc = (urbs_for_ep_list(&uhci->urb_list, hdev, ep) ||
- urbs_for_ep_list(&uhci->complete_list, hdev, ep) ||
- urbs_for_ep_list(&uhci->urb_remove_list, hdev, ep));
- spin_unlock_irq(&uhci->schedule_lock);
- return rc;
-}
-
/* Wait until all the URBs for a particular device/endpoint are gone */
static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
- struct hcd_dev *hdev, int endpoint)
+ struct usb_host_endpoint *ep)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
- wait_event_interruptible(uhci->waitqh,
- !urbs_for_ep(uhci, hdev, endpoint));
+ wait_event_interruptible(uhci->waitqh, list_empty(&ep->urb_list));
}
static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
On Fri, Jan 07, 2005 at 09:47:43PM -0800, Greg KH wrote:
> ChangeSet 1.1938.444.33, 2004/12/22 13:50:21-08:00, [email protected]
>
> [PATCH] driver core: Fix up vesafb failure probing.
>
> bus.c file invokes a probe callback for most devices in a list, then checks
> for -ENODEV return ("no such device"), if so it remains silent. However, some
> drivers (including vesafb.c) may return -ENXIO ("no such device or address"),
> which is indeed error -6.
>
> I shut up the warning with the attached patch, that basically ignores
> both -ENODEV and -ENXIO.
NAK. We shouldn't have two return codes indicating the same error (or
actually non-error in this case). Let's fix the drivers instead.
On Sat, Jan 08, 2005 at 12:08:58PM +0000, Christoph Hellwig wrote:
> On Fri, Jan 07, 2005 at 09:47:43PM -0800, Greg KH wrote:
> > ChangeSet 1.1938.444.33, 2004/12/22 13:50:21-08:00, [email protected]
> >
> > [PATCH] driver core: Fix up vesafb failure probing.
> >
> > bus.c file invokes a probe callback for most devices in a list, then checks
> > for -ENODEV return ("no such device"), if so it remains silent. However, some
> > drivers (including vesafb.c) may return -ENXIO ("no such device or address"),
> > which is indeed error -6.
> >
> > I shut up the warning with the attached patch, that basically ignores
> > both -ENODEV and -ENXIO.
>
> NAK. We shouldn't have two return codes indicating the same error (or
> actually non-error in this case). Let's fix the drivers instead.
Ok, David, care to send a patch to do so?
thanks,
greg k-h
On Sat, 8 Jan 2005 14:42:32 -0800, Greg KH <[email protected]> wrote:
> On Sat, Jan 08, 2005 at 12:08:58PM +0000, Christoph Hellwig wrote:
> > On Fri, Jan 07, 2005 at 09:47:43PM -0800, Greg KH wrote:
> > > ChangeSet 1.1938.444.33, 2004/12/22 13:50:21-08:00, [email protected]
> > >
> > > [PATCH] driver core: Fix up vesafb failure probing.
> > >
> > > bus.c file invokes a probe callback for most devices in a list, then checks
> > > for -ENODEV return ("no such device"), if so it remains silent. However, some
> > > drivers (including vesafb.c) may return -ENXIO ("no such device or address"),
> > > which is indeed error -6.
> > >
> > > I shut up the warning with the attached patch, that basically ignores
> > > both -ENODEV and -ENXIO.
> >
> > NAK. We shouldn't have two return codes indicating the same error (or
> > actually non-error in this case). Let's fix the drivers instead.
>
> Ok, David, care to send a patch to do so?
The above would be the patch I posted here
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=125890
the reason I went for the lazy approach is mainly that I tried to look into the
usage of -ENXIO vs -ENODEV, but just grepping in drivers/video/*.c turned out
to be confusing rather than enlightening... should *all* -ENXIO be converted
into -ENODEV ?