]> err.no Git - linux-2.6/commitdiff
Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 9 Sep 2005 03:24:02 +0000 (20:24 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 9 Sep 2005 03:24:02 +0000 (20:24 -0700)
290 files changed:
Documentation/feature-removal-schedule.txt
Documentation/input/yealink.txt [new file with mode: 0644]
MAINTAINERS
arch/alpha/kernel/sys_marvel.c
arch/arm/common/locomo.c
arch/arm/configs/s3c2410_defconfig
arch/arm/mach-clps7500/core.c
arch/arm/mach-ebsa110/core.c
arch/arm/mach-epxa10db/arch.c
arch/arm/mach-footbridge/isa.c
arch/arm/mach-h720x/cpu-h7202.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-ixp4xx/coyote-setup.c
arch/arm/mach-ixp4xx/gtwx5715-setup.c
arch/arm/mach-ixp4xx/ixdp425-setup.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/board-generic.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-netstar.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/devices.c [new file with mode: 0644]
arch/arm/mach-omap1/fpga.c
arch/arm/mach-omap1/io.c
arch/arm/mach-omap1/irq.c
arch/arm/mach-omap1/leds-h2p2-debug.c
arch/arm/mach-omap1/leds-innovator.c
arch/arm/mach-omap1/leds-osk.c
arch/arm/mach-omap1/leds.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap1/time.c
arch/arm/mach-rpc/riscpc.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-shark/core.c
arch/arm/mm/flush.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/pci/i386.c
arch/ia64/Kconfig
arch/ia64/configs/sn2_defconfig
arch/ia64/configs/tiger_defconfig
arch/ia64/configs/zx1_defconfig
arch/ia64/defconfig
arch/ia64/kernel/acpi.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/iosapic.c
arch/ia64/lib/memcpy_mck.S
arch/ia64/mm/fault.c
arch/ia64/pci/pci.c
arch/ia64/sn/kernel/setup.c
arch/ia64/sn/kernel/xpc_main.c
arch/ia64/sn/kernel/xpnet.c
arch/m68knommu/platform/523x/Makefile [new file with mode: 0644]
arch/m68knommu/platform/5272/config.c
arch/m68knommu/platform/5307/Makefile
arch/m68knommu/platform/68328/config.c
arch/m68knommu/platform/68328/timers.c [new file with mode: 0644]
arch/m68knommu/platform/68EZ328/config.c
arch/m68knommu/platform/68VZ328/config.c [moved from arch/m68knommu/platform/68VZ328/de2/config.c with 51% similarity]
arch/m68knommu/platform/68VZ328/ucdimm/config.c [deleted file]
arch/ppc/kernel/pci.c
arch/ppc/syslib/mpc10x_common.c
arch/ppc/syslib/mpc83xx_devices.c
arch/ppc/syslib/mpc85xx_devices.c
arch/ppc64/kernel/eeh.c
arch/ppc64/kernel/iSeries_VpdInfo.c
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/setup.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/lib/Makefile
arch/sparc64/lib/mb.S [deleted file]
drivers/block/ub.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/generic.c
drivers/char/drm/drmP.h
drivers/cpufreq/cpufreq.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-pxa.c [new file with mode: 0644]
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/mthca/mthca_reset.c
drivers/mmc/mmc.c
drivers/mmc/mmci.c
drivers/mmc/pxamci.c
drivers/mmc/wbsd.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/irda/irda-usb.c
drivers/net/irda/vlsi_ir.h
drivers/parport/parport_pc.c
drivers/pci/Kconfig
drivers/pci/Makefile
drivers/pci/bus.c
drivers/pci/gen-devlist.c [deleted file]
drivers/pci/hotplug/Makefile
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpaphp.h
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/rpaphp_vio.c [deleted file]
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/hotplug/shpchp.h
drivers/pci/msi.c
drivers/pci/names.c [deleted file]
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.ids [deleted file]
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pci/setup-res.c
drivers/scsi/ahci.c
drivers/scsi/ata_piix.c
drivers/scsi/sata_sis.c
drivers/scsi/sata_uli.c
drivers/serial/8250.c
drivers/serial/8250_accent.c
drivers/serial/8250_boca.c
drivers/serial/8250_fourport.c
drivers/serial/8250_hub6.c
drivers/serial/8250_mca.c
drivers/usb/atm/cxacru.c
drivers/usb/class/Kconfig
drivers/usb/class/usblp.c
drivers/usb/core/Makefile
drivers/usb/core/devio.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/inode.c
drivers/usb/core/message.c
drivers/usb/core/urb.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/ether.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/gadget_chips.h
drivers/usb/gadget/serial.c
drivers/usb/gadget/zero.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-ppc-soc.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/input/Kconfig
drivers/usb/input/Makefile
drivers/usb/input/hid-core.c
drivers/usb/input/keyspan_remote.c
drivers/usb/input/map_to_7segment.h [new file with mode: 0644]
drivers/usb/input/yealink.c [new file with mode: 0644]
drivers/usb/input/yealink.h [new file with mode: 0644]
drivers/usb/misc/auerswald.c
drivers/usb/misc/ldusb.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/usbtest.c
drivers/usb/mon/Makefile
drivers/usb/mon/mon_dma.c [new file with mode: 0644]
drivers/usb/mon/mon_text.c
drivers/usb/mon/usb_mon.h
drivers/usb/net/Kconfig
drivers/usb/net/Makefile
drivers/usb/net/asix.c [new file with mode: 0644]
drivers/usb/net/catc.c
drivers/usb/net/cdc_ether.c [new file with mode: 0644]
drivers/usb/net/cdc_subset.c [new file with mode: 0644]
drivers/usb/net/gl620a.c [new file with mode: 0644]
drivers/usb/net/kaweth.c
drivers/usb/net/net1080.c [new file with mode: 0644]
drivers/usb/net/pegasus.c
drivers/usb/net/plusb.c [new file with mode: 0644]
drivers/usb/net/rndis_host.c [new file with mode: 0644]
drivers/usb/net/rtl8150.c
drivers/usb/net/usbnet.c
drivers/usb/net/usbnet.h [new file with mode: 0644]
drivers/usb/net/zaurus.c [new file with mode: 0644]
drivers/usb/net/zd1201.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/keyspan.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/Kconfig
drivers/usb/storage/Makefile
drivers/usb/storage/onetouch.c [new file with mode: 0644]
drivers/usb/storage/onetouch.h [new file with mode: 0644]
drivers/usb/storage/scsiglue.c
drivers/usb/storage/shuttle_usbat.c
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/video/nvidia/nvidia.c
drivers/video/riva/fbdev.c
drivers/w1/Kconfig
drivers/w1/Makefile
drivers/w1/ds_w1_bridge.c
drivers/w1/dscore.c
drivers/w1/dscore.h
drivers/w1/w1.c
drivers/w1/w1.h
drivers/w1/w1_ds2433.c [new file with mode: 0644]
drivers/w1/w1_family.c
drivers/w1/w1_family.h
drivers/w1/w1_int.c
drivers/w1/w1_io.c
drivers/w1/w1_io.h
drivers/w1/w1_netlink.c
drivers/w1/w1_netlink.h
drivers/w1/w1_smem.c
drivers/w1/w1_therm.c
include/asm-alpha/pci.h
include/asm-arm/arch-pxa/hardware.h
include/asm-arm/arch-pxa/i2c.h [new file with mode: 0644]
include/asm-arm/arch-pxa/mmc.h
include/asm-arm/arch-sa1100/hardware.h
include/asm-arm/cacheflush.h
include/asm-arm/pci.h
include/asm-generic/pci.h
include/asm-ia64/iosapic.h
include/asm-ia64/irq.h
include/asm-ia64/pci.h
include/asm-m68knommu/coldfire.h
include/asm-m68knommu/m523xsim.h [new file with mode: 0644]
include/asm-m68knommu/mcfsim.h
include/asm-m68knommu/mcfuart.h
include/asm-parisc/pci.h
include/asm-ppc/pci.h
include/asm-ppc64/pci.h
include/asm-sparc64/pci.h
include/asm-sparc64/system.h
include/linux/crc16.h [new file with mode: 0644]
include/linux/i2c-pxa.h [new file with mode: 0644]
include/linux/in6.h
include/linux/ipv6.h
include/linux/mempolicy.h
include/linux/mmc/host.h
include/linux/pci.h
include/linux/pci_regs.h [new file with mode: 0644]
include/linux/serial_8250.h
include/linux/skbuff.h
include/linux/usb.h
include/linux/usb_isp116x.h
include/net/ax25.h
include/net/compat.h
include/net/ipv6.h
include/net/transp_v6.h
lib/Kconfig
lib/Makefile
lib/crc16.c [new file with mode: 0644]
mm/mempolicy.c
net/ax25/ax25_addr.c
net/ipv4/netfilter/ip_conntrack_netbios_ns.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/route.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/datagram.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/raw.c
net/ipv6/reassembly.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/rose/rose_subr.c
net/xfrm/xfrm_policy.c
sound/usb/usbaudio.c

index 2e0a01b21fe040503243c963a65f8411e795961b..5f95d4b3cab1a4f6625f65431a720703e1ce2a05 100644 (file)
@@ -25,15 +25,6 @@ Who: Pavel Machek <pavel@suse.cz>
 
 ---------------------------
 
-What:  PCI Name Database (CONFIG_PCI_NAMES)
-When:  July 2005
-Why:   It bloats the kernel unnecessarily, and is handled by userspace better
-       (pciutils supports it.)  Will eliminate the need to try to keep the
-       pci.ids file in sync with the sf.net database all of the time.
-Who:   Greg Kroah-Hartman <gregkh@suse.de>
-
----------------------------
-
 What:  io_remap_page_range() (macro or function)
 When:  September 2005
 Why:   Replaced by io_remap_pfn_range() which allows more memory space
diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
new file mode 100644 (file)
index 0000000..85f095a
--- /dev/null
@@ -0,0 +1,203 @@
+Driver documentation for yealink usb-p1k phones
+
+0. Status
+~~~~~~~~~
+
+The p1k is a relatively cheap usb 1.1 phone with:
+  - keyboard           full support, yealink.ko / input event API
+  - LCD                        full support, yealink.ko / sysfs API
+  - LED                        full support, yealink.ko / sysfs API
+  - dialtone           full support, yealink.ko / sysfs API
+  - ringtone           full support, yealink.ko / sysfs API
+  - audio playback     full support, snd_usb_audio.ko / alsa API
+  - audio record       full support, snd_usb_audio.ko / alsa API
+
+For vendor documentation see http://www.yealink.com
+
+
+1. Compilation (stand alone version)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Currently only kernel 2.6.x.y versions are supported.
+In order to build the yealink.ko module do:
+
+  make
+
+If you encounter problems please check if in the MAKE_OPTS variable in
+the Makefile is pointing to the location where your kernel sources
+are located, default /usr/src/linux.
+
+
+
+2. keyboard features
+~~~~~~~~~~~~~~~~~~~~
+The current mapping in the kernel is provided by the map_p1k_to_key
+function:
+
+   Physical USB-P1K button layout      input events
+
+
+              up                            up
+        IN           OUT               left,   right
+             down                          down
+
+      pickup   C    hangup             enter, backspace, escape
+        1      2      3                        1, 2, 3
+        4      5      6                        4, 5, 6,
+        7      8      9                        7, 8, 9,
+        *      0      #                        *, 0, #,
+
+  The "up" and "down" keys, are symbolised by arrows on the button.
+  The "pickup" and "hangup" keys are symbolised by a green and red phone
+  on the button.
+
+
+3. LCD features
+~~~~~~~~~~~~~~~
+The LCD is divided and organised as a 3 line display:
+
+    |[]   [][]   [][]   [][]   in   |[][]
+    |[] M [][] D [][] : [][]   out  |[][]
+                              store
+
+    NEW REP         SU MO TU WE TH FR SA
+
+    [] [] [] [] [] [] [] [] [] [] [] []
+    [] [] [] [] [] [] [] [] [] [] [] []
+
+
+Line 1 Format (see below)      : 18.e8.M8.88...188
+       Icon names              :   M  D  :  IN OUT STORE
+Line 2  Format                 : .........
+       Icon name               : NEW REP SU MO TU WE TH FR SA
+Line 3  Format                 : 888888888888
+
+
+Format description:
+  From a user space perspective the world is seperated in "digits" and "icons".
+  A digit can have a character set, an icon can only be ON or OFF.
+
+  Format specifier
+    '8' :  Generic 7 segment digit with individual addressable segments
+
+    Reduced capabillity 7 segm digit, when segments are hard wired together.
+    '1' : 2 segments digit only able to produce a 1.
+    'e' : Most significant day of the month digit,
+          able to produce at least 1 2 3.
+    'M' : Most significant minute digit,
+          able to produce at least 0 1 2 3 4 5.
+
+    Icons or pictograms:
+    '.' : For example like AM, PM, SU, a 'dot' .. or other single segment
+         elements.
+
+
+4. Driver usage
+~~~~~~~~~~~~~~~
+For userland the following interfaces are available using the sysfs interface:
+  /sys/.../
+           line1       Read/Write, lcd line1
+           line2       Read/Write, lcd line2
+           line3       Read/Write, lcd line3
+
+          get_icons    Read, returns a set of available icons.
+          hide_icon    Write, hide the element by writing the icon name.
+          show_icon    Write, display the element by writing the icon name.
+
+          map_seg7     Read/Write, the 7 segments char set, common for all
+                       yealink phones. (see map_to_7segment.h)
+
+          ringtone     Write, upload binary representation of a ringtone,
+                       see yealink.c. status EXPERIMENTAL due to potential
+                       races between async. and sync usb calls.
+
+
+4.1 lineX
+~~~~~~~~~
+Reading /sys/../lineX will return the format string with its current value:
+
+  Example:
+  cat ./line3
+  888888888888
+  Linux Rocks!
+
+Writing to /sys/../lineX will set the coresponding LCD line.
+ - Excess characters are ignored.
+ - If less characters are written than allowed, the remaining digits are
+   unchanged.
+ - The tab '\t'and '\n' char does not overwrite the original content.
+ - Writing a space to an icon will always hide its content.
+
+  Example:
+  date +"%m.%e.%k:%M"  | sed 's/^0/ /' > ./line1
+
+  Will update the LCD with the current date & time.
+
+
+4.2 get_icons
+~~~~~~~~~~~~~
+Reading will return all available icon names and its current settings:
+
+  cat ./get_icons
+  on M
+  on D
+  on :
+     IN
+     OUT
+     STORE
+     NEW
+     REP
+     SU
+     MO
+     TU
+     WE
+     TH
+     FR
+     SA
+     LED
+     DIALTONE
+     RINGTONE
+
+
+4.3 show/hide icons
+~~~~~~~~~~~~~~~~~~~
+Writing to these files will update the state of the icon.
+Only one icon at a time can be updated.
+
+If an icon is also on a ./lineX the corresponding value is
+updated with the first letter of the icon.
+
+  Example - light up the store icon:
+  echo -n "STORE" > ./show_icon
+
+  cat ./line1
+  18.e8.M8.88...188
+               S
+
+  Example - sound the ringtone for 10 seconds:
+  echo -n RINGTONE > /sys/..../show_icon
+  sleep 10
+  echo -n RINGTONE > /sys/..../hide_icon
+
+
+5. Sound features
+~~~~~~~~~~~~~~~~~
+Sound is supported by the ALSA driver: snd_usb_audio
+
+One 16-bit channel with sample and playback rates of 8000 Hz is the practical
+limit of the device.
+
+  Example - recording test:
+  arecord -v -d 10 -r 8000 -f S16_LE -t wav  foobar.wav
+
+  Example - playback test:
+  aplay foobar.wav
+
+
+6. Credits & Acknowledgments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  - Olivier Vandorpe, for starting the usbb2k-api project doing much of
+       the reverse engineering.
+  - Martin Diehl, for pointing out how to handle USB memory allocation.
+  - Dmitry Torokhov, for the numerous code reviews and suggestions.
+
index 8e4e829210708b741327b1f3aeefd032bdd3dd6c..eaa46594f0211a4abdb420e9abb758c2ad95f26b 100644 (file)
@@ -116,6 +116,12 @@ M: ajk@iehk.rwth-aachen.de
 L:     linux-hams@vger.kernel.org
 S:     Maintained
 
+YEALINK PHONE DRIVER
+P:     Henk Vergonet
+M:     Henk.Vergonet@gmail.com
+L:     usbb2k-api-dev@nongnu.org
+S:     Maintained
+
 8139CP 10/100 FAST ETHERNET DRIVER
 P:     Jeff Garzik
 M:     jgarzik@pobox.com
@@ -1813,13 +1819,6 @@ M:       hch@infradead.org
 L:     linux-abi-devel@lists.sourceforge.net
 S:     Maintained
 
-PCI ID DATABASE
-P:     Martin Mares
-M:     mj@ucw.cz
-L:     pciids-devel@lists.sourceforge.net
-W:     http://pciids.sourceforge.net/
-S:     Maintained
-
 PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
 P:     Thomas Sailer
 M:     sailer@ife.ee.ethz.ch
index 804727853d2576dcd05f35120fbe3db3573f2335..e32fee50522076c7cfaf685d80690e2c0846c135 100644 (file)
@@ -373,12 +373,11 @@ marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
                irq += 0x80;                    /* offset for lsi       */
 
 #if 1
-               printk("PCI:%d:%d:%d (hose %d) [%s] is using MSI\n",
+               printk("PCI:%d:%d:%d (hose %d) is using MSI\n",
                       dev->bus->number, 
                       PCI_SLOT(dev->devfn), 
                       PCI_FUNC(dev->devfn),
-                      hose->index,
-                      pci_pretty_name (dev));
+                      hose->index);
                printk("  %d message(s) from 0x%04x\n", 
                       1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
                       msg_dat);
index 51f430cc2fbf5b7a08bcfed5bc6dee1e97fb1435..2786f7c34b3fc9e7627d613a00e63e9aaf40681d 100644 (file)
@@ -541,6 +541,103 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
        return ret;
 }
 
+#ifdef CONFIG_PM
+
+struct locomo_save_data {
+       u16     LCM_GPO;
+       u16     LCM_SPICT;
+       u16     LCM_GPE;
+       u16     LCM_ASD;
+       u16     LCM_SPIMD;
+};
+
+static int locomo_suspend(struct device *dev, u32 pm_message_t, u32 level)
+{
+       struct locomo *lchip = dev_get_drvdata(dev);
+       struct locomo_save_data *save;
+       unsigned long flags;
+
+       if (level != SUSPEND_DISABLE)
+               return 0;
+
+       save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
+       if (!save)
+               return -ENOMEM;
+
+       dev->power.saved_state = (void *) save;
+
+       spin_lock_irqsave(&lchip->lock, flags);
+
+       save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);     /* GPIO */
+       locomo_writel(0x00, lchip->base + LOCOMO_GPO);
+       save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPICT);   /* SPI */
+       locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
+       save->LCM_GPE     = locomo_readl(lchip->base + LOCOMO_GPE);     /* GPIO */
+       locomo_writel(0x00, lchip->base + LOCOMO_GPE);
+       save->LCM_ASD     = locomo_readl(lchip->base + LOCOMO_ASD);     /* ADSTART */
+       locomo_writel(0x00, lchip->base + LOCOMO_ASD);
+       save->LCM_SPIMD   = locomo_readl(lchip->base + LOCOMO_SPIMD);   /* SPI */
+       locomo_writel(0x3C14, lchip->base + LOCOMO_SPIMD);
+
+       locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
+       locomo_writel(0x00, lchip->base + LOCOMO_DAC);
+       locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
+
+       if ( (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88) )
+               locomo_writel(0x00, lchip->base + LOCOMO_C32K);         /* CLK32 off */
+       else
+               /* 18MHz already enabled, so no wait */
+               locomo_writel(0xc1, lchip->base + LOCOMO_C32K);         /* CLK32 on */
+
+       locomo_writel(0x00, lchip->base + LOCOMO_TADC);         /* 18MHz clock off*/
+       locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC);                   /* 22MHz/24MHz clock off */
+       locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);                      /* FL */
+
+       spin_unlock_irqrestore(&lchip->lock, flags);
+
+       return 0;
+}
+
+static int locomo_resume(struct device *dev, u32 level)
+{
+       struct locomo *lchip = dev_get_drvdata(dev);
+       struct locomo_save_data *save;
+       unsigned long r;
+       unsigned long flags;
+       
+       if (level != RESUME_ENABLE)
+               return 0;
+
+       save = (struct locomo_save_data *) dev->power.saved_state;
+       if (!save)
+               return 0;
+
+       spin_lock_irqsave(&lchip->lock, flags);
+
+       locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
+       locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPICT);
+       locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
+       locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
+       locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPIMD);
+
+       locomo_writel(0x00, lchip->base + LOCOMO_C32K);
+       locomo_writel(0x90, lchip->base + LOCOMO_TADC);
+
+       locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
+       r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+       r &= 0xFEFF;
+       locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+       locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
+
+       spin_unlock_irqrestore(&lchip->lock, flags);
+
+       dev->power.saved_state = NULL;
+       kfree(save);
+
+       return 0;
+}
+#endif
+
 /**
  *     locomo_probe - probe for a single LoCoMo chip.
  *     @phys_addr: physical address of device.
@@ -707,6 +804,10 @@ static struct device_driver locomo_device_driver = {
        .bus            = &platform_bus_type,
        .probe          = locomo_probe,
        .remove         = locomo_remove,
+#ifdef CONFIG_PM
+       .suspend        = locomo_suspend,
+       .resume         = locomo_resume,
+#endif
 };
 
 /*
index 96a794d8de842d2476a6776ce0bc46c0afd5369e..756348bf51702c982b17521ecfd66719842b845f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-git4
-# Wed Jun 22 15:56:42 2005
+# Linux kernel version: 2.6.13-git8
+# Thu Sep  8 19:24:02 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
@@ -31,6 +32,7 @@ CONFIG_SYSCTL=y
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
@@ -88,7 +90,9 @@ CONFIG_ARCH_S3C2410=y
 #
 # S3C24XX Implementations
 #
+CONFIG_MACH_ANUBIS=y
 CONFIG_ARCH_BAST=y
+CONFIG_BAST_PC104_IRQ=y
 CONFIG_ARCH_H1940=y
 CONFIG_MACH_N30=y
 CONFIG_ARCH_SMDK2410=y
@@ -112,6 +116,7 @@ CONFIG_S3C2410_DMA=y
 # CONFIG_S3C2410_DMA_DEBUG is not set
 # CONFIG_S3C2410_PM_DEBUG is not set
 # CONFIG_S3C2410_PM_CHECK is not set
+CONFIG_PM_SIMTEC=y
 CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
 
 #
@@ -149,7 +154,15 @@ CONFIG_ISA_DMA_API=y
 #
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
-# CONFIG_DISCONTIGMEM is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -185,6 +198,74 @@ CONFIG_BINFMT_AOUT=y
 CONFIG_PM=y
 CONFIG_APM=y
 
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
 #
 # Device Drivers
 #
@@ -258,6 +339,7 @@ CONFIG_MTD_ROM=y
 # CONFIG_MTD_IMPA7 is not set
 CONFIG_MTD_BAST=y
 CONFIG_MTD_BAST_MAXSIZE=4
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -312,7 +394,6 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
@@ -354,6 +435,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -376,76 +458,19 @@ CONFIG_BLK_DEV_IDE_BAST=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
 #
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_FIB_TRIE is not set
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -480,6 +505,8 @@ CONFIG_DM9000=m
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -562,7 +589,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 # CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
 # CONFIG_SERIAL_8250_RSA is not set
 
 #
@@ -605,7 +631,6 @@ CONFIG_S3C2410_RTC=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -628,7 +653,7 @@ CONFIG_I2C_ALGOBIT=m
 #
 # I2C Hardware Bus support
 #
-# CONFIG_I2C_ISA is not set
+CONFIG_I2C_ISA=m
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 CONFIG_I2C_S3C2410=y
@@ -636,14 +661,33 @@ CONFIG_I2C_S3C2410=y
 # CONFIG_I2C_PCA_ISA is not set
 
 #
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
 #
-CONFIG_I2C_SENSOR=m
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=m
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -662,27 +706,21 @@ CONFIG_SENSORS_LM85=m
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Other I2C Chip support
+# Misc devices
 #
-# CONFIG_SENSORS_DS1337 is not set
-CONFIG_SENSORS_EEPROM=m
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 
 #
-# Misc devices
+# Multimedia Capabilities Port drivers
 #
 
 #
@@ -731,7 +769,7 @@ CONFIG_DUMMY_CONSOLE=y
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB is not set
 
 #
@@ -749,6 +787,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -758,6 +797,7 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
 
 #
 # XFS support
@@ -765,6 +805,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -791,11 +832,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -812,8 +853,7 @@ CONFIG_JFFS_FS_VERBOSE=0
 # CONFIG_JFFS_PROC_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -835,6 +875,7 @@ CONFIG_NFS_FS=y
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -920,6 +961,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_MAGIC_SYSRQ is not set
 CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
index 112f1d68fb2b10b8be32171ec24dbdac6569af3f..e216ab8b9e8f7c048a83d057c7af36d7575b6826 100644 (file)
@@ -354,7 +354,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index 23c4da10101bd8e04c2f67b4f3ca5da9d150130f..5aeadfd721431466ba66307c3437a716b7b32b25 100644 (file)
@@ -219,7 +219,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index 7daa021676d0ac4aa688a8a1c1f546c9ab974000..44c56571d18365ba3b488175a0186444ea3e4da8 100644 (file)
@@ -52,7 +52,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index aa3a1fef563ee4c6ee780cbb446fdcbc6b72d195..28846c7edaaff3fa628a6f48baac8068ebfb51d1 100644 (file)
@@ -34,7 +34,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index 4b3199319e68b4c988f4f24edff2ded120405f24..a4a7c0125d030ea3e5482a4f716d05d08f4f5700 100644 (file)
@@ -90,7 +90,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index 098c817a7fb82a8e6fc7f38c24757ec620f6e47e..74bd2fd602d45181ed333bb3ee7fb9e9cc6aaf5e 100644 (file)
@@ -174,7 +174,7 @@ static struct resource ixp2000_uart_resource = {
 
 static struct platform_device ixp2000_serial_device = {
        .name           = "serial8250",
-       .id             = 0,
+       .id             = PLAT8250_DEV_PLATFORM,
        .dev            = {
                .platform_data          = ixp2000_serial_port,
        },
index 8b2f25322452b2c449ca02296128075e4a09918e..050c92768913b73d542dab88a3a3f883ace1ed38 100644 (file)
@@ -66,7 +66,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
 
 static struct platform_device coyote_uart = {
        .name           = "serial8250",
-       .id             = 0,
+       .id             = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = coyote_uart_data,
        },
index 3fd92c5cbaa83e21566595aab80090a93dcdd192..29a6d02fa851d4c19841545830af52788de21fbf 100644 (file)
@@ -93,7 +93,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
 
 static struct platform_device gtwx5715_uart_device = {
        .name           = "serial8250",
-       .id             = 0,
+       .id             = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = gtwx5715_uart_platform_data,
        },
index 6c14ff3c23a04706df50f9f8ad38e5179994e21b..ae1fa099d5fa4c965a8f089d8708d1b00b466224 100644 (file)
@@ -96,7 +96,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
 
 static struct platform_device ixdp425_uart = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev.platform_data      = ixdp425_uart_data,
        .num_resources          = 2,
        .resource               = ixdp425_uart_resources
index 7408ac94f771663005b2a52c609aea5c5d7afede..27fc2e8e5fca6d07cfa6659bc9562279de7084ac 100644 (file)
@@ -47,6 +47,14 @@ config MACH_OMAP_OSK
          TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
           if you have such a board.
 
+config OMAP_OSK_MISTRAL
+       bool "Mistral QVGA board Support"
+       depends on MACH_OMAP_OSK
+       help
+         The OSK supports an optional add-on board with a Quarter-VGA
+         touchscreen, PDA-ish buttons, a resume button, bicolor LED,
+         and camera connector.  Say Y here if you have this board.
+
 config MACH_OMAP_PERSEUS2
        bool "TI Perseus2"
        depends on ARCH_OMAP1 && ARCH_OMAP730
index d386fd913f0c617a890cf88838b739f9c1f53430..181a93deaaee4fa9cca5cbd5fbbca498e0930f3f 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := io.o id.o irq.o time.o serial.o
+obj-y := io.o id.o irq.o time.o serial.o devices.o
 led-y := leds.o
 
 # Specific board support
@@ -23,6 +23,7 @@ endif
 
 # LEDs support
 led-$(CONFIG_MACH_OMAP_H2)             += leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_H3)             += leds-h2p2-debug.o
 led-$(CONFIG_MACH_OMAP_INNOVATOR)      += leds-innovator.o
 led-$(CONFIG_MACH_OMAP_PERSEUS2)       += leds-h2p2-debug.o
 led-$(CONFIG_MACH_OMAP_OSK)            += leds-osk.o
index 122796ebe8f5a0b8425748464b756cc83813ef71..c209c7172a9aedf295c725e5ecf79bbb0b8ea02f 100644 (file)
@@ -48,19 +48,43 @@ static struct omap_usb_config generic1510_usb_config __initdata = {
 
 #if defined(CONFIG_ARCH_OMAP16XX)
 static struct omap_usb_config generic1610_usb_config __initdata = {
+#ifdef CONFIG_USB_OTG
+       .otg            = 1,
+#endif
        .register_host  = 1,
        .register_dev   = 1,
        .hmc_mode       = 16,
        .pins[0]        = 6,
 };
+
+static struct omap_mmc_config generic_mmc_config __initdata = {
+       .mmc [0] = {
+               .enabled        = 0,
+               .wire4          = 0,
+               .wp_pin         = -1,
+               .power_pin      = -1,
+               .switch_pin     = -1,
+       },
+       .mmc [1] = {
+               .enabled        = 0,
+               .wire4          = 0,
+               .wp_pin         = -1,
+               .power_pin      = -1,
+               .switch_pin     = -1,
+       },
+};
+
 #endif
 
 static struct omap_board_config_kernel generic_config[] = {
        { OMAP_TAG_USB,           NULL },
+       { OMAP_TAG_MMC,           &generic_mmc_config },
 };
 
 static void __init omap_generic_init(void)
 {
+       const struct omap_uart_config *uart_conf;
+
        /*
         * Make sure the serial ports are muxed on at this point.
         * You have to mux them off in device drivers later on
@@ -76,6 +100,18 @@ static void __init omap_generic_init(void)
                generic_config[0].data = &generic1610_usb_config;
        }
 #endif
+
+       uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+       if (uart_conf != NULL) {
+               unsigned int enabled_ports, i;
+
+               enabled_ports = uart_conf->enabled_uarts;
+               for (i = 0; i < 3; i++) {
+                       if (!(enabled_ports & (1 << i)))
+                               generic_serial_ports[i] = 0;
+               }
+       }
+
        omap_board_config = generic_config;
        omap_board_config_size = ARRAY_SIZE(generic_config);
        omap_serial_init(generic_serial_ports);
@@ -83,7 +119,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io()
+       omap_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
index f4983ee95ab4e29dbc112c97f7414b76b5e39293..d46a70063b0c61821088ae2c8f483c6a9356454f 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/mach/map.h>
 
 #include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
 #include <asm/arch/tc.h>
 #include <asm/arch/usb.h>
 #include <asm/arch/common.h>
@@ -80,8 +81,7 @@ static struct flash_platform_data h2_flash_data = {
 };
 
 static struct resource h2_flash_resource = {
-       .start          = OMAP_CS2B_PHYS,
-       .end            = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
+       /* This is on CS3, wherever it's mapped */
        .flags          = IORESOURCE_MEM,
 };
 
@@ -126,10 +126,9 @@ static void __init h2_init_smc91x(void)
                printk("Error requesting gpio 0 for smc91x irq\n");
                return;
        }
-       omap_set_gpio_edge_ctrl(0, OMAP_GPIO_FALLING_EDGE);
 }
 
-void h2_init_irq(void)
+static void __init h2_init_irq(void)
 {
        omap_init_irq();
        omap_gpio_init();
@@ -152,9 +151,13 @@ static struct omap_usb_config h2_usb_config __initdata = {
 };
 
 static struct omap_mmc_config h2_mmc_config __initdata = {
-       .mmc_blocks             = 1,
-       .mmc1_power_pin         = -1,   /* tps65010 gpio3 */
-       .mmc1_switch_pin        = OMAP_MPUIO(1),
+       .mmc [0] = {
+               .enabled        = 1,
+               .wire4          = 1,
+               .wp_pin         = OMAP_MPUIO(3),
+               .power_pin      = -1,   /* tps65010 gpio3 */
+               .switch_pin     = OMAP_MPUIO(1),
+       },
 };
 
 static struct omap_board_config_kernel h2_config[] = {
@@ -164,6 +167,16 @@ static struct omap_board_config_kernel h2_config[] = {
 
 static void __init h2_init(void)
 {
+       /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
+        * and NAND (either 16bit or 8bit) on CS3.
+        */
+       h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys();
+       h2_flash_resource.end += SZ_32M - 1;
+
+       /* MMC:  card detect and WP */
+       // omap_cfg_reg(U19_ARMIO1);            /* CD */
+       omap_cfg_reg(BALLOUT_V8_ARMIO3);        /* WP */
+
        platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
        omap_board_config = h2_config;
        omap_board_config_size = ARRAY_SIZE(h2_config);
index 7cd419d61b400889c56e39feb64572f888205b6b..2798613696fa7e0781609bb61132858d25089e27 100644 (file)
@@ -82,8 +82,7 @@ static struct flash_platform_data h3_flash_data = {
 };
 
 static struct resource h3_flash_resource = {
-       .start          = OMAP_CS2B_PHYS,
-       .end            = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
+       /* This is on CS3, wherever it's mapped */
        .flags          = IORESOURCE_MEM,
 };
 
@@ -161,13 +160,26 @@ static struct omap_usb_config h3_usb_config __initdata = {
        .pins[1]        = 3,
 };
 
+static struct omap_mmc_config h3_mmc_config __initdata = {
+       .mmc[0] = {
+               .enabled        = 1,
+               .power_pin      = -1,   /* tps65010 GPIO4 */
+               .switch_pin     = OMAP_MPUIO(1),
+       },
+};
+
 static struct omap_board_config_kernel h3_config[] = {
        { OMAP_TAG_USB,  &h3_usb_config },
+       { OMAP_TAG_MMC,  &h3_mmc_config },
 };
 
 static void __init h3_init(void)
 {
+       h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys();
+       h3_flash_resource.end += OMAP_CS3_SIZE - 1;
        (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+       omap_board_config = h3_config;
+       omap_board_config_size = ARRAY_SIZE(h3_config);
 }
 
 static void __init h3_init_smc91x(void)
@@ -177,7 +189,6 @@ static void __init h3_init_smc91x(void)
                printk("Error requesting gpio 40 for smc91x irq\n");
                return;
        }
-       omap_set_gpio_edge_ctrl(40, OMAP_GPIO_FALLING_EDGE);
 }
 
 void h3_init_irq(void)
index 91de60a91ef86a04ae32e3d47a675c32752f33be..df0312b596e484a6e79cf5356c767020e8d55c54 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
+#include <asm/arch/mux.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/tc.h>
@@ -173,7 +174,6 @@ static void __init innovator_init_smc91x(void)
                        printk("Error requesting gpio 0 for smc91x irq\n");
                        return;
                }
-               omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
        }
 }
 
@@ -220,8 +220,19 @@ static struct omap_usb_config h2_usb_config __initdata = {
 };
 #endif
 
+static struct omap_mmc_config innovator_mmc_config __initdata = {
+       .mmc [0] = {
+               .enabled        = 1,
+               .wire4          = 1,
+               .wp_pin         = OMAP_MPUIO(3),
+               .power_pin      = -1,   /* FPGA F3 UIO42 */
+               .switch_pin     = -1,   /* FPGA F4 UIO43 */
+       },
+};
+
 static struct omap_board_config_kernel innovator_config[] = {
        { OMAP_TAG_USB,         NULL },
+       { OMAP_TAG_MMC,         &innovator_mmc_config },
 };
 
 static void __init innovator_init(void)
index 6750b2014092d8ced13f0f28356d2e2ad31a49a8..d904e643f5ec2c30fabf5d8438f5e40cdec82ad1 100644 (file)
@@ -75,16 +75,15 @@ static void __init netstar_init(void)
        mdelay(50);     /* 50ms until PHY ready */
        /* smc91x interrupt pin */
        omap_request_gpio(8);
-       omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
 
        omap_request_gpio(12);
        omap_request_gpio(13);
        omap_request_gpio(14);
        omap_request_gpio(15);
-       omap_set_gpio_edge_ctrl(12, OMAP_GPIO_FALLING_EDGE);
-       omap_set_gpio_edge_ctrl(13, OMAP_GPIO_FALLING_EDGE);
-       omap_set_gpio_edge_ctrl(14, OMAP_GPIO_FALLING_EDGE);
-       omap_set_gpio_edge_ctrl(15, OMAP_GPIO_FALLING_EDGE);
+       set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
+       set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
+       set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
+       set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
 
        platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
 
index 6844e536c698da5820a3b5f05d8ae5e085f67402..21103df50415a7007428f04224b54c8c2127b023 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/interrupt.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/mach/flash.h>
 
 #include <asm/arch/gpio.h>
 #include <asm/arch/usb.h>
 #include <asm/arch/tc.h>
 #include <asm/arch/common.h>
 
-static struct map_desc osk5912_io_desc[] __initdata = {
-{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
-       MT_DEVICE },
+static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
+
+static struct mtd_partition osk_partitions[] = {
+       /* bootloader (U-Boot, etc) in first sector */
+       {
+             .name             = "bootloader",
+             .offset           = 0,
+             .size             = SZ_128K,
+             .mask_flags       = MTD_WRITEABLE, /* force read-only */
+       },
+       /* bootloader params in the next sector */
+       {
+             .name             = "params",
+             .offset           = MTDPART_OFS_APPEND,
+             .size             = SZ_128K,
+             .mask_flags       = 0,
+       }, {
+             .name             = "kernel",
+             .offset           = MTDPART_OFS_APPEND,
+             .size             = SZ_2M,
+             .mask_flags       = 0
+       }, {
+             .name             = "filesystem",
+             .offset           = MTDPART_OFS_APPEND,
+             .size             = MTDPART_SIZ_FULL,
+             .mask_flags       = 0
+       }
 };
 
-static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
+static struct flash_platform_data osk_flash_data = {
+       .map_name       = "cfi_probe",
+       .width          = 2,
+       .parts          = osk_partitions,
+       .nr_parts       = ARRAY_SIZE(osk_partitions),
+};
+
+static struct resource osk_flash_resource = {
+       /* this is on CS3, wherever it's mapped */
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device osk5912_flash_device = {
+       .name           = "omapflash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &osk_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &osk_flash_resource,
+};
 
 static struct resource osk5912_smc91x_resources[] = {
        [0] = {
@@ -86,9 +135,16 @@ static struct platform_device osk5912_cf_device = {
        .resource       = osk5912_cf_resources,
 };
 
+static struct platform_device osk5912_mcbsp1_device = {
+       .name           = "omap_mcbsp",
+       .id             = 1,
+};
+
 static struct platform_device *osk5912_devices[] __initdata = {
+       &osk5912_flash_device,
        &osk5912_smc91x_device,
        &osk5912_cf_device,
+       &osk5912_mcbsp1_device,
 };
 
 static void __init osk_init_smc91x(void)
@@ -97,7 +153,6 @@ static void __init osk_init_smc91x(void)
                printk("Error requesting gpio 0 for smc91x irq\n");
                return;
        }
-       omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
 
        /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
        EMIFS_CCS(1) |= 0x2;
@@ -110,11 +165,11 @@ static void __init osk_init_cf(void)
                printk("Error requesting gpio 62 for CF irq\n");
                return;
        }
-       /* it's really active-low */
-       omap_set_gpio_edge_ctrl(62, OMAP_GPIO_FALLING_EDGE);
+       /* the CF I/O IRQ is really active-low */
+       set_irq_type(OMAP_GPIO_IRQ(62), IRQT_FALLING);
 }
 
-void osk_init_irq(void)
+static void __init osk_init_irq(void)
 {
        omap_init_irq();
        omap_gpio_init();
@@ -142,18 +197,69 @@ static struct omap_board_config_kernel osk_config[] = {
        { OMAP_TAG_USB,           &osk_usb_config },
 };
 
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+
+#ifdef CONFIG_PM
+static irqreturn_t
+osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
+{
+       return IRQ_HANDLED;
+}
+#endif
+
+static void __init osk_mistral_init(void)
+{
+       /* FIXME here's where to feed in framebuffer, touchpad, and
+        * keyboard setup ...  not in the drivers for those devices!
+        *
+        * NOTE:  we could actually tell if there's a Mistral board
+        * attached, e.g. by trying to read something from the ads7846.
+        * But this is too early for that...
+        */
+
+       /* the sideways button (SW1) is for use as a "wakeup" button */
+       omap_cfg_reg(N15_1610_MPUIO2);
+       if (omap_request_gpio(OMAP_MPUIO(2)) == 0) {
+               int ret = 0;
+               omap_set_gpio_direction(OMAP_MPUIO(2), 1);
+               set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING);
+#ifdef CONFIG_PM
+               /* share the IRQ in case someone wants to use the
+                * button for more than wakeup from system sleep.
+                */
+               ret = request_irq(OMAP_GPIO_IRQ(OMAP_MPUIO(2)),
+                               &osk_mistral_wake_interrupt,
+                               SA_SHIRQ, "mistral_wakeup",
+                               &osk_mistral_wake_interrupt);
+               if (ret != 0) {
+                       omap_free_gpio(OMAP_MPUIO(2));
+                       printk(KERN_ERR "OSK+Mistral: no wakeup irq, %d?\n",
+                               ret);
+               } else
+                       enable_irq_wake(OMAP_GPIO_IRQ(OMAP_MPUIO(2)));
+#endif
+       } else
+               printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
+}
+#else
+static void __init osk_mistral_init(void) { }
+#endif
+
 static void __init osk_init(void)
 {
+       osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
+       osk_flash_resource.end += SZ_32M - 1;
        platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
        omap_board_config = osk_config;
        omap_board_config_size = ARRAY_SIZE(osk_config);
        USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+
+       osk_mistral_init();
 }
 
 static void __init osk_map_io(void)
 {
        omap_map_common_io();
-       iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc));
        omap_serial_init(osk_serial_ports);
 }
 
index 213317392d9b1c4066fca07e8cb7bfd1714d9ea9..107c68c8ab54b796fe7f5271adb11a40c52de760 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
+#include <asm/arch/tc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/fpga.h>
@@ -83,8 +84,8 @@ static struct flash_platform_data p2_flash_data = {
 };
 
 static struct resource p2_flash_resource = {
-       .start          = OMAP_FLASH_0_START,
-       .end            = OMAP_FLASH_0_START + OMAP_FLASH_0_SIZE - 1,
+       .start          = OMAP_CS0_PHYS,
+       .end            = OMAP_CS0_PHYS + SZ_32M - 1,
        .flags          = IORESOURCE_MEM,
 };
 
index e422819889904124bf56e84fd577a90ba5c9bca9..bf30b1acda0b97a1c9795a0006622c7db6935265 100644 (file)
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
+#include <asm/arch/common.h>
 #include <asm/arch/gpio.h>
-#include <asm/arch/tc.h>
 #include <asm/arch/mux.h>
+#include <asm/arch/tc.h>
 #include <asm/arch/usb.h>
-#include <asm/arch/common.h>
 
 extern void omap_init_time(void);
 extern int omap_gpio_init(void);
@@ -74,7 +75,7 @@ static struct plat_serial8250_port voiceblue_ports[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 1,
+       .id                     = PLAT8250_DEV_PLATFORM1,
        .dev                    = {
                .platform_data  = voiceblue_ports,
        },
@@ -86,6 +87,27 @@ static int __init ext_uart_init(void)
 }
 arch_initcall(ext_uart_init);
 
+static struct flash_platform_data voiceblue_flash_data = {
+       .map_name       = "cfi_probe",
+       .width          = 2,
+};
+
+static struct resource voiceblue_flash_resource = {
+       .start  = OMAP_CS0_PHYS,
+       .end    = OMAP_CS0_PHYS + SZ_32M - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device voiceblue_flash_device = {
+       .name           = "omapflash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &voiceblue_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &voiceblue_flash_resource,
+};
+
 static struct resource voiceblue_smc91x_resources[] = {
        [0] = {
                .start  = OMAP_CS2_PHYS + 0x300,
@@ -107,6 +129,7 @@ static struct platform_device voiceblue_smc91x_device = {
 };
 
 static struct platform_device *voiceblue_devices[] __initdata = {
+       &voiceblue_flash_device,
        &voiceblue_smc91x_device,
 };
 
@@ -119,8 +142,17 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
        .pins[2]        = 6,
 };
 
+static struct omap_mmc_config voiceblue_mmc_config __initdata = {
+       .mmc[0] = {
+               .enabled        = 1,
+               .power_pin      = 2,
+               .switch_pin     = -1,
+       },
+};
+
 static struct omap_board_config_kernel voiceblue_config[] = {
        { OMAP_TAG_USB, &voiceblue_usb_config },
+       { OMAP_TAG_MMC, &voiceblue_mmc_config },
 };
 
 static void __init voiceblue_init_irq(void)
@@ -131,9 +163,6 @@ static void __init voiceblue_init_irq(void)
 
 static void __init voiceblue_init(void)
 {
-       /* There is a good chance board is going up, so enable Power LED
-        * (it is connected through invertor) */
-       omap_writeb(0x00, OMAP_LPG1_LCR);
        /* Watchdog */
        omap_request_gpio(0);
        /* smc91x reset */
@@ -145,7 +174,6 @@ static void __init voiceblue_init(void)
        mdelay(50);     /* 50ms until PHY ready */
        /* smc91x interrupt pin */
        omap_request_gpio(8);
-       omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
        /* 16C554 reset*/
        omap_request_gpio(6);
        omap_set_gpio_direction(6, 0);
@@ -155,14 +183,19 @@ static void __init voiceblue_init(void)
        omap_request_gpio(13);
        omap_request_gpio(14);
        omap_request_gpio(15);
-       omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE);
-       omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
-       omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE);
-       omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE);
+       set_irq_type(OMAP_GPIO_IRQ(12), IRQT_RISING);
+       set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
+       set_irq_type(OMAP_GPIO_IRQ(14), IRQT_RISING);
+       set_irq_type(OMAP_GPIO_IRQ(15), IRQT_RISING);
 
        platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
        omap_board_config = voiceblue_config;
        omap_board_config_size = ARRAY_SIZE(voiceblue_config);
+
+       /* There is a good chance board is going up, so enable power LED
+        * (it is connected through invertor) */
+       omap_writeb(0x00, OMAP_LPG1_LCR);
+       omap_writeb(0x00, OMAP_LPG1_PMR);       /* Disable clock */
 }
 
 static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
@@ -184,9 +217,9 @@ static int panic_event(struct notifier_block *this, unsigned long event,
        if (test_and_set_bit(MACHINE_PANICED, &machine_state))
                return NOTIFY_DONE;
 
-       /* Flash Power LED
-        * (TODO: Enable clock right way (enabled in bootloader already)) */
+       /* Flash power LED */
        omap_writeb(0x78, OMAP_LPG1_LCR);
+       omap_writeb(0x01, OMAP_LPG1_PMR);       /* Enable clock */
 
        return NOTIFY_DONE;
 }
@@ -195,15 +228,14 @@ static struct notifier_block panic_block = {
        .notifier_call  = panic_event,
 };
 
-static int __init setup_notifier(void)
+static int __init voiceblue_setup(void)
 {
        /* Setup panic notifier */
        notifier_chain_register(&panic_notifier_list, &panic_block);
 
        return 0;
 }
-
-postcore_initcall(setup_notifier);
+postcore_initcall(voiceblue_setup);
 
 static int wdt_gpio_state;
 
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
new file mode 100644 (file)
index 0000000..e8b3981
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * linux/arch/arm/mach-omap1/devices.c
+ *
+ * OMAP1 platform device setup/initialization
+ *
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
+
+
+static void omap_nop_release(struct device *dev)
+{
+        /* Nothing */
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if    defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define        OMAP_I2C_BASE           0xfffb3800
+
+static struct resource i2c_resources[] = {
+       {
+               .start          = OMAP_I2C_BASE,
+               .end            = OMAP_I2C_BASE + 0x3f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_I2C,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+/* DMA not used; works around erratum writing to non-empty i2c fifo */
+
+static struct platform_device omap_i2c_device = {
+        .name           = "i2c_omap",
+        .id             = -1,
+        .dev = {
+                .release        = omap_nop_release,
+        },
+       .num_resources  = ARRAY_SIZE(i2c_resources),
+       .resource       = i2c_resources,
+};
+
+static void omap_init_i2c(void)
+{
+       /* FIXME define and use a boot tag, in case of boards that
+        * either don't wire up I2C, or chips that mux it differently...
+        * it can include clocking and address info, maybe more.
+        */
+       omap_cfg_reg(I2C_SCL);
+       omap_cfg_reg(I2C_SDA);
+
+       (void) platform_device_register(&omap_i2c_device);
+}
+#else
+static inline void omap_init_i2c(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if    defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
+
+static u64 irda_dmamask = 0xffffffff;
+
+static struct platform_device omap1610ir_device = {
+       .name = "omap1610-ir",
+       .id = -1,
+       .dev = {
+               .release        = omap_nop_release,
+               .dma_mask       = &irda_dmamask,
+       },
+};
+
+static void omap_init_irda(void)
+{
+       /* FIXME define and use a boot tag, members something like:
+        *  u8          uart;           // uart1, or uart3
+        * ... but driver only handles uart3 for now
+        *  s16         fir_sel;        // gpio for SIR vs FIR
+        * ... may prefer a callback for SIR/MIR/FIR mode select;
+        * while h2 uses a GPIO, H3 uses a gpio expander
+        */
+       if (machine_is_omap_h2()
+                       || machine_is_omap_h3())
+               (void) platform_device_register(&omap1610ir_device);
+}
+#else
+static inline void omap_init_irda(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if    defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define        OMAP_MMC1_BASE          0xfffb7800
+#define        OMAP_MMC2_BASE          0xfffb7c00      /* omap16xx only */
+
+static struct omap_mmc_conf mmc1_conf;
+
+static u64 mmc1_dmamask = 0xffffffff;
+
+static struct resource mmc1_resources[] = {
+       {
+               .start          = IO_ADDRESS(OMAP_MMC1_BASE),
+               .end            = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_MMC,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mmc_omap_device1 = {
+       .name           = "mmci-omap",
+       .id             = 1,
+       .dev = {
+               .release        = omap_nop_release,
+               .dma_mask       = &mmc1_dmamask,
+               .platform_data  = &mmc1_conf,
+       },
+       .num_resources  = ARRAY_SIZE(mmc1_resources),
+       .resource       = mmc1_resources,
+};
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+static struct omap_mmc_conf mmc2_conf;
+
+static u64 mmc2_dmamask = 0xffffffff;
+
+static struct resource mmc2_resources[] = {
+       {
+               .start          = IO_ADDRESS(OMAP_MMC2_BASE),
+               .end            = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_1610_MMC2,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mmc_omap_device2 = {
+       .name           = "mmci-omap",
+       .id             = 2,
+       .dev = {
+               .release        = omap_nop_release,
+               .dma_mask       = &mmc2_dmamask,
+               .platform_data  = &mmc2_conf,
+       },
+       .num_resources  = ARRAY_SIZE(mmc2_resources),
+       .resource       = mmc2_resources,
+};
+#endif
+
+static void __init omap_init_mmc(void)
+{
+       const struct omap_mmc_config    *mmc_conf;
+       const struct omap_mmc_conf      *mmc;
+
+       /* NOTE:  assumes MMC was never (wrongly) enabled */
+       mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+       if (!mmc_conf)
+               return;
+
+       /* block 1 is always available and has just one pinout option */
+       mmc = &mmc_conf->mmc[0];
+       if (mmc->enabled) {
+               omap_cfg_reg(MMC_CMD);
+               omap_cfg_reg(MMC_CLK);
+               omap_cfg_reg(MMC_DAT0);
+               if (cpu_is_omap1710()) {
+                     omap_cfg_reg(M15_1710_MMC_CLKI);
+                     omap_cfg_reg(P19_1710_MMC_CMDDIR);
+                     omap_cfg_reg(P20_1710_MMC_DATDIR0);
+               }
+               if (mmc->wire4) {
+                       omap_cfg_reg(MMC_DAT1);
+                       /* NOTE:  DAT2 can be on W10 (here) or M15 */
+                       if (!mmc->nomux)
+                               omap_cfg_reg(MMC_DAT2);
+                       omap_cfg_reg(MMC_DAT3);
+               }
+               mmc1_conf = *mmc;
+               (void) platform_device_register(&mmc_omap_device1);
+       }
+
+#ifdef CONFIG_ARCH_OMAP16XX
+       /* block 2 is on newer chips, and has many pinout options */
+       mmc = &mmc_conf->mmc[1];
+       if (mmc->enabled) {
+               if (!mmc->nomux) {
+                       omap_cfg_reg(Y8_1610_MMC2_CMD);
+                       omap_cfg_reg(Y10_1610_MMC2_CLK);
+                       omap_cfg_reg(R18_1610_MMC2_CLKIN);
+                       omap_cfg_reg(W8_1610_MMC2_DAT0);
+                       if (mmc->wire4) {
+                               omap_cfg_reg(V8_1610_MMC2_DAT1);
+                               omap_cfg_reg(W15_1610_MMC2_DAT2);
+                               omap_cfg_reg(R10_1610_MMC2_DAT3);
+                       }
+
+                       /* These are needed for the level shifter */
+                       omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+                       omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+                       omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+               }
+
+               /* Feedback clock must be set on OMAP-1710 MMC2 */
+               if (cpu_is_omap1710())
+                       omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+                                    MOD_CONF_CTRL_1);
+               mmc2_conf = *mmc;
+               (void) platform_device_register(&mmc_omap_device2);
+       }
+#endif
+       return;
+}
+#else
+static inline void omap_init_mmc(void) {}
+#endif
+
+#if    defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
+
+#define        OMAP_RTC_BASE           0xfffb4800
+
+static struct resource rtc_resources[] = {
+       {
+               .start          = OMAP_RTC_BASE,
+               .end            = OMAP_RTC_BASE + 0x5f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_RTC_TIMER,
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = INT_RTC_ALARM,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device omap_rtc_device = {
+       .name           = "omap_rtc",
+       .id             = -1,
+       .dev = {
+               .release        = omap_nop_release,
+       },
+       .num_resources  = ARRAY_SIZE(rtc_resources),
+       .resource       = rtc_resources,
+};
+
+static void omap_init_rtc(void)
+{
+       (void) platform_device_register(&omap_rtc_device);
+}
+#else
+static inline void omap_init_rtc(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if    defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
+
+#define        OMAP_WDT_BASE           0xfffeb000
+
+static struct resource wdt_resources[] = {
+       {
+               .start          = OMAP_WDT_BASE,
+               .end            = OMAP_WDT_BASE + 0x4f,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device omap_wdt_device = {
+       .name      = "omap1610_wdt",
+       .id          = -1,
+       .dev = {
+               .release        = omap_nop_release,
+       },
+       .num_resources  = ARRAY_SIZE(wdt_resources),
+       .resource       = wdt_resources,
+};
+
+static void omap_init_wdt(void)
+{
+       (void) platform_device_register(&omap_wdt_device);
+}
+#else
+static inline void omap_init_wdt(void) {}
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+ *
+ *  (a) Does any "standard config" pin muxing needed.  Board-specific
+ *     code will have muxed GPIO pins and done "nonstandard" setup;
+ *     that code could live in the boot loader.
+ *  (b) Populating board-specific platform_data with the data drivers
+ *     rely on to handle wiring variations.
+ *  (c) Creating platform devices as meaningful on this board and
+ *     with this kernel configuration.
+ *
+ * Claiming GPIOs, and setting their direction and initial values, is the
+ * responsibility of the device drivers.  So is responding to probe().
+ *
+ * Board-specific knowlege like creating devices or pin setup is to be
+ * kept out of drivers as much as possible.  In particular, pin setup
+ * may be handled by the boot loader, and drivers should expect it will
+ * normally have been done by the time they're probed.
+ */
+static int __init omap_init_devices(void)
+{
+       /* please keep these calls, and their implementations above,
+        * in alphabetical order so they're easier to sort through.
+        */
+       omap_init_i2c();
+       omap_init_irda();
+       omap_init_mmc();
+       omap_init_rtc();
+       omap_init_wdt();
+
+       return 0;
+}
+arch_initcall(omap_init_devices);
+
index c12a7833562570a4e88497c85b5381f3dd0ad080..aca2a120813ae9f95456749a36939d447019a292 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/fpga.c
+ * linux/arch/arm/mach-omap1/fpga.c
  *
  * Interrupt handler for OMAP-1510 Innovator FPGA
  *
@@ -181,7 +181,7 @@ void omap1510_fpga_init_irq(void)
         */
        omap_request_gpio(13);
        omap_set_gpio_direction(13, 1);
-       omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
+       set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
        set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
 }
 
index 207df0fe934dacbc3c65a9d6fe8e8a3932837c54..eb8261d7dead9b0eb99ae98887f6a540c79450f8 100644 (file)
@@ -19,6 +19,7 @@
 
 extern int clk_init(void);
 extern void omap_check_revision(void);
+extern void omap_sram_init(void);
 
 /*
  * The machine specific code may provide the extra mapping besides the
@@ -32,7 +33,6 @@ static struct map_desc omap_io_desc[] __initdata = {
 static struct map_desc omap730_io_desc[] __initdata = {
  { OMAP730_DSP_BASE,    OMAP730_DSP_START,    OMAP730_DSP_SIZE,    MT_DEVICE },
  { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
- { OMAP730_SRAM_BASE,   OMAP730_SRAM_START,   OMAP730_SRAM_SIZE,   MT_DEVICE }
 };
 #endif
 
@@ -40,27 +40,13 @@ static struct map_desc omap730_io_desc[] __initdata = {
 static struct map_desc omap1510_io_desc[] __initdata = {
  { OMAP1510_DSP_BASE,    OMAP1510_DSP_START,    OMAP1510_DSP_SIZE,    MT_DEVICE },
  { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
- { OMAP1510_SRAM_BASE,   OMAP1510_SRAM_START,   OMAP1510_SRAM_SIZE,   MT_DEVICE }
 };
 #endif
 
 #if defined(CONFIG_ARCH_OMAP16XX)
-static struct map_desc omap1610_io_desc[] __initdata = {
+static struct map_desc omap16xx_io_desc[] __initdata = {
  { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
  { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
- { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP1610_SRAM_SIZE,   MT_DEVICE }
-};
-
-static struct map_desc omap5912_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
-/*
- * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
- * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
- * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
- * can be used.
- */
- { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
 };
 #endif
 
@@ -86,14 +72,13 @@ static void __init _omap_map_io(void)
        }
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
-       if (cpu_is_omap1610() || cpu_is_omap1710()) {
-               iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
-       }
-       if (cpu_is_omap5912()) {
-               iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
+       if (cpu_is_omap16xx()) {
+               iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc));
        }
 #endif
 
+       omap_sram_init();
+
        /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
         * on a Posted Write in the TIPB Bridge".
         */
@@ -108,8 +93,9 @@ static void __init _omap_map_io(void)
 /*
  * This should only get called from board specific init
  */
-void omap_map_common_io(void)
+void __init omap_map_common_io(void)
 {
        if (!initialized)
                _omap_map_io();
 }
+
index afd5d67e4ae73625e25a88bcf93ef79b34323602..192ce6055faabb13f31c6e49c6c4b3b05b3dda9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/irq.c
+ * linux/arch/arm/mach-omap1/irq.c
  *
  * Interrupt handler for all OMAP boards
  *
index ec0d8285f243dcaf5885130c10cac1108b2ac448..be283cda63dda9f5817c0e9befce16d7e135974c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/leds-h2p2-debug.c
+ * linux/arch/arm/mach-omap1/leds-h2p2-debug.c
  *
  * Copyright 2003 by Texas Instruments Incorporated
  *
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
+#include <linux/version.h>
 
 #include <asm/io.h>
 #include <asm/hardware.h>
index 8043b7d0f66e7008afc755051a959cc80275744d..c8ffd1ddcdedff180bfc682560419236a16568bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/leds-innovator.c
+ * linux/arch/arm/mach-omap1/leds-innovator.c
  */
 #include <linux/config.h>
 #include <linux/init.h>
index 4a0e8b9d4fc37d5748e067c01ff0b84a59d1e1d2..2c8bda847c186e3a47ecf8518000bc1d8406dd91 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/leds-osk.c
+ * linux/arch/arm/mach-omap1/leds-osk.c
  *
  * LED driver for OSK, and optionally Mistral QVGA, boards
  */
@@ -64,7 +64,7 @@ static void tps_work(void *unused)
 
 static DECLARE_WORK(work, tps_work, NULL);
 
-#ifdef CONFIG_FB_OMAP
+#ifdef CONFIG_OMAP_OSK_MISTRAL
 
 /* For now, all system indicators require the Mistral board, since that
  * LED can be manipulated without a task context.  This LED is either red,
@@ -127,7 +127,7 @@ void osk_leds_event(led_event_t evt)
                hw_led_state = 0;
                break;
 
-#ifdef CONFIG_FB_OMAP
+#ifdef CONFIG_OMAP_OSK_MISTRAL
 
        case led_timer:
                hw_led_state ^= TIMER_LED;
@@ -144,7 +144,7 @@ void osk_leds_event(led_event_t evt)
                mistral_setled();
                break;
 
-#endif /* CONFIG_FB_OMAP */
+#endif /* CONFIG_OMAP_OSK_MISTRAL */
 
        /* "green" == tps LED1 (leftmost, normally power-good)
         * works only with DC adapter, not on battery power!
index 8ab21fe98e1bc388c0e3a40a4b83bb919a88c622..5c6b1bb6e722deda5bf715e5435498b2846c7228 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/leds.c
+ * linux/arch/arm/mach-omap1/leds.c
  *
  * OMAP LEDs dispatcher
  */
@@ -20,7 +20,9 @@ omap_leds_init(void)
        if (machine_is_omap_innovator())
                leds_event = innovator_leds_event;
 
-       else if (machine_is_omap_h2() || machine_is_omap_perseus2())
+       else if (machine_is_omap_h2()
+                       || machine_is_omap_h3()
+                       || machine_is_omap_perseus2())
                leds_event = h2p2_dbg_leds_event;
 
        else if (machine_is_omap_osk())
@@ -30,8 +32,12 @@ omap_leds_init(void)
                return -1;
 
        if (machine_is_omap_h2()
+                       || machine_is_omap_h3()
                        || machine_is_omap_perseus2()
-                       || machine_is_omap_osk()) {
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+                       || machine_is_omap_osk()
+#endif
+                       ) {
 
                /* LED1/LED2 pins can be used as GPIO (as done here), or by
                 * the LPG (works even in deep sleep!), to drive a bicolor
index 214e5d17c8b56eed98458405885ccaf573c7c318..40c4f7c40e73369d6b7f052ca66e966012b99d67 100644 (file)
 
 #include <asm/arch/board.h>
 #include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
 #include <asm/arch/fpga.h>
+#ifdef CONFIG_PM
+#include <asm/arch/pm.h>
+#endif
 
 static struct clk * uart1_ck = NULL;
 static struct clk * uart2_ck = NULL;
@@ -94,7 +98,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
@@ -193,6 +197,86 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
        }
 }
 
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+
+static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id,
+                                             struct pt_regs *regs)
+{
+       /* Need to do something with serial port right after wake-up? */
+       return IRQ_HANDLED;
+}
+
+/*
+ * Reroutes serial RX lines to GPIO lines for the duration of
+ * sleep to allow waking up the device from serial port even
+ * in deep sleep.
+ */
+void omap_serial_wake_trigger(int enable)
+{
+       if (!cpu_is_omap16xx())
+               return;
+
+       if (uart1_ck != NULL) {
+               if (enable)
+                       omap_cfg_reg(V14_16XX_GPIO37);
+               else
+                       omap_cfg_reg(V14_16XX_UART1_RX);
+       }
+       if (uart2_ck != NULL) {
+               if (enable)
+                       omap_cfg_reg(R9_16XX_GPIO18);
+               else
+                       omap_cfg_reg(R9_16XX_UART2_RX);
+       }
+       if (uart3_ck != NULL) {
+               if (enable)
+                       omap_cfg_reg(L14_16XX_GPIO49);
+               else
+                       omap_cfg_reg(L14_16XX_UART3_RX);
+       }
+}
+
+static void __init omap_serial_set_port_wakeup(int gpio_nr)
+{
+       int ret;
+
+       ret = omap_request_gpio(gpio_nr);
+       if (ret < 0) {
+               printk(KERN_ERR "Could not request UART wake GPIO: %i\n",
+                      gpio_nr);
+               return;
+       }
+       omap_set_gpio_direction(gpio_nr, 1);
+       set_irq_type(OMAP_GPIO_IRQ(gpio_nr), IRQT_RISING);
+       ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt,
+                         0, "serial wakeup", NULL);
+       if (ret) {
+               omap_free_gpio(gpio_nr);
+               printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
+                      gpio_nr);
+               return;
+       }
+       enable_irq_wake(OMAP_GPIO_IRQ(gpio_nr));
+}
+
+static int __init omap_serial_wakeup_init(void)
+{
+       if (!cpu_is_omap16xx())
+               return 0;
+
+       if (uart1_ck != NULL)
+               omap_serial_set_port_wakeup(37);
+       if (uart2_ck != NULL)
+               omap_serial_set_port_wakeup(18);
+       if (uart3_ck != NULL)
+               omap_serial_set_port_wakeup(49);
+
+       return 0;
+}
+late_initcall(omap_serial_wakeup_init);
+
+#endif /* CONFIG_OMAP_SERIAL_WAKE */
+
 static int __init omap_init(void)
 {
        return platform_device_register(&serial_device);
index d540539c9bbb7e23fd27e3d4272a481ce21f136a..191a9b1ee9b7168f1ef3b561b08f732e55b4c2bf 100644 (file)
@@ -247,13 +247,6 @@ unsigned long long sched_clock(void)
 #define OMAP_32K_TIMER_TCR             0x04
 
 #define OMAP_32K_TICKS_PER_HZ          (32768 / HZ)
-#if (32768 % HZ) != 0
-/* We cannot ignore modulo.
- * Potential error can be as high as several percent.
- */
-#define OMAP_32K_TICK_MODULO           (32768 % HZ)
-static unsigned modulo_count = 0; /* Counts 1/HZ units */
-#endif
 
 /*
  * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
@@ -296,13 +289,22 @@ static inline void omap_32k_timer_stop(void)
 }
 
 /*
- * Rounds down to nearest usec
+ * Rounds down to nearest usec. Note that this will overflow for larger values.
  */
 static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
 {
        return (ticks_32k * 5*5*5*5*5*5) >> 9;
 }
 
+/*
+ * Rounds down to nearest nsec.
+ */
+static inline unsigned long long
+omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
+{
+       return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
+}
+
 static unsigned long omap_32k_last_tick = 0;
 
 /*
@@ -314,6 +316,15 @@ static unsigned long omap_32k_timer_gettimeoffset(void)
        return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
 }
 
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+       return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
+}
+
 /*
  * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
  * function is also called from other interrupts to remove latency
@@ -330,19 +341,6 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
        now = omap_32k_sync_timer_read();
 
        while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
-#ifdef OMAP_32K_TICK_MODULO
-               /* Modulo addition may put omap_32k_last_tick ahead of now
-                * and cause unwanted repetition of the while loop.
-                */
-               if (unlikely(now - omap_32k_last_tick == ~0))
-                       break;
-
-               modulo_count += OMAP_32K_TICK_MODULO;
-               if (modulo_count > HZ) {
-                       ++omap_32k_last_tick;
-                       modulo_count -= HZ;
-               }
-#endif
                omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
                timer_tick(regs);
        }
index a10268618f7414674e438fb30d9569acf06b2f0c..e3587efec4bf685683d3f1a812e791cd41430f0a 100644 (file)
@@ -140,7 +140,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index e9182242da95be91ebe9dfc5f389c0a3318d8a5e..1a3367da640897e30acf33118d5fca4073a7fc1a 100644 (file)
@@ -381,7 +381,7 @@ static struct plat_serial8250_port bast_sio_data[] = {
 
 static struct platform_device bast_sio = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = &bast_sio_data,
        },
index 924e8464c21273b5503d7aa7c96593ba28f281cb..8f9ab2893df4b718bf29613b971ec79cc03ff117 100644 (file)
@@ -221,7 +221,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index e737eae4521f6fe5b7a8a58abb26c7a9be5b2a6c..946c0d11c73b6d80c0dd8e60c8725ba478dd270b 100644 (file)
@@ -41,7 +41,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device serial_device = {
        .name                   = "serial8250",
-       .id                     = 0,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index 191788fb18d13a4f3adad73afd92a649c0c7ff21..b0208c9925764940db06976ec69665b66d7275e0 100644 (file)
 #include <asm/tlbflush.h>
 
 #ifdef CONFIG_CPU_CACHE_VIPT
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+       if (cache_is_vivt()) {
+               if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
+                       __cpuc_flush_user_all();
+               return;
+       }
+
+       if (cache_is_vipt_aliasing()) {
+               asm(    "mcr    p15, 0, %0, c7, c14, 0\n"
+               "       mcr     p15, 0, %0, c7, c5, 0\n"
+               "       mcr     p15, 0, %0, c7, c10, 4"
+                   :
+                   : "r" (0)
+                   : "cc");
+       }
+}
+
+void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+       if (cache_is_vivt()) {
+               if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask))
+                       __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
+                                               vma->vm_flags);
+               return;
+       }
+
+       if (cache_is_vipt_aliasing()) {
+               asm(    "mcr    p15, 0, %0, c7, c14, 0\n"
+               "       mcr     p15, 0, %0, c7, c5, 0\n"
+               "       mcr     p15, 0, %0, c7, c10, 4"
+                   :
+                   : "r" (0)
+                   : "cc");
+       }
+}
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
+{
+       if (cache_is_vivt()) {
+               if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
+                       unsigned long addr = user_addr & PAGE_MASK;
+                       __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
+               }
+               return;
+       }
+
+       if (cache_is_vipt_aliasing())
+               flush_pfn_alias(pfn, user_addr);
+}
+
 #define ALIAS_FLUSH_START      0xffff4000
 
 #define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
index bf02b5026e6238ea13ff4743d856ecc5b9be5206..8ef38544453c24cb8488d3202ed23750890d4566 100644 (file)
@@ -467,11 +467,11 @@ static void __init longhaul_setup_voltagescaling(void)
        }
 
        if (vrmrev==0) {
-               dprintk ("VRM 8.5 \n");
+               dprintk ("VRM 8.5\n");
                memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
                numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
        } else {
-               dprintk ("Mobile VRM \n");
+               dprintk ("Mobile VRM\n");
                memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
                numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
        }
index 327a55d4d1c67b878f885f08cf353d06d816a057..c397b622043019196ffb9fdef2834c120ff4536e 100644 (file)
@@ -259,7 +259,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
 
        if (model->op_points == NULL) {
                /* Matched a non-match */
-               dprintk(KERN_INFO PFX "no table support for CPU model \"%s\"\n",
+               dprintk(KERN_INFO PFX "no table support for CPU model \"%s\"\n",
                       cpu->x86_model_id);
 #ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
                dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
@@ -402,7 +402,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
 
        for (i=0; i<p.state_count; i++) {
                if (p.states[i].control != p.states[i].status) {
-                       dprintk("Different control (%x) and status values (%x)\n",
+                       dprintk("Different control (%llu) and status values (%llu)\n",
                                p.states[i].control, p.states[i].status);
                        result = -EINVAL;
                        goto err_unreg;
@@ -415,7 +415,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
                }
 
                if (p.states[i].core_frequency > p.states[0].core_frequency) {
-                       dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i,
+                       dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i,
                                p.states[i].core_frequency, p.states[0].core_frequency);
                        p.states[i].core_frequency = 0;
                        continue;
@@ -498,13 +498,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
        if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
                return -ENODEV;
 
-       for (i = 0; i < N_IDS; i++)
-               if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
-                       break;
-
-       if (i != N_IDS)
-               centrino_cpu[policy->cpu] = &cpu_ids[i];
-
        if (is_const_loops_cpu(policy->cpu)) {
                centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
        }
@@ -513,6 +506,13 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
                if (policy->cpu != 0)
                        return -ENODEV;
 
+               for (i = 0; i < N_IDS; i++)
+                       if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
+                               break;
+
+               if (i != N_IDS)
+                       centrino_cpu[policy->cpu] = &cpu_ids[i];
+
                if (!centrino_cpu[policy->cpu]) {
                        dprintk(KERN_INFO PFX "found unsupported CPU with "
                        "Enhanced SpeedStep: send /proc/cpuinfo to "
index b25fb6b635ae85e8595454e7c304a864d10c353c..2718fb6f6aba89467467e48f1dd24fba465fae08 100644 (file)
@@ -99,7 +99,7 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
        u32 function = GET_SPEEDSTEP_FREQS;
 
        if (!(ist_info.event & 0xFFFF)) {
-               dprintk("bug #1422 -- can't read freqs from BIOS\n", result);
+               dprintk("bug #1422 -- can't read freqs from BIOS\n");
                return -ENODEV;
        }
 
index 3cc480998a47d4000013cd093aeb0e26b7a5d2ff..6d6338500c3cac7d0b2a8ae4f32c746346bcc383 100644 (file)
@@ -283,9 +283,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
        /* Write-combine setting is ignored, it is changed via the mtrr
         * interfaces on this platform.
         */
-       if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-                            vma->vm_end - vma->vm_start,
-                            vma->vm_page_prot))
+       if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+                              vma->vm_end - vma->vm_start,
+                              vma->vm_page_prot))
                return -EAGAIN;
 
        return 0;
index 00151a8320d8f1732e147d64698e28e747c45833..ed25d66c8d50b2951eb3e1610a24f735c3e73957 100644 (file)
@@ -339,12 +339,6 @@ config IA64_PALINFO
          To use this option, you have to ensure that the "/proc file system
          support" (CONFIG_PROC_FS) is enabled, too.
 
-config ACPI_DEALLOCATE_IRQ
-       bool
-       depends on ACPI
-       depends on IOSAPIC && EXPERIMENTAL
-       default y
-
 source "drivers/firmware/Kconfig"
 
 source "fs/Kconfig.binfmt"
index 1ca6e6e11b42f51c488bbf448f49df4eaf7e03dd..08112ab384686d9e204b31f40f1126a7550e7e71 100644 (file)
@@ -111,7 +111,6 @@ CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
index 3ec94a12eac0f9a70b3c9fa55f355ef5333aaf70..d452e18ac49425345f239d53bde0baa17cc3f842 100644 (file)
@@ -109,7 +109,6 @@ CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
index d4cf73d124bce959ebb5e346a038de342bf56efa..80b0e9eb7fb3d0ae2852d085f73ce3d2421e2146 100644 (file)
@@ -109,7 +109,6 @@ CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
index b6ec8d32c346ab8310574084a335ced4044f601f..5da208115ea1e7a296ac3f0d4148588c7f4749c5 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -335,7 +334,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_QLOGIC_1280_1040 is not set
index 318787c84ac0eda2ec0ae05a7dd2115c5d080f12..28a4529fdd60aed47c0cc2824ad381f763a73c2e 100644 (file)
@@ -583,14 +583,12 @@ int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
 
 EXPORT_SYMBOL(acpi_register_gsi);
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_unregister_gsi(u32 gsi)
 {
        iosapic_unregister_intr(gsi);
 }
 
 EXPORT_SYMBOL(acpi_unregister_gsi);
-#endif                         /* CONFIG_ACPI_DEALLOCATE_IRQ */
 
 static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size)
 {
index 9be53e1ea40431505fb392c9e54a7887e933d810..3c882102450999450b783d4b8642d4c74f4bae03 100644 (file)
@@ -204,9 +204,6 @@ GLOBAL_ENTRY(ia64_switch_to)
 (p6)   br.cond.dpnt .map
        ;;
 .done:
-(p6)   ssm psr.ic                      // if we had to map, reenable the psr.ic bit FIRST!!!
-       ;;
-(p6)   srlz.d
        ld8 sp=[r21]                    // load kernel stack pointer of new task
        mov IA64_KR(CURRENT)=in0        // update "current" application register
        mov r8=r13                      // return pointer to previously running task
@@ -234,6 +231,9 @@ GLOBAL_ENTRY(ia64_switch_to)
        mov IA64_KR(CURRENT_STACK)=r26  // remember last page we mapped...
        ;;
        itr.d dtr[r25]=r23              // wire in new mapping...
+       ssm psr.ic                      // reenable the psr.ic bit
+       ;;
+       srlz.d
        br.cond.sptk .done
 END(ia64_switch_to)
 
index a13df592ebf7adba9e9f98dba3e53d840c2dcfe1..574084f343fad79b32406c6e8b354c23554594bf 100644 (file)
@@ -782,7 +782,6 @@ again:
        return vector;
 }
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void
 iosapic_unregister_intr (unsigned int gsi)
 {
@@ -865,7 +864,6 @@ iosapic_unregister_intr (unsigned int gsi)
        spin_unlock(&iosapic_lock);
        spin_unlock_irqrestore(&idesc->lock, flags);
 }
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
 
 /*
  * ACPI calls this when it finds an entry for a platform interrupt.
index 6f308e62c1377cc04ee24efcd08775a66ed24dae..46c9331e7ab5f81181b5e19745c154a80c4b852e 100644 (file)
@@ -625,8 +625,11 @@ EK(.ex_handler,  (p17)     st8     [dst1]=r39,8);                                          \
        clrrrb
        ;;
        alloc   saved_pfs_stack=ar.pfs,3,3,3,0
+       cmp.lt  p8,p0=A,r0
        sub     B = dst0, saved_in0     // how many byte copied so far
        ;;
+(p8)   mov     A = 0;                  // A shouldn't be negative, cap it
+       ;;
        sub     C = A, B
        sub     D = saved_in2, A
        ;;
index 24614869e866ed7f2bd653d1cdc577d4aa02ce89..3c32af910d604732283ab91ebb10aa50cbcdee6b 100644 (file)
@@ -230,9 +230,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
                return;
        }
 
-       if (ia64_done_with_exception(regs))
-               return;
-
        /*
         * Since we have no vma's for region 5, we might get here even if the address is
         * valid, due to the VHPT walker inserting a non present translation that becomes
@@ -243,6 +240,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
        if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
                return;
 
+       if (ia64_done_with_exception(regs))
+               return;
+
        /*
         * Oops. The kernel tried to access some bad page. We'll have to terminate things
         * with extreme prejudice.
index 9977c122e9fa2c1a314e2d90fb5260dba87b0cb7..9b5de589b82f4bea4be004911ef5c4ef40a413c3 100644 (file)
@@ -498,13 +498,11 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
        return acpi_pci_irq_enable(dev);
 }
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void
 pcibios_disable_device (struct pci_dev *dev)
 {
        acpi_pci_irq_disable(dev);
 }
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
 
 void
 pcibios_align_resource (void *data, struct resource *res,
index a594aca959e6e141eb83a8769887f9199dc8b42a..14908ad7db8c1f3d863ae2f06d20c2fbe43331e4 100644 (file)
@@ -56,7 +56,7 @@
 
 DEFINE_PER_CPU(struct pda_s, pda_percpu);
 
-#define MAX_PHYS_MEMORY                (1UL << 49)     /* 1 TB */
+#define MAX_PHYS_MEMORY                (1UL << IA64_MAX_PHYS_BITS)     /* Max physical address supported */
 
 lboard_t *root_lboard[MAX_COMPACT_NODES];
 
index bb1d5cf30440cb9bf01b501084dd3ec08e8326ce..ed7c21586e98e44bcc3f815144c4bc40336c33b6 100644 (file)
@@ -885,6 +885,10 @@ xpc_init(void)
        pid_t pid;
 
 
+       if (!ia64_platform_is("sn2")) {
+               return -ENODEV;
+       }
+
        /*
         * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
         * both a partition's reserved page and its XPC variables. Its size was
index 78c13d676fa6693a30768935721358dea1e840a9..d0c2c114a459a5c694402e540eb7468afb137dec 100644 (file)
@@ -636,6 +636,10 @@ xpnet_init(void)
        int result = -ENOMEM;
 
 
+       if (!ia64_platform_is("sn2")) {
+               return -ENODEV;
+       }
+
        dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
 
        /*
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile
new file mode 100644 (file)
index 0000000..c1578b0
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
index 5cb28690f89a598d2008b147872b31678e917c1e..cf36e7d007b9eab480c48b9544532a55323e3569 100644 (file)
@@ -104,11 +104,11 @@ int mcf_timerirqpending(int timer)
 
 void config_BSP(char *commandp, int size)
 {
-#if 0
-       volatile unsigned long  *pivrp;
+#if defined (CONFIG_MOD5272)
+       volatile unsigned char  *pivrp;
 
        /* Set base of device vectors to be 64 */
-       pivrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PIVR);
+       pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR);
        *pivrp = 0x40;
 #endif
 
index 84b6b70641e17bff2656832242d92d82a0a68eaa..6fe5a2b8fb08476298ad4ac4171b309f72845f6f 100644 (file)
@@ -19,6 +19,7 @@ endif
 obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
 obj-$(CONFIG_M5206)    += timers.o
 obj-$(CONFIG_M5206e)   += timers.o
+obj-$(CONFIG_M523x)    += pit.o
 obj-$(CONFIG_M5249)    += timers.o
 obj-$(CONFIG_M527x)     += pit.o
 obj-$(CONFIG_M5272)    += timers.o
index fd7c93f86481aa4345f5a91d817c4d933d88b36b..bcfa5d7fe1e25d147c0f910846dff8a419a32974 100644 (file)
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
 /*
- *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *  linux/arch/m68knommu/platform/68328/config.c
  *
  *  Copyright (C) 1993 Hamish Macdonald
  *  Copyright (C) 1999 D. Jeff Dionne
@@ -11,6 +13,8 @@
  * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
  */
 
+/***************************************************************************/
+
 #include <asm/dbg.h>
 #include <stdarg.h>
 #include <linux/config.h>
 #include <asm/machdep.h>
 #include <asm/MC68328.h>
 
+/***************************************************************************/
 
-void BSP_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
-{
-
-#ifdef CONFIG_XCOPILOT_BUGS
-  /*
-   * The only thing I know is that CLK32 is not available on Xcopilot
-   * I have little idea about what frequency SYSCLK has on Xcopilot. 
-   * The values for prescaler and compare registers were simply 
-   * taken from the original source
-   */
-
-  /* Restart mode, Enable int, SYSCLK, Enable timer */
-  TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_SYSCLK | TCTL_TEN;
-  /* Set prescaler */
-  TPRER2 = 2;
-  /* Set compare register */
-  TCMP2 = 0xd7e4;
-#else
-  /* Restart mode, Enable int, 32KHz, Enable timer */
-  TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
-  /* Set prescaler (Divide 32KHz by 32)*/
-  TPRER2 = 31;
-  /* Set compare register  32Khz / 32 / 10 = 100 */
-  TCMP2 = 10;
-#endif
-                                                                    
-  request_irq(TMR2_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
-}
-
-void BSP_tick(void)
-{
-  /* Reset Timer2 */
-  TSTAT2 &= 0;
-}
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
+void m68328_timer_tick(void);
+unsigned long m68328_timer_gettimeoffset(void);
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
 
-unsigned long BSP_gettimeoffset (void)
-{
-  return 0;
-}
+/***************************************************************************/
 
-void BSP_gettod (int *yearp, int *monp, int *dayp,
-                  int *hourp, int *minp, int *secp)
-{
-}
-
-int BSP_hwclk(int op, struct hwclk_time *t)
-{
-  if (!op) {
-    /* read */
-  } else {
-    /* write */
-  }
-  return 0;
-}
-
-int BSP_set_clock_mmss (unsigned long nowtime)
-{
-#if 0
-  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-
-  tod->second1 = real_seconds / 10;
-  tod->second2 = real_seconds % 10;
-  tod->minute1 = real_minutes / 10;
-  tod->minute2 = real_minutes % 10;
-#endif
-  return 0;
-}
-
-void BSP_reset (void)
+void m68328_reset (void)
 {
   local_irq_disable();
   asm volatile ("moveal #0x10c00000, %a0;\n\t"
@@ -108,18 +52,22 @@ void BSP_reset (void)
                "jmp (%a0);");
 }
 
+/***************************************************************************/
+
 void config_BSP(char *command, int len)
 {
   printk(KERN_INFO "\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n");
   printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
   printk(KERN_INFO "68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
 
-  mach_sched_init      = BSP_sched_init;
-  mach_tick            = BSP_tick;
-  mach_gettimeoffset   = BSP_gettimeoffset;
-  mach_gettod          = BSP_gettod;
+  mach_sched_init      = m68328_timer_init;
+  mach_tick            = m68328_timer_tick;
+  mach_gettimeoffset   = m68328_timer_gettimeoffset;
+  mach_gettod          = m68328_timer_gettod;
   mach_hwclk           = NULL;
   mach_set_clock_mmss  = NULL;
-  mach_reset           = BSP_reset;
+  mach_reset           = m68328_reset;
   *command = '\0';
 }
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c
new file mode 100644 (file)
index 0000000..68c2cd6
--- /dev/null
@@ -0,0 +1,106 @@
+/***************************************************************************/
+
+/*
+ *  linux/arch/m68knommu/platform/68328/timers.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *  Copyright (C) 2001 Georges Menie, Ken Desmet
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68VZ328.h>
+
+/***************************************************************************/
+
+#if defined(CONFIG_DRAGEN2)
+/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
+#define CLOCK_SOURCE   TCTL_CLKSOURCE_SYSCLK
+#define CLOCK_PRE      7
+#define TICKS_PER_JIFFY        41450
+
+#elif defined(CONFIG_XCOPILOT_BUGS)
+/*
+ * The only thing I know is that CLK32 is not available on Xcopilot
+ * I have little idea about what frequency SYSCLK has on Xcopilot.
+ * The values for prescaler and compare registers were simply
+ * taken from the original source
+ */
+#define CLOCK_SOURCE   TCTL_CLKSOURCE_SYSCLK
+#define CLOCK_PRE      2
+#define TICKS_PER_JIFFY        0xd7e4
+
+#else
+/* default to using the 32Khz clock */
+#define CLOCK_SOURCE   TCTL_CLKSOURCE_32KHZ
+#define CLOCK_PRE      31
+#define TICKS_PER_JIFFY        10
+#endif
+
+/***************************************************************************/
+
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *))
+{
+       /* disable timer 1 */
+       TCTL = 0;
+
+       /* set ISR */
+       if (request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL)) 
+               panic("Unable to attach timer interrupt\n");
+
+       /* Restart mode, Enable int, Set clock source */
+       TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
+       TPRER = CLOCK_PRE;
+       TCMP = TICKS_PER_JIFFY;
+
+       /* Enable timer 1 */
+       TCTL |= TCTL_TEN;
+}
+
+/***************************************************************************/
+
+void m68328_timer_tick(void)
+{
+       /* Reset Timer1 */
+       TSTAT &= 0;
+}
+/***************************************************************************/
+
+unsigned long m68328_timer_gettimeoffset(void)
+{
+       unsigned long ticks = TCN, offset = 0;
+
+       /* check for pending interrupt */
+       if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
+               offset = 1000000 / HZ;
+       ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
+       return ticks + offset;
+}
+
+/***************************************************************************/
+
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
+{
+       long now = RTCTIME;
+
+       *year = *mon = *day = 1;
+       *hour = (now >> 24) % 24;
+       *min = (now >> 16) % 60;
+       *sec = now % 60;
+}
+
+/***************************************************************************/
index c21971971ff540638b28373eeeffd3a1f512ec83..d8d56e5de31073b38e73a5477097d0c20567631d 100644 (file)
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
 /*
- *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *  linux/arch/m68knommu/platform/68EZ328/config.c
  *
  *  Copyright (C) 1993 Hamish Macdonald
  *  Copyright (C) 1999 D. Jeff Dionne
@@ -9,6 +11,8 @@
  * for more details.
  */
 
+/***************************************************************************/
+
 #include <stdarg.h>
 #include <linux/config.h>
 #include <linux/types.h>
 #include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
-#include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/MC68EZ328.h>
 #ifdef CONFIG_UCSIMM
 #include <asm/bootstd.h>
 #endif
-#ifdef CONFIG_PILOT
-#include "PalmV/romfs.h"
-#endif
-
-void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
-{
-  /* Restart mode, Enable int, 32KHz, Enable timer */
-  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
-  /* Set prescaler (Divide 32KHz by 32)*/
-  TPRER = 31;
-  /* Set compare register  32Khz / 32 / 10 = 100 */
-  TCMP = 10;                                                              
-
-  request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
-}
-
-void BSP_tick(void)
-{
-       /* Reset Timer1 */
-       TSTAT &= 0;
-}
-
-unsigned long BSP_gettimeoffset (void)
-{
-  return 0;
-}
 
-void BSP_gettod (int *yearp, int *monp, int *dayp,
-                  int *hourp, int *minp, int *secp)
-{
-}
+/***************************************************************************/
 
-int BSP_hwclk(int op, struct hwclk_time *t)
-{
-  if (!op) {
-    /* read */
-  } else {
-    /* write */
-  }
-  return 0;
-}
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
+void m68328_timer_tick(void);
+unsigned long m68328_timer_gettimeoffset(void);
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
 
-int BSP_set_clock_mmss (unsigned long nowtime)
-{
-#if 0
-  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+/***************************************************************************/
 
-  tod->second1 = real_seconds / 10;
-  tod->second2 = real_seconds % 10;
-  tod->minute1 = real_minutes / 10;
-  tod->minute2 = real_minutes % 10;
-#endif
-  return 0;
-}
-
-void BSP_reset (void)
+void m68ez328_reset(void)
 {
   local_irq_disable();
   asm volatile ("
@@ -93,6 +51,8 @@ void BSP_reset (void)
     ");
 }
 
+/***************************************************************************/
+
 unsigned char *cs8900a_hwaddr;
 static int errno;
 
@@ -119,11 +79,13 @@ void config_BSP(char *command, int len)
   else command[0] = 0;
 #endif
  
-  mach_sched_init      = BSP_sched_init;
-  mach_tick            = BSP_tick;
-  mach_gettimeoffset   = BSP_gettimeoffset;
-  mach_gettod          = BSP_gettod;
+  mach_sched_init      = m68328_timer_init;
+  mach_tick            = m68328_timer_tick;
+  mach_gettimeoffset   = m68328_timer_gettimeoffset;
+  mach_gettod          = m68328_timer_gettod;
   mach_hwclk           = NULL;
   mach_set_clock_mmss  = NULL;
-  mach_reset           = BSP_reset;
+  mach_reset           = m68ez328_reset;
 }
+
+/***************************************************************************/
similarity index 51%
rename from arch/m68knommu/platform/68VZ328/de2/config.c
rename to arch/m68knommu/platform/68VZ328/config.c
index d0586197f1131deae7e72f23f67f465b17a2556a..d926524cdf82632e9b456996a61406694fbf3fea 100644 (file)
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
 /*
- *  linux/arch/m68knommu/platform/MC68VZ328/de2/config.c
+ *  linux/arch/m68knommu/platform/68VZ328/config.c
  *
  *  Copyright (C) 1993 Hamish Macdonald
  *  Copyright (C) 1999 D. Jeff Dionne
@@ -10,6 +12,8 @@
  * for more details.
  */
 
+/***************************************************************************/
+
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/MC68VZ328.h>
+#include <asm/bootstd.h>
 
 #ifdef CONFIG_INIT_LCD
-#include "screen.h"
+#include "bootlogo.h"
 #endif
 
-/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
-#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
-#define CLOCK_PRE 7
-#define TICKS_PER_JIFFY 41450
-
-static void
-dragen2_sched_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *))
-{
-       /* disable timer 1 */
-       TCTL = 0;
-
-       /* set ISR */
-       if (request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL)) 
-               panic("Unable to attach timer interrupt\n");
-
-       /* Restart mode, Enable int, Set clock source */
-       TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
-       TPRER = CLOCK_PRE;
-       TCMP = TICKS_PER_JIFFY;
-
-       /* Enable timer 1 */
-       TCTL |= TCTL_TEN;
-}
-
-static void dragen2_tick(void)
-{
-       /* Reset Timer1 */
-       TSTAT &= 0;
-}
-
-static unsigned long dragen2_gettimeoffset(void)
-{
-       unsigned long ticks = TCN, offset = 0;
-
-       /* check for pending interrupt */
-       if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
-               offset = 1000000 / HZ;
-
-       ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
+/***************************************************************************/
 
-       return ticks + offset;
-}
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
+void m68328_timer_tick(void);
+unsigned long m68328_timer_gettimeoffset(void);
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
 
-static void dragen2_gettod(int *year, int *mon, int *day, int *hour,
-                                                  int *min, int *sec)
-{
-       long now = RTCTIME;
+/***************************************************************************/
+/*                        Init Drangon Engine hardware                     */
+/***************************************************************************/
+#if defined(CONFIG_DRAGEN2)
 
-       *year = *mon = *day = 1;
-       *hour = (now >> 24) % 24;
-       *min = (now >> 16) % 60;
-       *sec = now % 60;
-}
-
-static void dragen2_reset(void)
+static void m68vz328_reset(void)
 {
        local_irq_disable();
 
@@ -103,7 +66,7 @@ static void dragen2_reset(void)
        );
 }
 
-static void init_hardware(void)
+static void init_hardware(char *command, int size)
 {
 #ifdef CONFIG_DIRECT_IO_ACCESS
        SCR = 0x10;                                     /* allow user access to internal registers */
@@ -170,6 +133,60 @@ static void init_hardware(void)
 #endif
 }
 
+/***************************************************************************/
+/*                      Init RT-Control uCdimm hardware                    */
+/***************************************************************************/
+#elif defined(CONFIG_UCDIMM)
+
+static void m68vz328_reset(void)
+{
+       local_irq_disable();
+       asm volatile ("
+               moveal #0x10c00000, %a0;
+               moveb #0, 0xFFFFF300;
+               moveal 0(%a0), %sp;
+               moveal 4(%a0), %a0;
+               jmp (%a0);
+       ");
+}
+
+unsigned char *cs8900a_hwaddr;
+static int errno;
+
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+
+static void init_hardware(char *command, int size)
+{
+       char *p;
+
+       printk(KERN_INFO "uCdimm serial string [%s]\n", getserialnum());
+       p = cs8900a_hwaddr = gethwaddr(0);
+       printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+               p[0], p[1], p[2], p[3], p[4], p[5]);
+       p = getbenv("APPEND");
+       if (p)
+               strcpy(p, command);
+       else
+               command[0] = 0;
+}
+
+/***************************************************************************/
+#else
+
+static void m68vz328_reset(void)
+{
+}
+
+static void init_hardware(char *command, int size)
+{
+}
+
+/***************************************************************************/
+#endif
+/***************************************************************************/
+
 void config_BSP(char *command, int size)
 {
        printk(KERN_INFO "68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
@@ -181,11 +198,13 @@ void config_BSP(char *command, int size)
        memset(command, 0, size);
 #endif
 
-       init_hardware();
+       init_hardware(command, size);
 
-       mach_sched_init = (void *)dragen2_sched_init;
-       mach_tick = dragen2_tick;
-       mach_gettimeoffset = dragen2_gettimeoffset;
-       mach_reset = dragen2_reset;
-       mach_gettod = dragen2_gettod;
+       mach_sched_init = (void *) m68328_timer_init;
+       mach_tick = m68328_timer_tick;
+       mach_gettimeoffset = m68328_timer_gettimeoffset;
+       mach_gettod = m68328_timer_gettod;
+       mach_reset = m68vz328_reset;
 }
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68VZ328/ucdimm/config.c b/arch/m68knommu/platform/68VZ328/ucdimm/config.c
deleted file mode 100644 (file)
index 2deadaf..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *  linux/arch/m68knommu/platform/68VZ328/ucdimm/config.c
- *
- *  Copyright (C) 1993 Hamish Macdonald
- *  Copyright (C) 1999 D. Jeff Dionne
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#include <stdarg.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-
-#include <asm/setup.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/machdep.h>
-#include <asm/MC68VZ328.h>
-#include <asm/bootstd.h>
-
-void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
-{
-       /* Restart mode, Enable int, 32KHz, Enable timer */
-       TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
-       /* Set prescaler (Divide 32KHz by 32)*/
-       TPRER = 31;
-       /* Set compare register  32Khz / 32 / 10 = 100 */
-       TCMP = 10;                                                              
-
-       request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
-}
-
-void BSP_tick(void)
-{
-       /* Reset Timer1 */
-       TSTAT &= 0;
-}
-
-unsigned long BSP_gettimeoffset (void)
-{
-       return 0;
-}
-
-void BSP_gettod (int *yearp, int *monp, int *dayp,
-                  int *hourp, int *minp, int *secp)
-{
-}
-
-int BSP_hwclk(int op, struct hwclk_time *t)
-{
-       if (!op) {
-               /* read */
-       } else {
-               /* write */
-       }
-       return 0;
-}
-
-int BSP_set_clock_mmss (unsigned long nowtime)
-{
-#if 0
-       short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-
-       tod->second1 = real_seconds / 10;
-       tod->second2 = real_seconds % 10;
-       tod->minute1 = real_minutes / 10;
-       tod->minute2 = real_minutes % 10;
-#endif
-       return 0;
-}
-
-void BSP_reset (void)
-{
-       local_irq_disable();
-       asm volatile ("
-               moveal #0x10c00000, %a0;
-               moveb #0, 0xFFFFF300;
-               moveal 0(%a0), %sp;
-               moveal 4(%a0), %a0;
-               jmp (%a0);
-       ");
-}
-
-unsigned char *cs8900a_hwaddr;
-static int errno;
-
-_bsc0(char *, getserialnum)
-_bsc1(unsigned char *, gethwaddr, int, a)
-_bsc1(char *, getbenv, char *, a)
-
-void config_BSP(char *command, int len)
-{
-       unsigned char *p;
-
-       printk(KERN_INFO "\n68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
-
-       printk(KERN_INFO "uCdimm serial string [%s]\n",getserialnum());
-       p = cs8900a_hwaddr = gethwaddr(0);
-       printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
-               p[0], p[1], p[2], p[3], p[4], p[5]);
-       p = getbenv("APPEND");
-       if (p) strcpy(p,command);
-       else command[0] = 0;
-       mach_sched_init      = BSP_sched_init;
-       mach_tick            = BSP_tick;
-       mach_gettimeoffset   = BSP_gettimeoffset;
-       mach_gettod          = BSP_gettod;
-       mach_reset           = BSP_reset;
-}
index 7b3586a3bf302f22289ab5cf6cbe2e874edeed09..854e45beb387bfdc6bddd6bb9a816d3d9a17f2b8 100644 (file)
@@ -80,7 +80,6 @@ fixup_broken_pcnet32(struct pci_dev* dev)
        if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
                dev->vendor = PCI_VENDOR_ID_AMD;
                pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-               pci_name_device(dev);
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT,        PCI_ANY_ID,                     fixup_broken_pcnet32);
index 87065e2e4c5f726be73b004900a253052980e0cf..3e039706bdbcbc350430d068bd965c65757dd5a2 100644 (file)
@@ -140,12 +140,12 @@ struct platform_device ppc_sys_platform_devices[] = {
        },
        [MPC10X_UART0] = {
                .name = "serial8250",
-               .id     = 0,
+               .id     = PLAT8250_DEV_PLATFORM,
                .dev.platform_data = serial_plat_uart0,
        },
        [MPC10X_UART1] = {
                .name = "serial8250",
-               .id     = 1,
+               .id     = PLAT8250_DEV_PLATFORM1,
                .dev.platform_data = serial_plat_uart1,
        },
 
index 5aaf0e58e1f9d2f7b0b187ed475e98c81c8901de..95b3b8a7f0bae34386bfdbe6409a35253a4250ea 100644 (file)
@@ -165,7 +165,7 @@ struct platform_device ppc_sys_platform_devices[] = {
        },
        [MPC83xx_DUART] = {
                .name = "serial8250",
-               .id     = 0,
+               .id     = PLAT8250_DEV_PLATFORM,
                .dev.platform_data = serial_platform_data,
        },
        [MPC83xx_SEC2] = {
index 8af322dd476a6467cda34d4983d1e589d46f21a4..bbc5ac0de87835f7251fc0980f89166efb2fc6cc 100644 (file)
@@ -282,7 +282,7 @@ struct platform_device ppc_sys_platform_devices[] = {
        },
        [MPC85xx_DUART] = {
                .name = "serial8250",
-               .id     = 0,
+               .id     = PLAT8250_DEV_PLATFORM,
                .dev.platform_data = serial_platform_data,
        },
        [MPC85xx_PERFMON] = {
index af5272fedadf4d8f4a2705edd735479dd9d96751..4c857a6516fc30814bcd4121d2d2c536bf0eaaf5 100644 (file)
@@ -202,10 +202,9 @@ static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
        while (n) {
                struct pci_io_addr_range *piar;
                piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-               printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s %s\n",
+               printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
                       (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
-                      piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev),
-                      pci_pretty_name(piar->pcidev));
+                      piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
                cnt++;
                n = rb_next(n);
        }
@@ -260,8 +259,8 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
 
        dn = pci_device_to_OF_node(dev);
        if (!dn) {
-               printk(KERN_WARNING "PCI: no pci dn found for dev=%s %s\n",
-                       pci_name(dev), pci_pretty_name(dev));
+               printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n",
+                       pci_name(dev));
                return;
        }
 
@@ -269,8 +268,8 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
        if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
            dn->eeh_mode & EEH_MODE_NOCHECK) {
 #ifdef DEBUG
-               printk(KERN_INFO "PCI: skip building address cache for=%s %s\n",
-                      pci_name(dev), pci_pretty_name(dev));
+               printk(KERN_INFO "PCI: skip building address cache for=%s\n",
+                      pci_name(dev));
 #endif
                return;
        }
@@ -447,12 +446,12 @@ static void eeh_panic(struct pci_dev *dev, int reset_state)
         * in light of potential corruption, we can use it here.
         */
        if (panic_on_oops)
-               panic("EEH: MMIO failure (%d) on device:%s %s\n", reset_state,
-                     pci_name(dev), pci_pretty_name(dev));
+               panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
+                     pci_name(dev));
        else {
                __get_cpu_var(ignored_failures)++;
-               printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s %s\n",
-                      reset_state, pci_name(dev), pci_pretty_name(dev));
+               printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
+                      reset_state, pci_name(dev));
        }
 }
 
@@ -482,8 +481,8 @@ static void eeh_event_handler(void *dummy)
                        break;
 
                printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device "
-                      "%s %s\n", event->reset_state,
-                      pci_name(event->dev), pci_pretty_name(event->dev));
+                      "%s\n", event->reset_state,
+                      pci_name(event->dev));
 
                atomic_set(&eeh_fail_count, 0);
                notifier_call_chain (&eeh_notifier_chain,
@@ -851,8 +850,7 @@ void eeh_add_device_late(struct pci_dev *dev)
                return;
 
 #ifdef DEBUG
-       printk(KERN_DEBUG "EEH: adding device %s %s\n", pci_name(dev),
-              pci_pretty_name(dev));
+       printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
 #endif
 
        pci_addr_cache_insert_device (dev);
@@ -873,8 +871,7 @@ void eeh_remove_device(struct pci_dev *dev)
 
        /* Unregister the device with the EEH/PCI address search system */
 #ifdef DEBUG
-       printk(KERN_DEBUG "EEH: remove device %s %s\n", pci_name(dev),
-              pci_pretty_name(dev));
+       printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
 #endif
        pci_addr_cache_remove_device(dev);
 }
index d11c732daf816a2a7bed18c58e0a20fa52439c0e..5d921792571f59ee3c64cbfe42caf3f679a6b6b7 100644 (file)
@@ -264,8 +264,5 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
        printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s  ",
                        count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
                        frame, card);
-       if (pci_class_name(PciDev->class >> 8) == 0)
-               printk("0x%04X\n", (int)(PciDev->class >> 8));
-       else
-               printk("%s\n", pci_class_name(PciDev->class >> 8));
+       printk("0x%04X\n", (int)(PciDev->class >> 8));
 }
index d0d55c7908efe5a1c2bc5c584e4f9a91873b1c2f..b5ca7d8347e2ec2e9f3838650f437d97d5242871 100644 (file)
@@ -84,7 +84,6 @@ static void fixup_broken_pcnet32(struct pci_dev* dev)
        if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
                dev->vendor = PCI_VENDOR_ID_AMD;
                pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-               pci_name_device(dev);
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
index d0bb68af0ea41d48bca4bc945d6e727ffcd2a424..bfa8791c9807f865bb89085f0054759bbd452eaa 100644 (file)
@@ -1283,7 +1283,7 @@ void __init generic_find_legacy_serial_ports(u64 *physport,
 
 static struct platform_device serial_device = {
        .name   = "serial8250",
-       .id     = 0,
+       .id     = PLAT8250_DEV_PLATFORM,
        .dev    = {
                .platform_data = serial_ports,
        },
index ec8bf4012c0c411b66505727387d38a57f43fdc3..2ff7c32ab0ce155efd70e6a75e0f15cf2ecf62b6 100644 (file)
@@ -359,134 +359,17 @@ void pcibios_fixup_bus(struct pci_bus *pbus)
        pbus->resource[1] = &pbm->mem_space;
 }
 
-int pci_claim_resource(struct pci_dev *pdev, int resource)
+struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r)
 {
        struct pci_pbm_info *pbm = pdev->bus->sysdata;
-       struct resource *res = &pdev->resource[resource];
-       struct resource *root;
-
-       if (!pbm)
-               return -EINVAL;
+       struct resource *root = NULL;
 
-       if (res->flags & IORESOURCE_IO)
+       if (r->flags & IORESOURCE_IO)
                root = &pbm->io_space;
-       else
+       if (r->flags & IORESOURCE_MEM)
                root = &pbm->mem_space;
 
-       pbm->parent->resource_adjust(pdev, res, root);
-
-       return request_resource(root, res);
-}
-
-/*
- * Given the PCI bus a device resides on, try to
- * find an acceptable resource allocation for a
- * specific device resource..
- */
-static int pci_assign_bus_resource(const struct pci_bus *bus,
-       struct pci_dev *dev,
-       struct resource *res,
-       unsigned long size,
-       unsigned long min,
-       int resno)
-{
-       unsigned int type_mask;
-       int i;
-
-       type_mask = IORESOURCE_IO | IORESOURCE_MEM;
-       for (i = 0 ; i < 4; i++) {
-               struct resource *r = bus->resource[i];
-               if (!r)
-                       continue;
-
-               /* type_mask must match */
-               if ((res->flags ^ r->flags) & type_mask)
-                       continue;
-
-               /* Ok, try it out.. */
-               if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0)
-                       continue;
-
-               /* PCI config space updated by caller.  */
-               return 0;
-       }
-       return -EBUSY;
-}
-
-int pci_assign_resource(struct pci_dev *pdev, int resource)
-{
-       struct pcidev_cookie *pcp = pdev->sysdata;
-       struct pci_pbm_info *pbm = pcp->pbm;
-       struct resource *res = &pdev->resource[resource];
-       unsigned long min, size;
-       int err;
-
-       if (res->flags & IORESOURCE_IO)
-               min = pbm->io_space.start + 0x400UL;
-       else
-               min = pbm->mem_space.start;
-
-       size = res->end - res->start + 1;
-
-       err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource);
-
-       if (err < 0) {
-               printk("PCI: Failed to allocate resource %d for %s\n",
-                      resource, pci_name(pdev));
-       } else {
-               /* Update PCI config space. */
-               pbm->parent->base_address_update(pdev, resource);
-       }
-
-       return err;
-}
-
-/* Sort resources by alignment */
-void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
-{
-       int i;
-
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *r;
-               struct resource_list *list, *tmp;
-               unsigned long r_align;
-
-               r = &dev->resource[i];
-               r_align = r->end - r->start;
-               
-               if (!(r->flags) || r->parent)
-                       continue;
-               if (!r_align) {
-                       printk(KERN_WARNING "PCI: Ignore bogus resource %d "
-                                           "[%lx:%lx] of %s\n",
-                                           i, r->start, r->end, pci_name(dev));
-                       continue;
-               }
-               r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
-               for (list = head; ; list = list->next) {
-                       unsigned long align = 0;
-                       struct resource_list *ln = list->next;
-                       int idx;
-
-                       if (ln) {
-                               idx = ln->res - &ln->dev->resource[0];
-                               align = (idx < PCI_BRIDGE_RESOURCES) ?
-                                       ln->res->end - ln->res->start + 1 :
-                                       ln->res->start;
-                       }
-                       if (r_align > align) {
-                               tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
-                               if (!tmp)
-                                       panic("pdev_sort_resources(): "
-                                             "kmalloc() failed!\n");
-                               tmp->next = ln;
-                               tmp->res = r;
-                               tmp->dev = dev;
-                               list->next = tmp;
-                               break;
-                       }
-               }
-       }
+       return root;
 }
 
 void pcibios_update_irq(struct pci_dev *pdev, int irq)
index 91ab466d6c66ba7ae9d4aab057b93fd7f1b04bf1..6ed1ef25e0ac6eb4a9b23ca1d8e17f32a4247e96 100644 (file)
@@ -307,7 +307,7 @@ static unsigned char psycho_pil_table[] = {
 /*0x32*/15,            /* Power Management             */
 };
 
-static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
 {
        int ret;
 
@@ -344,9 +344,9 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
        return ret;
 }
 
-static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm,
-                                           struct pci_dev *pdev,
-                                           unsigned int ino)
+static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
+                                    struct pci_dev *pdev,
+                                    unsigned int ino)
 {
        struct ino_bucket *bucket;
        unsigned long imap, iclr;
@@ -1024,7 +1024,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
 #define PSYCHO_CE_INO          0x2f
 #define PSYCHO_PCIERR_A_INO    0x30
 #define PSYCHO_PCIERR_B_INO    0x31
-static void __init psycho_register_error_handlers(struct pci_controller_info *p)
+static void psycho_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
        unsigned long base = p->pbm_A.controller_regs;
@@ -1091,15 +1091,15 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
 }
 
 /* PSYCHO boot time probing and initialization. */
-static void __init psycho_resource_adjust(struct pci_dev *pdev,
-                                         struct resource *res,
-                                         struct resource *root)
+static void psycho_resource_adjust(struct pci_dev *pdev,
+                                  struct resource *res,
+                                  struct resource *root)
 {
        res->start += root->start;
        res->end += root->start;
 }
 
-static void __init psycho_base_address_update(struct pci_dev *pdev, int resource)
+static void psycho_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
@@ -1144,7 +1144,7 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource
                pci_write_config_dword(pdev, where + 4, 0);
 }
 
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
 {
        u8 *addr;
 
@@ -1161,8 +1161,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
        pci_config_write8(addr, 64);
 }
 
-static void __init pbm_scan_bus(struct pci_controller_info *p,
-                               struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+                        struct pci_pbm_info *pbm)
 {
        struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
 
@@ -1189,7 +1189,7 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
        pci_setup_busmastering(pbm, pbm->pci_bus);
 }
 
-static void __init psycho_scan_bus(struct pci_controller_info *p)
+static void psycho_scan_bus(struct pci_controller_info *p)
 {
        pbm_config_busmastering(&p->pbm_B);
        p->pbm_B.is_66mhz_capable = 0;
@@ -1204,7 +1204,7 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
        psycho_register_error_handlers(p);
 }
 
-static void __init psycho_iommu_init(struct pci_controller_info *p)
+static void psycho_iommu_init(struct pci_controller_info *p)
 {
        struct pci_iommu *iommu = p->pbm_A.iommu;
        unsigned long tsbbase, i;
@@ -1327,8 +1327,8 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
        psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
 }
 
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                                  struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+                                           struct pci_pbm_info *pbm)
 {
        char *name = pbm->name;
 
@@ -1481,7 +1481,7 @@ static void psycho_pbm_init(struct pci_controller_info *p,
 
 #define PSYCHO_CONFIGSPACE     0x001000000UL
 
-void __init psycho_init(int node, char *model_name)
+void psycho_init(int node, char *model_name)
 {
        struct linux_prom64_registers pr_regs[3];
        struct pci_controller_info *p;
index 52bf3431a42243cc323bfbbe8750a4c3622b4d3c..0ee6bd5b9ac67de368cfb54e7dd52a0f27c4a6ae 100644 (file)
@@ -554,7 +554,7 @@ static unsigned char sabre_pil_table[] = {
 /*0x32*/15,            /* Power Management             */
 };
 
-static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
 {
        int ret;
 
@@ -612,9 +612,9 @@ static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_a
        sabre_read(sync_reg);
 }
 
-static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
-                                          struct pci_dev *pdev,
-                                          unsigned int ino)
+static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
+                                   struct pci_dev *pdev,
+                                   unsigned int ino)
 {
        struct ino_bucket *bucket;
        unsigned long imap, iclr;
@@ -1009,7 +1009,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
 #define SABRE_UE_INO           0x2e
 #define SABRE_CE_INO           0x2f
 #define SABRE_PCIERR_INO       0x30
-static void __init sabre_register_error_handlers(struct pci_controller_info *p)
+static void sabre_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
        unsigned long base = pbm->controller_regs;
@@ -1056,9 +1056,9 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
        sabre_write(base + SABRE_PCICTRL, tmp);
 }
 
-static void __init sabre_resource_adjust(struct pci_dev *pdev,
-                                        struct resource *res,
-                                        struct resource *root)
+static void sabre_resource_adjust(struct pci_dev *pdev,
+                                 struct resource *res,
+                                 struct resource *root)
 {
        struct pci_pbm_info *pbm = pdev->bus->sysdata;
        unsigned long base;
@@ -1072,7 +1072,7 @@ static void __init sabre_resource_adjust(struct pci_dev *pdev,
        res->end += base;
 }
 
-static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
+static void sabre_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
@@ -1118,7 +1118,7 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
                pci_write_config_dword(pdev, where + 4, 0);
 }
 
-static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
+static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
 {
        struct pci_dev *pdev;
 
@@ -1181,7 +1181,7 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
        return cookie;
 }
 
-static void __init sabre_scan_bus(struct pci_controller_info *p)
+static void sabre_scan_bus(struct pci_controller_info *p)
 {
        static int once;
        struct pci_bus *sabre_bus, *pbus;
@@ -1262,9 +1262,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
        sabre_register_error_handlers(p);
 }
 
-static void __init sabre_iommu_init(struct pci_controller_info *p,
-                                   int tsbsize, unsigned long dvma_offset,
-                                   u32 dma_mask)
+static void sabre_iommu_init(struct pci_controller_info *p,
+                            int tsbsize, unsigned long dvma_offset,
+                            u32 dma_mask)
 {
        struct pci_iommu *iommu = p->pbm_A.iommu;
        unsigned long tsbbase, i, order;
@@ -1345,8 +1345,8 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
        }
 }
 
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                                  struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+                                           struct pci_pbm_info *pbm)
 {
        char *name = pbm->name;
        unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE;
@@ -1415,7 +1415,7 @@ static void __init pbm_register_toplevel_resources(struct pci_controller_info *p
                                            &pbm->mem_space);
 }
 
-static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
 {
        struct pci_pbm_info *pbm;
        char namebuf[128];
@@ -1552,7 +1552,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node,
        }
 }
 
-void __init sabre_init(int pnode, char *model_name)
+void sabre_init(int pnode, char *model_name)
 {
        struct linux_prom64_registers pr_regs[2];
        struct pci_controller_info *p;
index 6a182bb66281f24c0caf721207c5f9370323fd4e..331382e1a75d40d80680206b31b1c3eb26f129d3 100644 (file)
@@ -285,7 +285,7 @@ static unsigned char schizo_pil_table[] = {
 /*0x3f*/0,             /* Reserved for NewLink         */
 };
 
-static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
 {
        int ret;
 
@@ -1221,7 +1221,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
  * PCI bus units of the same Tomatillo.  I still have not really
  * figured this out...
  */
-static void __init tomatillo_register_error_handlers(struct pci_controller_info *p)
+static void tomatillo_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm;
        unsigned int irq;
@@ -1359,7 +1359,7 @@ static void __init tomatillo_register_error_handlers(struct pci_controller_info
                     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
 }
 
-static void __init schizo_register_error_handlers(struct pci_controller_info *p)
+static void schizo_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm;
        unsigned int irq;
@@ -1505,7 +1505,7 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p)
                     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
 }
 
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
 {
        u8 *addr;
 
@@ -1522,8 +1522,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
        pci_config_write8(addr, 64);
 }
 
-static void __init pbm_scan_bus(struct pci_controller_info *p,
-                               struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+                        struct pci_pbm_info *pbm)
 {
        struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
 
@@ -1550,8 +1550,8 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
        pci_setup_busmastering(pbm, pbm->pci_bus);
 }
 
-static void __init __schizo_scan_bus(struct pci_controller_info *p,
-                                    int chip_type)
+static void __schizo_scan_bus(struct pci_controller_info *p,
+                             int chip_type)
 {
        if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) {
                printk("PCI: Only one PCI bus module of controller found.\n");
@@ -1577,17 +1577,17 @@ static void __init __schizo_scan_bus(struct pci_controller_info *p,
                schizo_register_error_handlers(p);
 }
 
-static void __init schizo_scan_bus(struct pci_controller_info *p)
+static void schizo_scan_bus(struct pci_controller_info *p)
 {
        __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO);
 }
 
-static void __init tomatillo_scan_bus(struct pci_controller_info *p)
+static void tomatillo_scan_bus(struct pci_controller_info *p)
 {
        __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO);
 }
 
-static void __init schizo_base_address_update(struct pci_dev *pdev, int resource)
+static void schizo_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
@@ -1632,9 +1632,9 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource
                pci_write_config_dword(pdev, where + 4, 0);
 }
 
-static void __init schizo_resource_adjust(struct pci_dev *pdev,
-                                         struct resource *res,
-                                         struct resource *root)
+static void schizo_resource_adjust(struct pci_dev *pdev,
+                                  struct resource *res,
+                                  struct resource *root)
 {
        res->start += root->start;
        res->end += root->start;
@@ -1702,8 +1702,8 @@ static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
               pbm->mem_space.start);
 }
 
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                                  struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+                                           struct pci_pbm_info *pbm)
 {
        pbm->io_space.name = pbm->mem_space.name = pbm->name;
 
@@ -1932,7 +1932,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 #define TOMATILLO_PCI_IOC_TDIAG                (0x2250UL)
 #define TOMATILLO_PCI_IOC_DDIAG                (0x2290UL)
 
-static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
+static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
 {
        u64 tmp;
 
@@ -1986,9 +1986,9 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
        }
 }
 
-static void __init schizo_pbm_init(struct pci_controller_info *p,
-                                  int prom_node, u32 portid,
-                                  int chip_type)
+static void schizo_pbm_init(struct pci_controller_info *p,
+                           int prom_node, u32 portid,
+                           int chip_type)
 {
        struct linux_prom64_registers pr_regs[4];
        unsigned int busrange[2];
@@ -2145,7 +2145,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
        return (x == y);
 }
 
-static void __init __schizo_init(int node, char *model_name, int chip_type)
+static void __schizo_init(int node, char *model_name, int chip_type)
 {
        struct pci_controller_info *p;
        struct pci_iommu *iommu;
@@ -2213,17 +2213,17 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
        schizo_pbm_init(p, node, portid, chip_type);
 }
 
-void __init schizo_init(int node, char *model_name)
+void schizo_init(int node, char *model_name)
 {
        __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO);
 }
 
-void __init schizo_plus_init(int node, char *model_name)
+void schizo_plus_init(int node, char *model_name)
 {
        __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
 }
 
-void __init tomatillo_init(int node, char *model_name)
+void tomatillo_init(int node, char *model_name)
 {
        __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO);
 }
index d89fc24808d3eccd137db229c0bef7438b19ec7a..7d9a0f6c437dcc60dba88b30afe33af1dafcc550 100644 (file)
@@ -403,12 +403,3 @@ EXPORT_SYMBOL(xor_vis_4);
 EXPORT_SYMBOL(xor_vis_5);
 
 EXPORT_SYMBOL(prom_palette);
-
-/* memory barriers */
-EXPORT_SYMBOL(mb);
-EXPORT_SYMBOL(rmb);
-EXPORT_SYMBOL(wmb);
-EXPORT_SYMBOL(membar_storeload);
-EXPORT_SYMBOL(membar_storeload_storestore);
-EXPORT_SYMBOL(membar_storeload_loadload);
-EXPORT_SYMBOL(membar_storestore_loadstore);
index 6201f1040982aabde591d28673a4a0d7e2697f95..40dbeec7e5d6a8ed75006dd2873e0d40e019b29e 100644 (file)
@@ -12,7 +12,7 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \
         U1memcpy.o U1copy_from_user.o U1copy_to_user.o \
         U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \
         copy_in_user.o user_fixup.o memmove.o \
-        mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o mb.o
+        mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
 
 lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
 lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff --git a/arch/sparc64/lib/mb.S b/arch/sparc64/lib/mb.S
deleted file mode 100644 (file)
index 4004f74..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* mb.S: Out of line memory barriers.
- *
- * Copyright (C) 2005 David S. Miller (davem@davemloft.net)
- */
-
-       /* These are here in an effort to more fully work around
-        * Spitfire Errata #51.  Essentially, if a memory barrier
-        * occurs soon after a mispredicted branch, the chip can stop
-        * executing instructions until a trap occurs.  Therefore, if
-        * interrupts are disabled, the chip can hang forever.
-        *
-        * It used to be believed that the memory barrier had to be
-        * right in the delay slot, but a case has been traced
-        * recently wherein the memory barrier was one instruction
-        * after the branch delay slot and the chip still hung.  The
-        * offending sequence was the following in sym_wakeup_done()
-        * of the sym53c8xx_2 driver:
-        *
-        *      call    sym_ccb_from_dsa, 0
-        *       movge  %icc, 0, %l0
-        *      brz,pn  %o0, .LL1303
-        *       mov    %o0, %l2
-        *      membar  #LoadLoad
-        *
-        * The branch has to be mispredicted for the bug to occur.
-        * Therefore, we put the memory barrier explicitly into a
-        * "branch always, predicted taken" delay slot to avoid the
-        * problem case.
-        */
-
-       .text
-
-99:    retl
-        nop
-
-       .globl  mb
-mb:    ba,pt   %xcc, 99b
-        membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad
-       .size   mb, .-mb
-
-       .globl  rmb
-rmb:   ba,pt   %xcc, 99b
-        membar #LoadLoad
-       .size   rmb, .-rmb
-
-       .globl  wmb
-wmb:   ba,pt   %xcc, 99b
-        membar #StoreStore
-       .size   wmb, .-wmb
-
-       .globl  membar_storeload
-membar_storeload:
-       ba,pt   %xcc, 99b
-        membar #StoreLoad
-       .size   membar_storeload, .-membar_storeload
-
-       .globl  membar_storeload_storestore
-membar_storeload_storestore:
-       ba,pt   %xcc, 99b
-        membar #StoreLoad | #StoreStore
-       .size   membar_storeload_storestore, .-membar_storeload_storestore
-
-       .globl  membar_storeload_loadload
-membar_storeload_loadload:
-       ba,pt   %xcc, 99b
-        membar #StoreLoad | #LoadLoad
-       .size   membar_storeload_loadload, .-membar_storeload_loadload
-
-       .globl  membar_storestore_loadstore
-membar_storestore_loadstore:
-       ba,pt   %xcc, 99b
-        membar #StoreStore | #LoadStore
-       .size   membar_storestore_loadstore, .-membar_storestore_loadstore
index a026567f5d1878aaf53268ce8dceebb00194bd01..aa0bf7ee008d923d2f8264f5683313c871dac92b 100644 (file)
  *  -- verify the 13 conditions and do bulk resets
  *  -- kill last_pipe and simply do two-state clearing on both pipes
  *  -- verify protocol (bulk) from USB descriptors (maybe...)
- *  -- highmem and sg
+ *  -- highmem
  *  -- move top_sense and work_bcs into separate allocations (if they survive)
  *     for cache purists and esoteric architectures.
+ *  -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ?
  *  -- prune comments, they are too volumnous
  *  -- Exterminate P3 printks
  *  -- Resove XXX's
@@ -171,7 +172,7 @@ struct bulk_cs_wrap {
  */
 struct ub_dev;
 
-#define UB_MAX_REQ_SG  1
+#define UB_MAX_REQ_SG  4
 #define UB_MAX_SECTORS 64
 
 /*
@@ -234,13 +235,10 @@ struct ub_scsi_cmd {
 
        int stat_count;                 /* Retries getting status. */
 
-       /*
-        * We do not support transfers from highmem pages
-        * because the underlying USB framework does not do what we need.
-        */
-       char *data;                     /* Requested buffer */
        unsigned int len;               /* Requested length */
-       // struct scatterlist sgv[UB_MAX_REQ_SG];
+       unsigned int current_sg;
+       unsigned int nsg;               /* sgv[nsg] */
+       struct scatterlist sgv[UB_MAX_REQ_SG];
 
        struct ub_lun *lun;
        void (*done)(struct ub_dev *, struct ub_scsi_cmd *);
@@ -389,17 +387,18 @@ struct ub_dev {
        struct bulk_cs_wrap work_bcs;
        struct usb_ctrlrequest work_cr;
 
+       int sg_stat[UB_MAX_REQ_SG+1];
        struct ub_scsi_trace tr;
 };
 
 /*
  */
 static void ub_cleanup(struct ub_dev *sc);
-static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq);
+static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
 static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_scsi_cmd *cmd, struct request *rq);
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-    struct request *rq);
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct request *rq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_end_rq(struct request *rq, int uptodate);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -407,6 +406,7 @@ static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
 static void ub_scsi_action(unsigned long _dev);
 static void ub_scsi_dispatch(struct ub_dev *sc);
 static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
+static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc);
 static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -500,7 +500,8 @@ static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
        }
 }
 
-static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page)
+static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
+    char *page)
 {
        struct usb_interface *intf;
        struct ub_dev *sc;
@@ -523,6 +524,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, c
        cnt += sprintf(page + cnt,
            "qlen %d qmax %d\n",
            sc->cmd_queue.qlen, sc->cmd_queue.qmax);
+       cnt += sprintf(page + cnt,
+           "sg %d %d %d %d %d\n",
+           sc->sg_stat[0],
+           sc->sg_stat[1],
+           sc->sg_stat[2],
+           sc->sg_stat[3],
+           sc->sg_stat[4]);
 
        list_for_each (p, &sc->luns) {
                lun = list_entry(p, struct ub_lun, link);
@@ -744,20 +752,20 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc)
  * The request function is our main entry point
  */
 
-static void ub_bd_rq_fn(request_queue_t *q)
+static void ub_request_fn(request_queue_t *q)
 {
        struct ub_lun *lun = q->queuedata;
        struct request *rq;
 
        while ((rq = elv_next_request(q)) != NULL) {
-               if (ub_bd_rq_fn_1(lun, rq) != 0) {
+               if (ub_request_fn_1(lun, rq) != 0) {
                        blk_stop_queue(q);
                        break;
                }
        }
 }
 
-static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
+static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 {
        struct ub_dev *sc = lun->udev;
        struct ub_scsi_cmd *cmd;
@@ -774,9 +782,8 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
        memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 
        blkdev_dequeue_request(rq);
-
        if (blk_pc_request(rq)) {
-               rc = ub_cmd_build_packet(sc, cmd, rq);
+               rc = ub_cmd_build_packet(sc, lun, cmd, rq);
        } else {
                rc = ub_cmd_build_block(sc, lun, cmd, rq);
        }
@@ -791,7 +798,7 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
        cmd->back = rq;
 
        cmd->tag = sc->tagcnt++;
-       if ((rc = ub_submit_scsi(sc, cmd)) != 0) {
+       if (ub_submit_scsi(sc, cmd) != 0) {
                ub_put_cmd(lun, cmd);
                ub_end_rq(rq, 0);
                return 0;
@@ -804,58 +811,31 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_scsi_cmd *cmd, struct request *rq)
 {
        int ub_dir;
-#if 0 /* We use rq->buffer for now */
-       struct scatterlist *sg;
        int n_elem;
-#endif
        unsigned int block, nblks;
 
        if (rq_data_dir(rq) == WRITE)
                ub_dir = UB_DIR_WRITE;
        else
                ub_dir = UB_DIR_READ;
+       cmd->dir = ub_dir;
 
        /*
         * get scatterlist from block layer
         */
-#if 0 /* We use rq->buffer for now */
-       sg = &cmd->sgv[0];
-       n_elem = blk_rq_map_sg(q, rq, sg);
+       n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
        if (n_elem <= 0) {
-               ub_put_cmd(lun, cmd);
-               ub_end_rq(rq, 0);
-               blk_start_queue(q);
-               return 0;               /* request with no s/g entries? */
+               printk(KERN_INFO "%s: failed request map (%d)\n",
+                   sc->name, n_elem); /* P3 */
+               return -1;              /* request with no s/g entries? */
        }
-
-       if (n_elem != 1) {              /* Paranoia */
+       if (n_elem > UB_MAX_REQ_SG) {   /* Paranoia */
                printk(KERN_WARNING "%s: request with %d segments\n",
                    sc->name, n_elem);
-               ub_put_cmd(lun, cmd);
-               ub_end_rq(rq, 0);
-               blk_start_queue(q);
-               return 0;
-       }
-#endif
-
-       /*
-        * XXX Unfortunately, this check does not work. It is quite possible
-        * to get bogus non-null rq->buffer if you allow sg by mistake.
-        */
-       if (rq->buffer == NULL) {
-               /*
-                * This must not happen if we set the queue right.
-                * The block level must create bounce buffers for us.
-                */
-               static int do_print = 1;
-               if (do_print) {
-                       printk(KERN_WARNING "%s: unmapped block request"
-                           " flags 0x%lx sectors %lu\n",
-                           sc->name, rq->flags, rq->nr_sectors);
-                       do_print = 0;
-               }
                return -1;
        }
+       cmd->nsg = n_elem;
+       sc->sg_stat[n_elem]++;
 
        /*
         * build the command
@@ -876,30 +856,15 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
        cmd->cdb[8] = nblks;
        cmd->cdb_len = 10;
 
-       cmd->dir = ub_dir;
-       cmd->data = rq->buffer;
        cmd->len = rq->nr_sectors * 512;
 
        return 0;
 }
 
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-    struct request *rq)
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct request *rq)
 {
-
-       if (rq->data_len != 0 && rq->data == NULL) {
-               static int do_print = 1;
-               if (do_print) {
-                       printk(KERN_WARNING "%s: unmapped packet request"
-                           " flags 0x%lx length %d\n",
-                           sc->name, rq->flags, rq->data_len);
-                       do_print = 0;
-               }
-               return -1;
-       }
-
-       memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
-       cmd->cdb_len = rq->cmd_len;
+       int n_elem;
 
        if (rq->data_len == 0) {
                cmd->dir = UB_DIR_NONE;
@@ -908,8 +873,29 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
                        cmd->dir = UB_DIR_WRITE;
                else
                        cmd->dir = UB_DIR_READ;
+
+       }
+
+       /*
+        * get scatterlist from block layer
+        */
+       n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
+       if (n_elem < 0) {
+               printk(KERN_INFO "%s: failed request map (%d)\n",
+                   sc->name, n_elem); /* P3 */
+               return -1;
        }
-       cmd->data = rq->data;
+       if (n_elem > UB_MAX_REQ_SG) {   /* Paranoia */
+               printk(KERN_WARNING "%s: request with %d segments\n",
+                   sc->name, n_elem);
+               return -1;
+       }
+       cmd->nsg = n_elem;
+       sc->sg_stat[n_elem]++;
+
+       memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
+       cmd->cdb_len = rq->cmd_len;
+
        cmd->len = rq->data_len;
 
        return 0;
@@ -919,24 +905,34 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
        struct request *rq = cmd->back;
        struct ub_lun *lun = cmd->lun;
-       struct gendisk *disk = lun->disk;
-       request_queue_t *q = disk->queue;
        int uptodate;
 
-       if (blk_pc_request(rq)) {
-               /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
-               memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
-               rq->sense_len = UB_SENSE_SIZE;
-       }
-
-       if (cmd->error == 0)
+       if (cmd->error == 0) {
                uptodate = 1;
-       else
+
+               if (blk_pc_request(rq)) {
+                       if (cmd->act_len >= rq->data_len)
+                               rq->data_len = 0;
+                       else
+                               rq->data_len -= cmd->act_len;
+               }
+       } else {
                uptodate = 0;
 
+               if (blk_pc_request(rq)) {
+                       /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
+                       memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
+                       rq->sense_len = UB_SENSE_SIZE;
+                       if (sc->top_sense[0] != 0)
+                               rq->errors = SAM_STAT_CHECK_CONDITION;
+                       else
+                               rq->errors = DID_ERROR << 16;
+               }
+       }
+
        ub_put_cmd(lun, cmd);
        ub_end_rq(rq, uptodate);
-       blk_start_queue(q);
+       blk_start_queue(lun->disk->queue);
 }
 
 static void ub_end_rq(struct request *rq, int uptodate)
@@ -1014,7 +1010,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        sc->last_pipe = sc->send_bulk_pipe;
        usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
            bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
-       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
+       sc->work_urb.transfer_flags = 0;
 
        /* Fill what we shouldn't be filling, because usb-storage did so. */
        sc->work_urb.actual_length = 0;
@@ -1103,7 +1099,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
        struct urb *urb = &sc->work_urb;
        struct bulk_cs_wrap *bcs;
-       int pipe;
        int rc;
 
        if (atomic_read(&sc->poison)) {
@@ -1204,38 +1199,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        goto Bad_End;
                }
 
-               if (cmd->dir == UB_DIR_NONE) {
+               if (cmd->dir == UB_DIR_NONE || cmd->nsg < 1) {
                        ub_state_stat(sc, cmd);
                        return;
                }
 
-               UB_INIT_COMPLETION(sc->work_done);
-
-               if (cmd->dir == UB_DIR_READ)
-                       pipe = sc->recv_bulk_pipe;
-               else
-                       pipe = sc->send_bulk_pipe;
-               sc->last_pipe = pipe;
-               usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-                   cmd->data, cmd->len, ub_urb_complete, sc);
-               sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
-               sc->work_urb.actual_length = 0;
-               sc->work_urb.error_count = 0;
-               sc->work_urb.status = 0;
-
-               if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
-                       /* XXX Clear stalls */
-                       printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
-                       ub_complete(&sc->work_done);
-                       ub_state_done(sc, cmd, rc);
-                       return;
-               }
-
-               sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
-               add_timer(&sc->work_timer);
-
-               cmd->state = UB_CMDST_DATA;
-               ub_cmdtr_state(sc, cmd);
+               // udelay(125);         // usb-storage has this
+               ub_data_start(sc, cmd);
 
        } else if (cmd->state == UB_CMDST_DATA) {
                if (urb->status == -EPIPE) {
@@ -1257,16 +1227,22 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                if (urb->status == -EOVERFLOW) {
                        /*
                         * A babble? Failure, but we must transfer CSW now.
+                        * XXX This is going to end in perpetual babble. Reset.
                         */
                        cmd->error = -EOVERFLOW;        /* A cheap trick... */
-               } else {
-                       if (urb->status != 0)
-                               goto Bad_End;
+                       ub_state_stat(sc, cmd);
+                       return;
                }
+               if (urb->status != 0)
+                       goto Bad_End;
 
-               cmd->act_len = urb->actual_length;
+               cmd->act_len += urb->actual_length;
                ub_cmdtr_act_len(sc, cmd);
 
+               if (++cmd->current_sg < cmd->nsg) {
+                       ub_data_start(sc, cmd);
+                       return;
+               }
                ub_state_stat(sc, cmd);
 
        } else if (cmd->state == UB_CMDST_STAT) {
@@ -1399,6 +1375,46 @@ Bad_End: /* Little Excel is dead */
        ub_state_done(sc, cmd, -EIO);
 }
 
+/*
+ * Factorization helper for the command state machine:
+ * Initiate a data segment transfer.
+ */
+static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+{
+       struct scatterlist *sg = &cmd->sgv[cmd->current_sg];
+       int pipe;
+       int rc;
+
+       UB_INIT_COMPLETION(sc->work_done);
+
+       if (cmd->dir == UB_DIR_READ)
+               pipe = sc->recv_bulk_pipe;
+       else
+               pipe = sc->send_bulk_pipe;
+       sc->last_pipe = pipe;
+       usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
+           page_address(sg->page) + sg->offset, sg->length,
+           ub_urb_complete, sc);
+       sc->work_urb.transfer_flags = 0;
+       sc->work_urb.actual_length = 0;
+       sc->work_urb.error_count = 0;
+       sc->work_urb.status = 0;
+
+       if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
+               /* XXX Clear stalls */
+               printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
+               ub_complete(&sc->work_done);
+               ub_state_done(sc, cmd, rc);
+               return;
+       }
+
+       sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
+       add_timer(&sc->work_timer);
+
+       cmd->state = UB_CMDST_DATA;
+       ub_cmdtr_state(sc, cmd);
+}
+
 /*
  * Factorization helper for the command state machine:
  * Finish the command.
@@ -1426,7 +1442,7 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        sc->last_pipe = sc->recv_bulk_pipe;
        usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
            &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
-       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
+       sc->work_urb.transfer_flags = 0;
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
@@ -1484,6 +1500,7 @@ static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
        struct ub_scsi_cmd *scmd;
+       struct scatterlist *sg;
        int rc;
 
        if (cmd->cdb[0] == REQUEST_SENSE) {
@@ -1492,12 +1509,17 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        }
 
        scmd = &sc->top_rqs_cmd;
+       memset(scmd, 0, sizeof(struct ub_scsi_cmd));
        scmd->cdb[0] = REQUEST_SENSE;
        scmd->cdb[4] = UB_SENSE_SIZE;
        scmd->cdb_len = 6;
        scmd->dir = UB_DIR_READ;
        scmd->state = UB_CMDST_INIT;
-       scmd->data = sc->top_sense;
+       scmd->nsg = 1;
+       sg = &scmd->sgv[0];
+       sg->page = virt_to_page(sc->top_sense);
+       sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1);
+       sg->length = UB_SENSE_SIZE;
        scmd->len = UB_SENSE_SIZE;
        scmd->lun = cmd->lun;
        scmd->done = ub_top_sense_done;
@@ -1541,7 +1563,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 
        usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
            (unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
-       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
+       sc->work_urb.transfer_flags = 0;
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
@@ -1560,7 +1582,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
  */
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
 {
-       unsigned char *sense = scmd->data;
+       unsigned char *sense = sc->top_sense;
        struct ub_scsi_cmd *cmd;
 
        /*
@@ -1852,6 +1874,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_capacity *ret)
 {
        struct ub_scsi_cmd *cmd;
+       struct scatterlist *sg;
        char *p;
        enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) + 8 };
        unsigned long flags;
@@ -1872,7 +1895,11 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
        cmd->cdb_len = 10;
        cmd->dir = UB_DIR_READ;
        cmd->state = UB_CMDST_INIT;
-       cmd->data = p;
+       cmd->nsg = 1;
+       sg = &cmd->sgv[0];
+       sg->page = virt_to_page(p);
+       sg->offset = (unsigned int)p & (PAGE_SIZE-1);
+       sg->length = 8;
        cmd->len = 8;
        cmd->lun = lun;
        cmd->done = ub_probe_done;
@@ -2289,7 +2316,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
        disk->driverfs_dev = &sc->intf->dev;    /* XXX Many to one ok? */
 
        rc = -ENOMEM;
-       if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL)
+       if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
                goto err_blkqinit;
 
        disk->queue = q;
index 59f589d733f929d12639eab6852622a618a1796f..0a7624a9b1c1c6e3a3a5feffb3364f9e14c1eba9 100644 (file)
@@ -429,7 +429,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
        struct pci_dev *dev1;
        int i;
        unsigned size = amd64_fetch_size();
-       printk(KERN_INFO "Setting up ULi AGP. \n");
+       printk(KERN_INFO "Setting up ULi AGP.\n");
        dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0));
        if (dev1 == NULL) {
                printk(KERN_INFO PFX "Detected a ULi chipset, "
index f0079e991bdc4ffaf95c787e50bd9618a848e225..ac9da0ca36b7b1425a679ab74f3277e008ba661b 100644 (file)
@@ -319,7 +319,6 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)
                info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
        else
                info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
-       info->mode = bridge->mode;
        info->aper_base = bridge->gart_bus_addr;
        info->aper_size = agp_return_size();
        info->max_memory = bridge->max_memory_agp;
@@ -356,7 +355,7 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
                return -EINVAL;
 
        if (curr->is_bound == TRUE) {
-               printk (KERN_INFO PFX "memory %p is already bound!\n", curr);
+               printk(KERN_INFO PFX "memory %p is already bound!\n", curr);
                return -EINVAL;
        }
        if (curr->is_flushed == FALSE) {
@@ -391,7 +390,7 @@ int agp_unbind_memory(struct agp_memory *curr)
                return -EINVAL;
 
        if (curr->is_bound != TRUE) {
-               printk (KERN_INFO PFX "memory %p was not bound!\n", curr);
+               printk(KERN_INFO PFX "memory %p was not bound!\n", curr);
                return -EINVAL;
        }
 
@@ -415,7 +414,7 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
        u32 tmp;
 
        if (*requested_mode & AGP2_RESERVED_MASK) {
-               printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+               printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
                *requested_mode &= ~AGP2_RESERVED_MASK;
        }
 
@@ -423,7 +422,7 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
        tmp = *requested_mode & 7;
        switch (tmp) {
                case 0:
-                       printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
+                       printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
                        *requested_mode |= AGPSTAT2_1X;
                        break;
                case 1:
@@ -493,18 +492,18 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
        u32 tmp;
 
        if (*requested_mode & AGP3_RESERVED_MASK) {
-               printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+               printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
                *requested_mode &= ~AGP3_RESERVED_MASK;
        }
 
        /* Check the speed bits make sense. */
        tmp = *requested_mode & 7;
        if (tmp == 0) {
-               printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
+               printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
                *requested_mode |= AGPSTAT3_4X;
        }
        if (tmp >= 3) {
-               printk (KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
+               printk(KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
                *requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X;
        }
 
@@ -533,7 +532,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                 * AGP2.x 4x -> AGP3.0 4x.
                 */
                if (*requested_mode & AGPSTAT2_4X) {
-                       printk (KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
+                       printk(KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
                                                current->comm, *requested_mode);
                        *requested_mode &= ~AGPSTAT2_4X;
                        *requested_mode |= AGPSTAT3_4X;
@@ -544,7 +543,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                 * but have been passed an AGP 2.x mode.
                 * Convert AGP 1x,2x,4x -> AGP 3.0 4x.
                 */
-               printk (KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
+               printk(KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
                                        current->comm, *requested_mode);
                *requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X);
                *requested_mode |= AGPSTAT3_4X;
@@ -554,13 +553,13 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                if (!(*bridge_agpstat & AGPSTAT3_8X)) {
                        *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
                        *bridge_agpstat |= AGPSTAT3_4X;
-                       printk ("%s requested AGPx8 but bridge not capable.\n", current->comm);
+                       printk(KERN_INFO PFX "%s requested AGPx8 but bridge not capable.\n", current->comm);
                        return;
                }
                if (!(*vga_agpstat & AGPSTAT3_8X)) {
                        *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
                        *bridge_agpstat |= AGPSTAT3_4X;
-                       printk ("%s requested AGPx8 but graphic card not capable.\n", current->comm);
+                       printk(KERN_INFO PFX "%s requested AGPx8 but graphic card not capable.\n", current->comm);
                        return;
                }
                /* All set, bridge & device can do AGP x8*/
@@ -578,13 +577,13 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X))
                        *bridge_agpstat |= AGPSTAT3_4X;
                else {
-                       printk (KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
+                       printk(KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
                                                        "[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n",
                                                        origbridge, origvga, *bridge_agpstat, *vga_agpstat);
                        if (!(*bridge_agpstat & AGPSTAT3_4X))
-                               printk (KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
+                               printk(KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
                        if (!(*vga_agpstat & AGPSTAT3_4X))
-                               printk (KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
+                               printk(KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
                        return;
                }
        }
@@ -622,7 +621,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
        for (;;) {
                device = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, device);
                if (!device) {
-                       printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
+                       printk(KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
                        return 0;
                }
                cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
@@ -734,7 +733,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
                    pci_write_config_dword(bridge->dev,
                                        bridge->capndx+AGPCTRL, temp);
 
-                   printk (KERN_INFO PFX "Device is in legacy mode,"
+                   printk(KERN_INFO PFX "Device is in legacy mode,"
                                " falling back to 2.x\n");
                }
        }
index 6f98701dfe15da844eb19aa5e1483f6b73b21a97..121cc85f347e713dbaef7bcbe614cc8dcb48e33e 100644 (file)
@@ -1071,5 +1071,9 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
 extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
 extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
 
+#ifndef pci_pretty_name
+#define pci_pretty_name(dev) ""
+#endif
+
 #endif /* __KERNEL__ */
 #endif
index 10b0149823816b60dc4807a95f072142e1df3f42..109d62ccf6514fe5475154ed821c7cb6bbefcbdf 100644 (file)
@@ -627,7 +627,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
 
        ret = kobject_register(&policy->kobj);
        if (ret)
-               goto err_out;
+               goto err_out_driver_exit;
 
        /* set up files for this cpu device */
        drv_attr = cpufreq_driver->attr;
@@ -673,6 +673,10 @@ err_out_unregister:
        kobject_unregister(&policy->kobj);
        wait_for_completion(&policy->kobj_unregister);
 
+err_out_driver_exit:
+       if (cpufreq_driver->exit)
+               cpufreq_driver->exit(policy);
+
 err_out:
        kfree(policy);
 
index 6e9da1372225b73ab74c304824be223c5f078592..8334496a7e0aee02b42ca7b4953a165d2efb91e1 100644 (file)
@@ -144,6 +144,22 @@ config I2C_I810
          This driver can also be built as a module.  If so, the module
          will be called i2c-i810.
 
+config I2C_PXA
+       tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
+       depends on I2C && EXPERIMENTAL && ARCH_PXA
+       help
+         If you have devices in the PXA I2C bus, say yes to this option.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-pxa.
+
+config I2C_PXA_SLAVE
+       bool "Intel PXA2XX I2C Slave comms support"
+       depends on I2C_PXA
+       help
+         Support I2C slave mode communications on the PXA I2C bus.  This
+         is necessary for systems where the PXA may be a target on the
+         I2C bus.
+
 config I2C_PIIX4
        tristate "Intel PIIX4"
        depends on I2C && PCI
index 42d6d814da726f9445c420c1df801040d3924cb3..980b3e98367040acf2df92baede7212012add7a7 100644 (file)
@@ -28,6 +28,7 @@ obj-$(CONFIG_I2C_PARPORT_LIGHT)       += i2c-parport-light.o
 obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
 obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
 obj-$(CONFIG_I2C_PROSAVAGE)    += i2c-prosavage.o
+obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
 obj-$(CONFIG_I2C_RPXLITE)      += i2c-rpx.o
 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o
 obj-$(CONFIG_I2C_SAVAGE4)      += i2c-savage4.o
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
new file mode 100644 (file)
index 0000000..fdf53ce
--- /dev/null
@@ -0,0 +1,1022 @@
+/*
+ *  i2c_adap_pxa.c
+ *
+ *  I2C adapter for the PXA I2C bus access.
+ *
+ *  Copyright (C) 2002 Intrinsyc Software Inc.
+ *  Copyright (C) 2004-2005 Deep Blue Solutions Ltd.
+ *
+ *  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.
+ *
+ *  History:
+ *    Apr 2002: Initial version [CS]
+ *    Jun 2002: Properly seperated algo/adap [FB]
+ *    Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
+ *    Jan 2003: added limited signal handling [Kai-Uwe Bloem]
+ *    Sep 2004: Major rework to ensure efficient bus handling [RMK]
+ *    Dec 2004: Added support for PXA27x and slave device probing [Liam Girdwood]
+ *    Feb 2005: Rework slave mode handling [RMK]
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/i2c-pxa.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/i2c.h>
+#include <asm/arch/pxa-regs.h>
+
+struct pxa_i2c {
+       spinlock_t              lock;
+       wait_queue_head_t       wait;
+       struct i2c_msg          *msg;
+       unsigned int            msg_num;
+       unsigned int            msg_idx;
+       unsigned int            msg_ptr;
+       unsigned int            slave_addr;
+
+       struct i2c_adapter      adap;
+#ifdef CONFIG_I2C_PXA_SLAVE
+       struct i2c_slave_client *slave;
+#endif
+
+       unsigned int            irqlogidx;
+       u32                     isrlog[32];
+       u32                     icrlog[32];
+};
+
+/*
+ * I2C Slave mode address
+ */
+#define I2C_PXA_SLAVE_ADDR      0x1
+
+#ifdef DEBUG
+
+struct bits {
+       u32     mask;
+       const char *set;
+       const char *unset;
+};
+#define BIT(m, s, u)   { .mask = m, .set = s, .unset = u }
+
+static inline void
+decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
+{
+       printk("%s %08x: ", prefix, val);
+       while (num--) {
+               const char *str = val & bits->mask ? bits->set : bits->unset;
+               if (str)
+                       printk("%s ", str);
+               bits++;
+       }
+}
+
+static const struct bits isr_bits[] = {
+       BIT(ISR_RWM,    "RX",           "TX"),
+       BIT(ISR_ACKNAK, "NAK",          "ACK"),
+       BIT(ISR_UB,     "Bsy",          "Rdy"),
+       BIT(ISR_IBB,    "BusBsy",       "BusRdy"),
+       BIT(ISR_SSD,    "SlaveStop",    NULL),
+       BIT(ISR_ALD,    "ALD",          NULL),
+       BIT(ISR_ITE,    "TxEmpty",      NULL),
+       BIT(ISR_IRF,    "RxFull",       NULL),
+       BIT(ISR_GCAD,   "GenCall",      NULL),
+       BIT(ISR_SAD,    "SlaveAddr",    NULL),
+       BIT(ISR_BED,    "BusErr",       NULL),
+};
+
+static void decode_ISR(unsigned int val)
+{
+       decode_bits(KERN_DEBUG "ISR", isr_bits, ARRAY_SIZE(isr_bits), val);
+       printk("\n");
+}
+
+static const struct bits icr_bits[] = {
+       BIT(ICR_START,  "START",        NULL),
+       BIT(ICR_STOP,   "STOP",         NULL),
+       BIT(ICR_ACKNAK, "ACKNAK",       NULL),
+       BIT(ICR_TB,     "TB",           NULL),
+       BIT(ICR_MA,     "MA",           NULL),
+       BIT(ICR_SCLE,   "SCLE",         "scle"),
+       BIT(ICR_IUE,    "IUE",          "iue"),
+       BIT(ICR_GCD,    "GCD",          NULL),
+       BIT(ICR_ITEIE,  "ITEIE",        NULL),
+       BIT(ICR_IRFIE,  "IRFIE",        NULL),
+       BIT(ICR_BEIE,   "BEIE",         NULL),
+       BIT(ICR_SSDIE,  "SSDIE",        NULL),
+       BIT(ICR_ALDIE,  "ALDIE",        NULL),
+       BIT(ICR_SADIE,  "SADIE",        NULL),
+       BIT(ICR_UR,     "UR",           "ur"),
+};
+
+static void decode_ICR(unsigned int val)
+{
+       decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val);
+       printk("\n");
+}
+
+static unsigned int i2c_debug = DEBUG;
+
+static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
+{
+       dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno, ISR, ICR, IBMR);
+}
+
+#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
+#else
+#define i2c_debug      0
+
+#define show_state(i2c) do { } while (0)
+#define decode_ISR(val) do { } while (0)
+#define decode_ICR(val) do { } while (0)
+#endif
+
+#define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0)
+
+static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
+
+static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
+{
+       unsigned int i;
+       printk("i2c: error: %s\n", why);
+       printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
+               i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
+       printk("i2c: ICR: %08x ISR: %08x\n"
+              "i2c: log: ", ICR, ISR);
+       for (i = 0; i < i2c->irqlogidx; i++)
+               printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
+       printk("\n");
+}
+
+static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
+{
+       return !(ICR & ICR_SCLE);
+}
+
+static void i2c_pxa_abort(struct pxa_i2c *i2c)
+{
+       unsigned long timeout = jiffies + HZ/4;
+
+       if (i2c_pxa_is_slavemode(i2c)) {
+               dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__);
+               return;
+       }
+
+       while (time_before(jiffies, timeout) && (IBMR & 0x1) == 0) {
+               unsigned long icr = ICR;
+
+               icr &= ~ICR_START;
+               icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
+
+               ICR = icr;
+
+               show_state(i2c);
+
+               msleep(1);
+       }
+
+       ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
+}
+
+static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
+{
+       int timeout = DEF_TIMEOUT;
+
+       while (timeout-- && ISR & (ISR_IBB | ISR_UB)) {
+               if ((ISR & ISR_SAD) != 0)
+                       timeout += 4;
+
+               msleep(2);
+               show_state(i2c);
+       }
+
+       if (timeout <= 0)
+               show_state(i2c);
+
+       return timeout <= 0 ? I2C_RETRY : 0;
+}
+
+static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
+{
+       unsigned long timeout = jiffies + HZ*4;
+
+       while (time_before(jiffies, timeout)) {
+               if (i2c_debug > 1)
+                       dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
+                               __func__, (long)jiffies, ISR, ICR, IBMR);
+
+               if (ISR & ISR_SAD) {
+                       if (i2c_debug > 0)
+                               dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
+                       goto out;
+               }
+
+               /* wait for unit and bus being not busy, and we also do a
+                * quick check of the i2c lines themselves to ensure they've
+                * gone high...
+                */
+               if ((ISR & (ISR_UB | ISR_IBB)) == 0 && IBMR == 3) {
+                       if (i2c_debug > 0)
+                               dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
+                       return 1;
+               }
+
+               msleep(1);
+       }
+
+       if (i2c_debug > 0)
+               dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
+ out:
+       return 0;
+}
+
+static int i2c_pxa_set_master(struct pxa_i2c *i2c)
+{
+       if (i2c_debug)
+               dev_dbg(&i2c->adap.dev, "setting to bus master\n");
+
+       if ((ISR & (ISR_UB | ISR_IBB)) != 0) {
+               dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
+               if (!i2c_pxa_wait_master(i2c)) {
+                       dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
+                       return I2C_RETRY;
+               }
+       }
+
+       ICR |= ICR_SCLE;
+       return 0;
+}
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
+{
+       unsigned long timeout = jiffies + HZ*1;
+
+       /* wait for stop */
+
+       show_state(i2c);
+
+       while (time_before(jiffies, timeout)) {
+               if (i2c_debug > 1)
+                       dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
+                               __func__, (long)jiffies, ISR, ICR, IBMR);
+
+               if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD ||
+                   (ICR & ICR_SCLE) == 0) {
+                       if (i2c_debug > 1)
+                               dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
+                       return 1;
+               }
+
+               msleep(1);
+       }
+
+       if (i2c_debug > 0)
+               dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
+       return 0;
+}
+
+/*
+ * clear the hold on the bus, and take of anything else
+ * that has been configured
+ */
+static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
+{
+       show_state(i2c);
+
+       if (errcode < 0) {
+               udelay(100);   /* simple delay */
+       } else {
+               /* we need to wait for the stop condition to end */
+
+               /* if we where in stop, then clear... */
+               if (ICR & ICR_STOP) {
+                       udelay(100);
+                       ICR &= ~ICR_STOP;
+               }
+
+               if (!i2c_pxa_wait_slave(i2c)) {
+                       dev_err(&i2c->adap.dev, "%s: wait timedout\n",
+                               __func__);
+                       return;
+               }
+       }
+
+       ICR &= ~(ICR_STOP|ICR_ACKNAK|ICR_MA);
+       ICR &= ~ICR_SCLE;
+
+       if (i2c_debug) {
+               dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", ICR, ISR);
+               decode_ICR(ICR);
+       }
+}
+#else
+#define i2c_pxa_set_slave(i2c, err)    do { } while (0)
+#endif
+
+static void i2c_pxa_reset(struct pxa_i2c *i2c)
+{
+       pr_debug("Resetting I2C Controller Unit\n");
+
+       /* abort any transfer currently under way */
+       i2c_pxa_abort(i2c);
+
+       /* reset according to 9.8 */
+       ICR = ICR_UR;
+       ISR = I2C_ISR_INIT;
+       ICR &= ~ICR_UR;
+
+       ISAR = i2c->slave_addr;
+
+       /* set control register values */
+       ICR = I2C_ICR_INIT;
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+       dev_info(&i2c->adap.dev, "Enabling slave mode\n");
+       ICR |= ICR_SADIE | ICR_ALDIE | ICR_SSDIE;
+#endif
+
+       i2c_pxa_set_slave(i2c, 0);
+
+       /* enable unit */
+       ICR |= ICR_IUE;
+       udelay(100);
+}
+
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+/*
+ * I2C EEPROM emulation.
+ */
+static struct i2c_eeprom_emu eeprom = {
+       .size = I2C_EEPROM_EMU_SIZE,
+       .watch = LIST_HEAD_INIT(eeprom.watch),
+};
+
+struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void)
+{
+       return &eeprom;
+}
+
+int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *emu, void *data,
+                             unsigned int addr, unsigned int size,
+                             struct i2c_eeprom_emu_watcher *watcher)
+{
+       struct i2c_eeprom_emu_watch *watch;
+       unsigned long flags;
+
+       if (addr + size > emu->size)
+               return -EINVAL;
+
+       watch = kmalloc(sizeof(struct i2c_eeprom_emu_watch), GFP_KERNEL);
+       if (watch) {
+               watch->start = addr;
+               watch->end = addr + size - 1;
+               watch->ops = watcher;
+               watch->data = data;
+
+               local_irq_save(flags);
+               list_add(&watch->node, &emu->watch);
+               local_irq_restore(flags);
+       }
+
+       return watch ? 0 : -ENOMEM;
+}
+
+void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *emu, void *data,
+                              struct i2c_eeprom_emu_watcher *watcher)
+{
+       struct i2c_eeprom_emu_watch *watch, *n;
+       unsigned long flags;
+
+       list_for_each_entry_safe(watch, n, &emu->watch, node) {
+               if (watch->ops == watcher && watch->data == data) {
+                       local_irq_save(flags);
+                       list_del(&watch->node);
+                       local_irq_restore(flags);
+                       kfree(watch);
+               }
+       }
+}
+
+static void i2c_eeprom_emu_event(void *ptr, i2c_slave_event_t event)
+{
+       struct i2c_eeprom_emu *emu = ptr;
+
+       eedbg(3, "i2c_eeprom_emu_event: %d\n", event);
+
+       switch (event) {
+       case I2C_SLAVE_EVENT_START_WRITE:
+               emu->seen_start = 1;
+               eedbg(2, "i2c_eeprom: write initiated\n");
+               break;
+
+       case I2C_SLAVE_EVENT_START_READ:
+               emu->seen_start = 0;
+               eedbg(2, "i2c_eeprom: read initiated\n");
+               break;
+
+       case I2C_SLAVE_EVENT_STOP:
+               emu->seen_start = 0;
+               eedbg(2, "i2c_eeprom: received stop\n");
+               break;
+
+       default:
+               eedbg(0, "i2c_eeprom: unhandled event\n");
+               break;
+       }
+}
+
+static int i2c_eeprom_emu_read(void *ptr)
+{
+       struct i2c_eeprom_emu *emu = ptr;
+       int ret;
+
+       ret = emu->bytes[emu->ptr];
+       emu->ptr = (emu->ptr + 1) % emu->size;
+
+       return ret;
+}
+
+static void i2c_eeprom_emu_write(void *ptr, unsigned int val)
+{
+       struct i2c_eeprom_emu *emu = ptr;
+       struct i2c_eeprom_emu_watch *watch;
+
+       if (emu->seen_start != 0) {
+               eedbg(2, "i2c_eeprom_emu_write: setting ptr %02x\n", val);
+               emu->ptr = val;
+               emu->seen_start = 0;
+               return;
+       }
+
+       emu->bytes[emu->ptr] = val;
+
+       eedbg(1, "i2c_eeprom_emu_write: ptr=0x%02x, val=0x%02x\n",
+             emu->ptr, val);
+
+       list_for_each_entry(watch, &emu->watch, node) {
+               if (!watch->ops || !watch->ops->write)
+                       continue;
+               if (watch->start <= emu->ptr && watch->end >= emu->ptr)
+                       watch->ops->write(watch->data, emu->ptr, val);
+       }
+
+       emu->ptr = (emu->ptr + 1) % emu->size;
+}
+
+struct i2c_slave_client eeprom_client = {
+       .data   = &eeprom,
+       .event  = i2c_eeprom_emu_event,
+       .read   = i2c_eeprom_emu_read,
+       .write  = i2c_eeprom_emu_write
+};
+
+/*
+ * PXA I2C Slave mode
+ */
+
+static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
+{
+       if (isr & ISR_BED) {
+               /* what should we do here? */
+       } else {
+               int ret = i2c->slave->read(i2c->slave->data);
+
+               IDBR = ret;
+               ICR |= ICR_TB;   /* allow next byte */
+       }
+}
+
+static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
+{
+       unsigned int byte = IDBR;
+
+       if (i2c->slave != NULL)
+               i2c->slave->write(i2c->slave->data, byte);
+
+       ICR |= ICR_TB;
+}
+
+static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
+{
+       int timeout;
+
+       if (i2c_debug > 0)
+               dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n",
+                      (isr & ISR_RWM) ? 'r' : 't');
+
+       if (i2c->slave != NULL)
+               i2c->slave->event(i2c->slave->data,
+                                (isr & ISR_RWM) ? I2C_SLAVE_EVENT_START_READ : I2C_SLAVE_EVENT_START_WRITE);
+
+       /*
+        * slave could interrupt in the middle of us generating a
+        * start condition... if this happens, we'd better back off
+        * and stop holding the poor thing up
+        */
+       ICR &= ~(ICR_START|ICR_STOP);
+       ICR |= ICR_TB;
+
+       timeout = 0x10000;
+
+       while (1) {
+               if ((IBMR & 2) == 2)
+                       break;
+
+               timeout--;
+
+               if (timeout <= 0) {
+                       dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
+                       break;
+               }
+       }
+
+       ICR &= ~ICR_SCLE;
+}
+
+static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
+{
+       if (i2c_debug > 2)
+               dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n");
+
+       if (i2c->slave != NULL)
+               i2c->slave->event(i2c->slave->data, I2C_SLAVE_EVENT_STOP);
+
+       if (i2c_debug > 2)
+               dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n");
+
+       /*
+        * If we have a master-mode message waiting,
+        * kick it off now that the slave has completed.
+        */
+       if (i2c->msg)
+               i2c_pxa_master_complete(i2c, I2C_RETRY);
+}
+#else
+static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
+{
+       if (isr & ISR_BED) {
+               /* what should we do here? */
+       } else {
+               IDBR = 0;
+               ICR |= ICR_TB;
+       }
+}
+
+static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
+{
+       ICR |= ICR_TB | ICR_ACKNAK;
+}
+
+static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
+{
+       int timeout;
+
+       /*
+        * slave could interrupt in the middle of us generating a
+        * start condition... if this happens, we'd better back off
+        * and stop holding the poor thing up
+        */
+       ICR &= ~(ICR_START|ICR_STOP);
+       ICR |= ICR_TB | ICR_ACKNAK;
+
+       timeout = 0x10000;
+
+       while (1) {
+               if ((IBMR & 2) == 2)
+                       break;
+
+               timeout--;
+
+               if (timeout <= 0) {
+                       dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
+                       break;
+               }
+       }
+
+       ICR &= ~ICR_SCLE;
+}
+
+static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
+{
+       if (i2c->msg)
+               i2c_pxa_master_complete(i2c, I2C_RETRY);
+}
+#endif
+
+/*
+ * PXA I2C Master mode
+ */
+
+static inline unsigned int i2c_pxa_addr_byte(struct i2c_msg *msg)
+{
+       unsigned int addr = (msg->addr & 0x7f) << 1;
+
+       if (msg->flags & I2C_M_RD)
+               addr |= 1;
+
+       return addr;
+}
+
+static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
+{
+       u32 icr;
+
+       /*
+        * Step 1: target slave address into IDBR
+        */
+       IDBR = i2c_pxa_addr_byte(i2c->msg);
+
+       /*
+        * Step 2: initiate the write.
+        */
+       icr = ICR & ~(ICR_STOP | ICR_ALDIE);
+       ICR = icr | ICR_START | ICR_TB;
+}
+
+/*
+ * We are protected by the adapter bus semaphore.
+ */
+static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
+{
+       long timeout;
+       int ret;
+
+       /*
+        * Wait for the bus to become free.
+        */
+       ret = i2c_pxa_wait_bus_not_busy(i2c);
+       if (ret) {
+               dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
+               goto out;
+       }
+
+       /*
+        * Set master mode.
+        */
+       ret = i2c_pxa_set_master(i2c);
+       if (ret) {
+               dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
+               goto out;
+       }
+
+       spin_lock_irq(&i2c->lock);
+
+       i2c->msg = msg;
+       i2c->msg_num = num;
+       i2c->msg_idx = 0;
+       i2c->msg_ptr = 0;
+       i2c->irqlogidx = 0;
+
+       i2c_pxa_start_message(i2c);
+
+       spin_unlock_irq(&i2c->lock);
+
+       /*
+        * The rest of the processing occurs in the interrupt handler.
+        */
+       timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+
+       /*
+        * We place the return code in i2c->msg_idx.
+        */
+       ret = i2c->msg_idx;
+
+       if (timeout == 0)
+               i2c_pxa_scream_blue_murder(i2c, "timeout");
+
+ out:
+       return ret;
+}
+
+/*
+ * i2c_pxa_master_complete - complete the message and wake up.
+ */
+static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
+{
+       i2c->msg_ptr = 0;
+       i2c->msg = NULL;
+       i2c->msg_idx ++;
+       i2c->msg_num = 0;
+       if (ret)
+               i2c->msg_idx = ret;
+       wake_up(&i2c->wait);
+}
+
+static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
+{
+       u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+
+ again:
+       /*
+        * If ISR_ALD is set, we lost arbitration.
+        */
+       if (isr & ISR_ALD) {
+               /*
+                * Do we need to do anything here?  The PXA docs
+                * are vague about what happens.
+                */
+               i2c_pxa_scream_blue_murder(i2c, "ALD set");
+
+               /*
+                * We ignore this error.  We seem to see spurious ALDs
+                * for seemingly no reason.  If we handle them as I think
+                * they should, we end up causing an I2C error, which
+                * is painful for some systems.
+                */
+               return; /* ignore */
+       }
+
+       if (isr & ISR_BED) {
+               int ret = BUS_ERROR;
+
+               /*
+                * I2C bus error - either the device NAK'd us, or
+                * something more serious happened.  If we were NAK'd
+                * on the initial address phase, we can retry.
+                */
+               if (isr & ISR_ACKNAK) {
+                       if (i2c->msg_ptr == 0 && i2c->msg_idx == 0)
+                               ret = I2C_RETRY;
+                       else
+                               ret = XFER_NAKED;
+               }
+               i2c_pxa_master_complete(i2c, ret);
+       } else if (isr & ISR_RWM) {
+               /*
+                * Read mode.  We have just sent the address byte, and
+                * now we must initiate the transfer.
+                */
+               if (i2c->msg_ptr == i2c->msg->len - 1 &&
+                   i2c->msg_idx == i2c->msg_num - 1)
+                       icr |= ICR_STOP | ICR_ACKNAK;
+
+               icr |= ICR_ALDIE | ICR_TB;
+       } else if (i2c->msg_ptr < i2c->msg->len) {
+               /*
+                * Write mode.  Write the next data byte.
+                */
+               IDBR = i2c->msg->buf[i2c->msg_ptr++];
+
+               icr |= ICR_ALDIE | ICR_TB;
+
+               /*
+                * If this is the last byte of the last message, send
+                * a STOP.
+                */
+               if (i2c->msg_ptr == i2c->msg->len &&
+                   i2c->msg_idx == i2c->msg_num - 1)
+                       icr |= ICR_STOP;
+       } else if (i2c->msg_idx < i2c->msg_num - 1) {
+               /*
+                * Next segment of the message.
+                */
+               i2c->msg_ptr = 0;
+               i2c->msg_idx ++;
+               i2c->msg++;
+
+               /*
+                * If we aren't doing a repeated start and address,
+                * go back and try to send the next byte.  Note that
+                * we do not support switching the R/W direction here.
+                */
+               if (i2c->msg->flags & I2C_M_NOSTART)
+                       goto again;
+
+               /*
+                * Write the next address.
+                */
+               IDBR = i2c_pxa_addr_byte(i2c->msg);
+
+               /*
+                * And trigger a repeated start, and send the byte.
+                */
+               icr &= ~ICR_ALDIE;
+               icr |= ICR_START | ICR_TB;
+       } else {
+               if (i2c->msg->len == 0) {
+                       /*
+                        * Device probes have a message length of zero
+                        * and need the bus to be reset before it can
+                        * be used again.
+                        */
+                       i2c_pxa_reset(i2c);
+               }
+               i2c_pxa_master_complete(i2c, 0);
+       }
+
+       i2c->icrlog[i2c->irqlogidx-1] = icr;
+
+       ICR = icr;
+       show_state(i2c);
+}
+
+static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
+{
+       u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+
+       /*
+        * Read the byte.
+        */
+       i2c->msg->buf[i2c->msg_ptr++] = IDBR;
+
+       if (i2c->msg_ptr < i2c->msg->len) {
+               /*
+                * If this is the last byte of the last
+                * message, send a STOP.
+                */
+               if (i2c->msg_ptr == i2c->msg->len - 1)
+                       icr |= ICR_STOP | ICR_ACKNAK;
+
+               icr |= ICR_ALDIE | ICR_TB;
+       } else {
+               i2c_pxa_master_complete(i2c, 0);
+       }
+
+       i2c->icrlog[i2c->irqlogidx-1] = icr;
+
+       ICR = icr;
+}
+
+static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
+{
+       struct pxa_i2c *i2c = dev_id;
+       u32 isr = ISR;
+
+       if (i2c_debug > 2 && 0) {
+               dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
+                       __func__, isr, ICR, IBMR);
+               decode_ISR(isr);
+       }
+
+       if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32))
+               i2c->isrlog[i2c->irqlogidx++] = isr;
+
+       show_state(i2c);
+
+       /*
+        * Always clear all pending IRQs.
+        */
+       ISR = isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED);
+
+       if (isr & ISR_SAD)
+               i2c_pxa_slave_start(i2c, isr);
+       if (isr & ISR_SSD)
+               i2c_pxa_slave_stop(i2c);
+
+       if (i2c_pxa_is_slavemode(i2c)) {
+               if (isr & ISR_ITE)
+                       i2c_pxa_slave_txempty(i2c, isr);
+               if (isr & ISR_IRF)
+                       i2c_pxa_slave_rxfull(i2c, isr);
+       } else if (i2c->msg) {
+               if (isr & ISR_ITE)
+                       i2c_pxa_irq_txempty(i2c, isr);
+               if (isr & ISR_IRF)
+                       i2c_pxa_irq_rxfull(i2c, isr);
+       } else {
+               i2c_pxa_scream_blue_murder(i2c, "spurious irq");
+       }
+
+       return IRQ_HANDLED;
+}
+
+
+static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+       struct pxa_i2c *i2c = adap->algo_data;
+       int ret, i;
+
+       for (i = adap->retries; i >= 0; i--) {
+               ret = i2c_pxa_do_xfer(i2c, msgs, num);
+               if (ret != I2C_RETRY)
+                       goto out;
+
+               if (i2c_debug)
+                       dev_dbg(&adap->dev, "Retrying transmission\n");
+               udelay(100);
+       }
+       i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
+       ret = -EREMOTEIO;
+ out:
+       i2c_pxa_set_slave(i2c, ret);
+       return ret;
+}
+
+static struct i2c_algorithm i2c_pxa_algorithm = {
+       .name           = "PXA-I2C-Algorithm",
+       .id             = I2C_ALGO_PXA,
+       .master_xfer    = i2c_pxa_xfer,
+};
+
+static struct pxa_i2c i2c_pxa = {
+       .lock   = SPIN_LOCK_UNLOCKED,
+       .wait   = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
+       .adap   = {
+               .name           = "pxa2xx-i2c",
+               .id             = I2C_ALGO_PXA,
+               .algo           = &i2c_pxa_algorithm,
+               .retries        = 5,
+       },
+};
+
+static int i2c_pxa_probe(struct device *dev)
+{
+       struct pxa_i2c *i2c = &i2c_pxa;
+       struct i2c_pxa_platform_data *plat = dev->platform_data;
+       int ret;
+
+#ifdef CONFIG_PXA27x
+       pxa_gpio_mode(GPIO117_I2CSCL_MD);
+       pxa_gpio_mode(GPIO118_I2CSDA_MD);
+       udelay(100);
+#endif
+
+       i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+       i2c->slave = &eeprom_client;
+       if (plat) {
+               i2c->slave_addr = plat->slave_addr;
+               if (plat->slave)
+                       i2c->slave = plat->slave;
+       }
+#endif
+
+       pxa_set_cken(CKEN14_I2C, 1);
+       ret = request_irq(IRQ_I2C, i2c_pxa_handler, SA_INTERRUPT,
+                         "pxa2xx-i2c", i2c);
+       if (ret)
+               goto out;
+
+       i2c_pxa_reset(i2c);
+
+       i2c->adap.algo_data = i2c;
+       i2c->adap.dev.parent = dev;
+
+       ret = i2c_add_adapter(&i2c->adap);
+       if (ret < 0) {
+               printk(KERN_INFO "I2C: Failed to add bus\n");
+               goto err_irq;
+       }
+
+       dev_set_drvdata(dev, i2c);
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+       printk(KERN_INFO "I2C: %s: PXA I2C adapter, slave address %d\n",
+              i2c->adap.dev.bus_id, i2c->slave_addr);
+#else
+       printk(KERN_INFO "I2C: %s: PXA I2C adapter\n",
+              i2c->adap.dev.bus_id);
+#endif
+       return 0;
+
+ err_irq:
+       free_irq(IRQ_I2C, i2c);
+ out:
+       return ret;
+}
+
+static int i2c_pxa_remove(struct device *dev)
+{
+       struct pxa_i2c *i2c = dev_get_drvdata(dev);
+
+       dev_set_drvdata(dev, NULL);
+
+       i2c_del_adapter(&i2c->adap);
+       free_irq(IRQ_I2C, i2c);
+       pxa_set_cken(CKEN14_I2C, 0);
+
+       return 0;
+}
+
+static struct device_driver i2c_pxa_driver = {
+       .name           = "pxa2xx-i2c",
+       .bus            = &platform_bus_type,
+       .probe          = i2c_pxa_probe,
+       .remove         = i2c_pxa_remove,
+};
+
+static int __init i2c_adap_pxa_init(void)
+{
+       return driver_register(&i2c_pxa_driver);
+}
+
+static void i2c_adap_pxa_exit(void)
+{
+       return driver_unregister(&i2c_pxa_driver);
+}
+
+module_init(i2c_adap_pxa_init);
+module_exit(i2c_adap_pxa_exit);
index 3241d6c9dc11d2f2a959224f22cd58070449d0b5..ffbcd40418d5fd82f8d246e0585fb7bd5ede17c7 100644 (file)
@@ -937,12 +937,12 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
                ++mthca_version_printed;
        }
 
-       printk(KERN_INFO PFX "Initializing %s (%s)\n",
-              pci_pretty_name(pdev), pci_name(pdev));
+       printk(KERN_INFO PFX "Initializing %s\n",
+              pci_name(pdev));
 
        if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
-               printk(KERN_ERR PFX "%s (%s) has invalid driver data %lx\n",
-                      pci_pretty_name(pdev), pci_name(pdev), id->driver_data);
+               printk(KERN_ERR PFX "%s has invalid driver data %lx\n",
+                      pci_name(pdev), id->driver_data);
                return -ENODEV;
        }
 
index 8ea801271a41581d468c011fd4c65a923d1884ee..4f995391dd1d8176e7ff0cc25f4ac5b049288ae3 100644 (file)
@@ -71,8 +71,8 @@ int mthca_reset(struct mthca_dev *mdev)
                                                bridge)) != NULL) {
                        if (bridge->hdr_type    == PCI_HEADER_TYPE_BRIDGE &&
                            bridge->subordinate == mdev->pdev->bus) {
-                               mthca_dbg(mdev, "Found bridge: %s (%s)\n",
-                                         pci_pretty_name(bridge), pci_name(bridge));
+                               mthca_dbg(mdev, "Found bridge: %s\n",
+                                         pci_name(bridge));
                                break;
                        }
                }
@@ -83,8 +83,8 @@ int mthca_reset(struct mthca_dev *mdev)
                         * assume we're in no-bridge mode and hope for
                         * the best.
                         */
-                       mthca_warn(mdev, "No bridge found for %s (%s)\n",
-                                 pci_pretty_name(mdev->pdev), pci_name(mdev->pdev));
+                       mthca_warn(mdev, "No bridge found for %s\n",
+                                 pci_name(mdev->pdev));
                }
 
        }
index 0a117c61cd1809e4f2ee6d924ac716810c8c848e..ceae379a4d4c56227541582affc855785fc248c5 100644 (file)
@@ -1079,13 +1079,17 @@ static void mmc_setup(struct mmc_host *host)
 /**
  *     mmc_detect_change - process change of state on a MMC socket
  *     @host: host which changed state.
+ *     @delay: optional delay to wait before detection (jiffies)
  *
  *     All we know is that card(s) have been inserted or removed
  *     from the socket(s).  We don't know which socket or cards.
  */
-void mmc_detect_change(struct mmc_host *host)
+void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 {
-       schedule_work(&host->detect);
+       if (delay)
+               schedule_delayed_work(&host->detect, delay);
+       else
+               schedule_work(&host->detect);
 }
 
 EXPORT_SYMBOL(mmc_detect_change);
@@ -1189,7 +1193,7 @@ int mmc_add_host(struct mmc_host *host)
        ret = mmc_add_host_sysfs(host);
        if (ret == 0) {
                mmc_power_off(host);
-               mmc_detect_change(host);
+               mmc_detect_change(host, 0);
        }
 
        return ret;
@@ -1259,7 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-       mmc_detect_change(host);
+       mmc_detect_change(host, 0);
 
        return 0;
 }
index 716c4ef4faf6f8c46c9582d5211d5fba3a332255..91c74843dc0d8c54c88bec1973a44eda18b0866b 100644 (file)
@@ -442,7 +442,7 @@ static void mmci_check_status(unsigned long data)
 
        status = host->plat->status(mmc_dev(host->mmc));
        if (status ^ host->oldstat)
-               mmc_detect_change(host->mmc);
+               mmc_detect_change(host->mmc, 0);
 
        host->oldstat = status;
        mod_timer(&host->timer, jiffies + HZ);
index e99a53b09e321390d683362cf483923774d535a7..b53af57074e3296b5bf994c105f37a42b3a8398a 100644 (file)
@@ -423,7 +423,9 @@ static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
 
 static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
 {
-       mmc_detect_change(devid);
+       struct pxamci_host *host = mmc_priv(devid);
+
+       mmc_detect_change(devid, host->pdata->detect_delay);
        return IRQ_HANDLED;
 }
 
index dec01d38c782fce5935ffb575ca90122934260e7..a62c86fef5ccc094f8a5e65ee0375837d14548e2 100644 (file)
@@ -1122,7 +1122,7 @@ static void wbsd_detect_card(unsigned long data)
        
        DBG("Executing card detection\n");
        
-       mmc_detect_change(host->mmc);   
+       mmc_detect_change(host->mmc, 0);        
 }
 
 /*
@@ -1198,7 +1198,7 @@ static void wbsd_tasklet_card(unsigned long param)
                 */
                spin_unlock(&host->lock);
 
-               mmc_detect_change(host->mmc);
+               mmc_detect_change(host->mmc, 0);
        }
        else
                spin_unlock(&host->lock);
index 55a72c7ad001a20ae03b4c3ebf3fe61281688884..83598e32179cee8c1f81b851e37c67f8fc736f87 100644 (file)
@@ -14,8 +14,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.2.20"
-#define DRV_MODULE_RELDATE     "August 22, 2005"
+#define DRV_MODULE_VERSION     "1.2.21"
+#define DRV_MODULE_RELDATE     "September 7, 2005"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -1533,6 +1533,7 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = dev->priv;
 
+       prefetch(bp->status_blk);
        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
                BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -1558,7 +1559,7 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
         * When using MSI, the MSI message will always complete after
         * the status block write.
         */
-       if ((bp->status_blk->status_idx == bp->last_status_idx) ||
+       if ((bp->status_blk->status_idx == bp->last_status_idx) &&
            (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
             BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
                return IRQ_NONE;
index 9ad3f5740cd8ee450a3aa96b2996b4d8c8882fca..62857b6a6ee41ea7bb086904a68f75f71abc4469 100644 (file)
@@ -50,6 +50,7 @@
 #endif
 #include <linux/workqueue.h>
 #include <linux/crc32.h>
+#include <linux/prefetch.h>
 
 /* Hardware data structures and register definitions automatically
  * generated from RTL code. Do not modify.
index 46e0022d3258ab3c870cf62e70a211c06a99d1ef..6c766fdc51a6970a9a7adf1f2a9f5640b5f3b4ad 100644 (file)
@@ -267,7 +267,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
                       frame, IRDA_USB_SPEED_MTU,
                       speed_bulk_callback, self);
        urb->transfer_buffer_length = USB_IRDA_HEADER;
-       urb->transfer_flags = URB_ASYNC_UNLINK;
+       urb->transfer_flags = 0;
 
        /* Irq disabled -> GFP_ATOMIC */
        if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) {
@@ -401,15 +401,12 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
                       skb->data, IRDA_SKB_MAX_MTU,
                       write_bulk_callback, skb);
        urb->transfer_buffer_length = skb->len;
-       /* Note : unlink *must* be Asynchronous because of the code in 
-        * irda_usb_net_timeout() -> call in irq - Jean II */
-       urb->transfer_flags = URB_ASYNC_UNLINK;
        /* This flag (URB_ZERO_PACKET) indicates that what we send is not
         * a continuous stream of data but separate packets.
         * In this case, the USB layer will insert an empty USB frame (TD)
         * after each of our packets that is exact multiple of the frame size.
         * This is how the dongle will detect the end of packet - Jean II */
-       urb->transfer_flags |= URB_ZERO_PACKET;
+       urb->transfer_flags = URB_ZERO_PACKET;
 
        /* Generate min turn time. FIXME: can we do better than this? */
        /* Trying to a turnaround time at this level is trying to measure
@@ -630,8 +627,6 @@ static void irda_usb_net_timeout(struct net_device *netdev)
                         * in completion handler, because urb->status will
                         * be -ENOENT. We will fix that at the next watchdog,
                         * leaving more time to USB to recover...
-                        * Also, we are in interrupt, so we need to have
-                        * URB_ASYNC_UNLINK to work properly...
                         * Jean II */
                        done = 1;
                        break;
@@ -1008,9 +1003,7 @@ static int irda_usb_net_close(struct net_device *netdev)
                }
        }
        /* Cancel Tx and speed URB - need to be synchronous to avoid races */
-       self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
        usb_kill_urb(self->tx_urb);
-       self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
        usb_kill_urb(self->speed_urb);
 
        /* Stop and remove instance of IrLAP */
@@ -1521,9 +1514,7 @@ static void irda_usb_disconnect(struct usb_interface *intf)
                        usb_kill_urb(self->rx_urb[i]);
                /* Cancel Tx and speed URB.
                 * Toggle flags to make sure it's synchronous. */
-               self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
                usb_kill_urb(self->tx_urb);
-               self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
                usb_kill_urb(self->speed_urb);
        }
 
index 414694abf588fe8eed1d6a10908fe075c74a87f3..741aecc655dfe7d9da06d610c77a1eb8e4a60618 100644 (file)
@@ -69,14 +69,8 @@ typedef void irqreturn_t;
 
 #else /* 2.5 or later */
 
-/* recent 2.5/2.6 stores pci device names at varying places ;-) */
-#ifdef CONFIG_PCI_NAMES
-/* human readable name */
-#define PCIDEV_NAME(pdev)      ((pdev)->pretty_name)
-#else
 /* whatever we get from the associated struct device - bus:slot:dev.fn id */
 #define PCIDEV_NAME(pdev)      (pci_name(pdev))
-#endif
 
 #endif
 
index 97f723179f621d15ed3f9283a8a80446aa4a2cb0..1b938bb9be3cc0a985c8b22d80fbdac97344e33a 100644 (file)
@@ -3010,7 +3010,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma)
        struct pci_dev *pdev = NULL;
        int ret = 0;
 
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+       for_each_pci_dev(pdev) {
                id = pci_match_id(parport_pc_pci_tbl, pdev);
                if (id == NULL || id->driver_data >= last_sio)
                        continue;
index 7f31991772ea4b0b2c51966479642f6e63c66490..f187fd8aeed6483d72c3b07ae72c49f2333fdbd9 100644 (file)
@@ -30,23 +30,6 @@ config PCI_LEGACY_PROC
 
          When in doubt, say N.
 
-config PCI_NAMES
-       bool "PCI device name database"
-       depends on PCI
-       ---help---
-         By default, the kernel contains a database of all known PCI device
-         names to make the information in /proc/pci, /proc/ioports and
-         similar files comprehensible to the user. 
-
-         This database increases size of the kernel image by about 80KB. This 
-         memory is freed after the system boots up if CONFIG_HOTPLUG is not set.
-
-         Anyway, if you are building an installation floppy or kernel for an 
-         embedded system where kernel image size really matters, you can disable 
-         this feature and you'll get device ID numbers instead of names.
-
-         When in doubt, say Y.
-
 config PCI_DEBUG
        bool "PCI Debugging"
        depends on PCI && DEBUG_KERNEL
index 3657f6199c48f8e579a8d1f49b91c0217f1ce0d7..716df015f8d017b4a5216f1e34e345bc5b813dd1 100644 (file)
@@ -3,14 +3,9 @@
 #
 
 obj-y          += access.o bus.o probe.o remove.o pci.o quirks.o \
-                       names.o pci-driver.o search.o pci-sysfs.o \
-                       rom.o
+                       pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
 obj-$(CONFIG_PROC_FS) += proc.o
 
-ifndef CONFIG_SPARC64
-obj-y += setup-res.o
-endif
-
 obj-$(CONFIG_HOTPLUG) += hotplug.o
 
 # Build the PCI Hotplug drivers if we were asked to
@@ -46,21 +41,6 @@ ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
 endif
 
-hostprogs-y := gen-devlist
-
-# Dependencies on generated files need to be listed explicitly
-$(obj)/names.o: $(obj)/devlist.h $(obj)/classlist.h
-$(obj)/classlist.h: $(obj)/devlist.h
-
-# And that's how to generate them
-quiet_cmd_devlist = DEVLIST $@
-      cmd_devlist = ( cd $(obj); ./gen-devlist ) < $<
-$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
-       $(call cmd,devlist)
-
-# Files generated that shall be removed upon make clean
-clean-files := devlist.h classlist.h
-
 # Build PCI Express stuff if needed
 obj-$(CONFIG_PCIEPORTBUS) += pcie/
 
index fb9a11243d2a1fbff876749a997617cfb4013670..eed67d9e73bcd6e3e9ac684342d460a1ac77c62b 100644 (file)
@@ -140,16 +140,65 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
 void pci_enable_bridges(struct pci_bus *bus)
 {
        struct pci_dev *dev;
+       int retval;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
                if (dev->subordinate) {
-                       pci_enable_device(dev);
+                       retval = pci_enable_device(dev);
                        pci_set_master(dev);
                        pci_enable_bridges(dev->subordinate);
                }
        }
 }
 
+/** pci_walk_bus - walk devices on/under bus, calling callback.
+ *  @top      bus whose devices should be walked
+ *  @cb       callback to be called for each device found
+ *  @userdata arbitrary pointer to be passed to callback.
+ *
+ *  Walk the given bus, including any bridged devices
+ *  on buses under this bus.  Call the provided callback
+ *  on each device found.
+ */
+void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+                 void *userdata)
+{
+       struct pci_dev *dev;
+       struct pci_bus *bus;
+       struct list_head *next;
+
+       bus = top;
+       spin_lock(&pci_bus_lock);
+       next = top->devices.next;
+       for (;;) {
+               if (next == &bus->devices) {
+                       /* end of this bus, go up or finish */
+                       if (bus == top)
+                               break;
+                       next = bus->self->bus_list.next;
+                       bus = bus->self->bus;
+                       continue;
+               }
+               dev = list_entry(next, struct pci_dev, bus_list);
+               pci_dev_get(dev);
+               if (dev->subordinate) {
+                       /* this is a pci-pci bridge, do its devices next */
+                       next = dev->subordinate->devices.next;
+                       bus = dev->subordinate;
+               } else
+                       next = dev->bus_list.next;
+               spin_unlock(&pci_bus_lock);
+
+               /* Run device routines with the bus unlocked */
+               cb(dev, userdata);
+
+               spin_lock(&pci_bus_lock);
+               pci_dev_put(dev);
+       }
+       spin_unlock(&pci_bus_lock);
+}
+EXPORT_SYMBOL_GPL(pci_walk_bus);
+
 EXPORT_SYMBOL(pci_bus_alloc_resource);
 EXPORT_SYMBOL_GPL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c
deleted file mode 100644 (file)
index 8abfc49..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *     Generate devlist.h and classlist.h from the PCI ID file.
- *
- *     (c) 1999--2002 Martin Mares <mj@ucw.cz>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#define MAX_NAME_SIZE 200
-
-static void
-pq(FILE *f, const char *c, int len)
-{
-       int i = 1;
-       while (*c && i != len) {
-               if (*c == '"')
-                       fprintf(f, "\\\"");
-               else {
-                       fputc(*c, f);
-                       if (*c == '?' && c[1] == '?') {
-                               /* Avoid trigraphs */
-                               fprintf(f, "\" \"");
-                       }
-               }
-               c++;
-               i++;
-       }
-}
-
-int
-main(void)
-{
-       char line[1024], *c, *bra, vend[8];
-       int vendors = 0;
-       int mode = 0;
-       int lino = 0;
-       int vendor_len = 0;
-       FILE *devf, *clsf;
-
-       devf = fopen("devlist.h", "w");
-       clsf = fopen("classlist.h", "w");
-       if (!devf || !clsf) {
-               fprintf(stderr, "Cannot create output file!\n");
-               return 1;
-       }
-
-       while (fgets(line, sizeof(line)-1, stdin)) {
-               lino++;
-               if ((c = strchr(line, '\n')))
-                       *c = 0;
-               if (!line[0] || line[0] == '#')
-                       continue;
-               if (line[1] == ' ') {
-                       if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') {
-                               vend[0] = line[2];
-                               vend[1] = line[3];
-                               vend[2] = 0;
-                               mode = 2;
-                       } else goto err;
-               }
-               else if (line[0] == '\t') {
-                       if (line[1] == '\t')
-                               continue;
-                       switch (mode) {
-                       case 1:
-                               if (strlen(line) > 5 && line[5] == ' ') {
-                                       c = line + 5;
-                                       while (*c == ' ')
-                                               *c++ = 0;
-                                       if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
-                                               /* Too long, try cutting off long description */
-                                               bra = strchr(c, '[');
-                                               if (bra && bra > c && bra[-1] == ' ')
-                                                       bra[-1] = 0;
-                                               if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
-                                                       fprintf(stderr, "Line %d: Device name too long. Name truncated.\n", lino);
-                                                       fprintf(stderr, "%s\n", c);
-                                                       /*return 1;*/
-                                               }
-                                       }
-                                       fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1);
-                                       pq(devf, c, MAX_NAME_SIZE - vendor_len - 1);
-                                       fputs("\")\n", devf);
-                               } else goto err;
-                               break;
-                       case 2:
-                               if (strlen(line) > 3 && line[3] == ' ') {
-                                       c = line + 3;
-                                       while (*c == ' ')
-                                               *c++ = 0;
-                                       fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c);
-                               } else goto err;
-                               break;
-                       default:
-                               goto err;
-                       }
-               } else if (strlen(line) > 4 && line[4] == ' ') {
-                       c = line + 4;
-                       while (*c == ' ')
-                               *c++ = 0;
-                       if (vendors)
-                               fputs("ENDVENDOR()\n\n", devf);
-                       vendors++;
-                       strcpy(vend, line);
-                       vendor_len = strlen(c);
-                       if (vendor_len + 24 > MAX_NAME_SIZE) {
-                               fprintf(stderr, "Line %d: Vendor name too long\n", lino);
-                               return 1;
-                       }
-                       fprintf(devf, "VENDOR(%s,\"", vend);
-                       pq(devf, c, 0);
-                       fputs("\")\n", devf);
-                       mode = 1;
-               } else {
-               err:
-                       fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line);
-                       return 1;
-               }
-       }
-       fputs("ENDVENDOR()\n\
-\n\
-#undef VENDOR\n\
-#undef DEVICE\n\
-#undef ENDVENDOR\n", devf);
-       fputs("\n#undef CLASS\n", clsf);
-
-       fclose(devf);
-       fclose(clsf);
-
-       return 0;
-}
index 246586a3d91a1bf5d9343ecae8ebbf749f3fcda2..3c71e3077ff1dd9b5cbbc1f5b0c18df022a84451 100644 (file)
@@ -41,8 +41,7 @@ acpiphp-objs          :=      acpiphp_core.o  \
 
 rpaphp-objs            :=      rpaphp_core.o   \
                                rpaphp_pci.o    \
-                               rpaphp_slot.o   \
-                               rpaphp_vio.o
+                               rpaphp_slot.o
 
 rpadlpar_io-objs       :=      rpadlpar_core.o \
                                rpadlpar_sysfs.o
index 2b92b9e8c910a34ddf9e118e292c583ec84b2b37..061ead21ef1467bab23c390ec1604b2d3a78ccf5 100644 (file)
@@ -302,7 +302,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
 
 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
 {
-       snprintf(buffer, buffer_size, "%d", slot->number);
+       snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
 }
 
 enum php_ctlr_type {
index 86b384e427178e91a59911df426f60342343f808..4ada15111af0849fafd69769d31d189942ab43c1 100644 (file)
 #include <asm/pci-bridge.h>
 #include <asm/semaphore.h>
 #include <asm/rtas.h>
+#include <asm/vio.h>
 #include "../pci.h"
 #include "rpaphp.h"
 #include "rpadlpar.h"
 
 static DECLARE_MUTEX(rpadlpar_sem);
 
+#define DLPAR_MODULE_NAME "rpadlpar_io"
+
 #define NODE_TYPE_VIO  1
 #define NODE_TYPE_SLOT 2
 #define NODE_TYPE_PHB  3
 
-static struct device_node *find_php_slot_vio_node(char *drc_name)
+static struct device_node *find_vio_slot_node(char *drc_name)
 {
-       struct device_node *child;
        struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
-       char *loc_code;
+       struct device_node *dn = NULL;
+       char *name;
+       int rc;
 
        if (!parent)
                return NULL;
 
-       for (child = of_get_next_child(parent, NULL);
-               child; child = of_get_next_child(parent, child)) {
-               loc_code = get_property(child, "ibm,loc-code", NULL);
-               if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
-                       return child;
+       while ((dn = of_get_next_child(parent, dn))) {
+               rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
+               if ((rc == 0) && (!strcmp(drc_name, name)))
+                       break;
        }
 
-       return NULL;
+       return dn;
 }
 
 /* Find dlpar-capable pci node that contains the specified name and type */
@@ -67,7 +70,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name,
        return np;
 }
 
-static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
+static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
 {
        struct device_node *dn;
 
@@ -83,7 +86,7 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
                return dn;
        }
 
-       dn = find_php_slot_vio_node(drc_name);
+       dn = find_vio_slot_node(drc_name);
        if (dn) {
                *node_type = NODE_TYPE_VIO;
                return dn;
@@ -92,14 +95,14 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
        return NULL;
 }
 
-static struct slot *find_slot(char *drc_name)
+static struct slot *find_slot(struct device_node *dn)
 {
        struct list_head *tmp, *n;
        struct slot *slot;
 
         list_for_each_safe(tmp, n, &rpaphp_slot_head) {
                 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
-                if (strcmp(slot->location, drc_name) == 0)
+                if (slot->dn == dn)
                         return slot;
         }
 
@@ -164,6 +167,20 @@ static int pci_add_secondary_bus(struct device_node *dn,
        return 0;
 }
 
+static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
+                                       struct device_node *dev_dn)
+{
+       struct pci_dev *tmp = NULL;
+       struct device_node *child_dn;
+
+       list_for_each_entry(tmp, &parent->devices, bus_list) {
+               child_dn = pci_device_to_OF_node(tmp);
+               if (child_dn == dev_dn)
+                       return tmp;
+       }
+       return NULL;
+}
+
 static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
 {
        struct pci_controller *hose = dn->phb;
@@ -179,49 +196,28 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
        pci_bus_add_devices(hose->bus);
 
        /* Confirm new bridge dev was created */
-       dev = rpaphp_find_pci_dev(dn);
-       if (!dev) {
-               printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__);
-               return NULL;
-       }
+       dev = dlpar_find_new_dev(hose->bus, dn);
+       if (dev) {
+               if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+                       printk(KERN_ERR "%s: unexpected header type %d\n",
+                               __FUNCTION__, dev->hdr_type);
+                       return NULL;
+               }
 
-       if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-               printk(KERN_ERR "%s: unexpected header type %d\n",
-                       __FUNCTION__, dev->hdr_type);
-               return NULL;
+               if (pci_add_secondary_bus(dn, dev))
+                       return NULL;
        }
 
-       if (pci_add_secondary_bus(dn, dev))
-               return NULL;
-
        return dev;
 }
 
-static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev)
+static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
 {
-       struct pci_bus *secondary_bus;
+       struct pci_dev *dev;
+       int rc;
 
-       if (!bridge_dev) {
-               printk(KERN_ERR "%s: unexpected null device\n",
-                       __FUNCTION__);
+       if (rpaphp_find_pci_bus(dn))
                return -EINVAL;
-       }
-
-       secondary_bus = bridge_dev->subordinate;
-
-       if (unmap_bus_range(secondary_bus)) {
-               printk(KERN_ERR "%s: failed to unmap bus range\n",
-                       __FUNCTION__);
-               return -ERANGE;
-       }
-
-       pci_remove_bus_device(bridge_dev);
-       return 0;
-}
-
-static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
-{
-       struct pci_dev *dev;
 
        /* Add pci bus */
        dev = dlpar_pci_add_bus(dn);
@@ -231,6 +227,21 @@ static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
                return -EIO;
        }
 
+       if (dn->child) {
+               rc = rpaphp_config_pci_adapter(dev->subordinate);
+               if (rc < 0) {
+                       printk(KERN_ERR "%s: unable to enable slot %s\n",
+                               __FUNCTION__, drc_name);
+                       return -EIO;
+               }
+       }
+
+       /* Add hotplug slot */
+       if (rpaphp_add_slot(dn)) {
+               printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
+                       __FUNCTION__, drc_name);
+               return -EIO;
+       }
        return 0;
 }
 
@@ -255,47 +266,67 @@ static int dlpar_remove_root_bus(struct pci_controller *phb)
        return 0;
 }
 
-static int dlpar_remove_phb(struct slot *slot)
+static int dlpar_remove_phb(char *drc_name, struct device_node *dn)
 {
-       struct pci_controller *phb;
-       struct device_node *dn;
+       struct slot *slot;
        int rc = 0;
 
-       dn = slot->dn;
-       if (!dn) {
-               printk(KERN_ERR "%s: unexpected NULL slot device node\n",
-                               __FUNCTION__);
-               return -EIO;
-       }
-
-       phb = dn->phb;
-       if (!phb) {
-               printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
-                               __FUNCTION__);
-               return -EIO;
-       }
+       if (!rpaphp_find_pci_bus(dn))
+               return -EINVAL;
 
-       if (rpaphp_remove_slot(slot)) {
-               printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
-                       __FUNCTION__, slot->location);
-               return -EIO;
+       slot = find_slot(dn);
+       if (slot) {
+               /* Remove hotplug slot */
+               if (rpaphp_remove_slot(slot)) {
+                       printk(KERN_ERR
+                               "%s: unable to remove hotplug slot %s\n",
+                               __FUNCTION__, drc_name);
+                       return -EIO;
+               }
        }
 
-       rc = dlpar_remove_root_bus(phb);
+       BUG_ON(!dn->phb);
+       rc = dlpar_remove_root_bus(dn->phb);
        if (rc < 0)
                return rc;
 
+       dn->phb = NULL;
+
        return 0;
 }
 
-static int dlpar_add_phb(struct device_node *dn)
+static int dlpar_add_phb(char *drc_name, struct device_node *dn)
 {
        struct pci_controller *phb;
 
+       if (dn->phb) {
+               /* PHB already exists */
+               return -EINVAL;
+       }
+
        phb = init_phb_dynamic(dn);
        if (!phb)
+               return -EIO;
+
+       if (rpaphp_add_slot(dn)) {
+               printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
+                       __FUNCTION__, drc_name);
+               return -EIO;
+       }
+       return 0;
+}
+
+static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
+{
+       if (vio_find_node(dn))
                return -EINVAL;
 
+       if (!vio_register_device_node(dn)) {
+               printk(KERN_ERR
+                       "%s: failed to register vio node %s\n",
+                       __FUNCTION__, drc_name);
+               return -EIO;
+       }
        return 0;
 }
 
@@ -316,18 +347,13 @@ int dlpar_add_slot(char *drc_name)
 {
        struct device_node *dn = NULL;
        int node_type;
-       int rc = 0;
+       int rc = -EIO;
 
        if (down_interruptible(&rpadlpar_sem))
                return -ERESTARTSYS;
 
-       /* Check for existing hotplug slot */
-       if (find_slot(drc_name)) {
-               rc = -EINVAL;
-               goto exit;
-       }
-
-       dn = find_newly_added_node(drc_name, &node_type);
+       /* Find newly added node */
+       dn = find_dlpar_node(drc_name, &node_type);
        if (!dn) {
                rc = -ENODEV;
                goto exit;
@@ -335,24 +361,17 @@ int dlpar_add_slot(char *drc_name)
 
        switch (node_type) {
                case NODE_TYPE_VIO:
-                       /* Just add hotplug slot */
+                       rc = dlpar_add_vio_slot(drc_name, dn);
                        break;
                case NODE_TYPE_SLOT:
                        rc = dlpar_add_pci_slot(drc_name, dn);
                        break;
                case NODE_TYPE_PHB:
-                       rc = dlpar_add_phb(dn);
+                       rc = dlpar_add_phb(drc_name, dn);
                        break;
-               default:
-                       printk("%s: unexpected node type\n", __FUNCTION__);
-                       return -EIO;
        }
 
-       if (!rc && rpaphp_add_slot(dn)) {
-               printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
-                       __FUNCTION__, drc_name);
-               rc = -EIO;
-       }
+       printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name);
 exit:
        up(&rpadlpar_sem);
        return rc;
@@ -366,17 +385,17 @@ exit:
  * of an I/O Slot.
  * Return Codes:
  * 0                   Success
- * -EIO                        Internal  Error
+ * -EINVAL             Vio dev doesn't exist
  */
-int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
+static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
 {
-       /* Remove hotplug slot */
+       struct vio_dev *vio_dev;
 
-       if (rpaphp_remove_slot(slot)) {
-               printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
-                       __FUNCTION__, drc_name);
-               return -EIO;
-       }
+       vio_dev = vio_find_node(dn);
+       if (!vio_dev)
+               return -EINVAL;
+
+       vio_unregister_device(vio_dev);
        return 0;
 }
 
@@ -391,31 +410,34 @@ int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
  * -ENODEV             Not a valid drc_name
  * -EIO                        Internal PCI Error
  */
-int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
+int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
 {
-       struct pci_dev *bridge_dev;
+       struct pci_bus *bus;
+       struct slot *slot;
 
-       bridge_dev = slot->bridge;
-       if (!bridge_dev) {
-               printk(KERN_ERR "%s: unexpected null bridge device\n",
-                       __FUNCTION__);
-               return -EIO;
-       }
+       bus = rpaphp_find_pci_bus(dn);
+       if (!bus)
+               return -EINVAL;
 
-       /* Remove hotplug slot */
-       if (rpaphp_remove_slot(slot)) {
-               printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
-                       __FUNCTION__, drc_name);
-               return -EIO;
+       slot = find_slot(dn);
+       if (slot) {
+               /* Remove hotplug slot */
+               if (rpaphp_remove_slot(slot)) {
+                       printk(KERN_ERR
+                               "%s: unable to remove hotplug slot %s\n",
+                               __FUNCTION__, drc_name);
+                       return -EIO;
+               }
        }
 
-       /* Remove pci bus */
-
-       if (dlpar_pci_remove_bus(bridge_dev)) {
-               printk(KERN_ERR "%s: unable to remove pci bus %s\n",
-                       __FUNCTION__, drc_name);
-               return -EIO;
+       if (unmap_bus_range(bus)) {
+               printk(KERN_ERR "%s: failed to unmap bus range\n",
+                       __FUNCTION__);
+               return -ERANGE;
        }
+
+       BUG_ON(!bus->self);
+       pci_remove_bus_device(bus->self);
        return 0;
 }
 
@@ -434,38 +456,31 @@ int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
  */
 int dlpar_remove_slot(char *drc_name)
 {
-       struct slot *slot;
+       struct device_node *dn;
+       int node_type;
        int rc = 0;
 
        if (down_interruptible(&rpadlpar_sem))
                return -ERESTARTSYS;
 
-       if (!find_php_slot_vio_node(drc_name) &&
-           !find_php_slot_pci_node(drc_name, "SLOT") &&
-           !find_php_slot_pci_node(drc_name, "PHB")) {
+       dn = find_dlpar_node(drc_name, &node_type);
+       if (!dn) {
                rc = -ENODEV;
                goto exit;
        }
 
-       slot = find_slot(drc_name);
-       if (!slot) {
-               rc = -EINVAL;
-               goto exit;
-       }
-       
-       if (slot->type == PHB) {
-               rc = dlpar_remove_phb(slot);
-       } else {
-               switch (slot->dev_type) {
-                       case PCI_DEV:
-                               rc = dlpar_remove_pci_slot(slot, drc_name);
-                               break;
-
-                       case VIO_DEV:
-                               rc = dlpar_remove_vio_slot(slot, drc_name);
-                               break;
-               }
+       switch (node_type) {
+               case NODE_TYPE_VIO:
+                       rc = dlpar_remove_vio_slot(drc_name, dn);
+                       break;
+               case NODE_TYPE_PHB:
+                       rc = dlpar_remove_phb(drc_name, dn);
+                       break;
+               case NODE_TYPE_SLOT:
+                       rc = dlpar_remove_pci_slot(drc_name, dn);
+                       break;
        }
+       printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
 exit:
        up(&rpadlpar_sem);
        return rc;
index 81746e6e0e0fefdcbe13be108364f123eab10365..61d94d1e29cbaeb063ba437b44180c1066fabe5a 100644 (file)
 #include <linux/pci.h>
 #include "pci_hotplug.h"
 
-#define        PHB     2
-#define        HOTPLUG 1
-#define        EMBEDDED 0
-
 #define DR_INDICATOR 9002
 #define DR_ENTITY_SENSE 9003
 
@@ -61,10 +57,6 @@ extern int debug;
 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
-/* slot types */
-#define VIO_DEV        1
-#define PCI_DEV        2
-
 /* slot states */
 
 #define        NOT_VALID       3
@@ -72,11 +64,6 @@ extern int debug;
 #define        CONFIGURED      1
 #define        EMPTY           0
 
-struct rpaphp_pci_func {
-       struct pci_dev *pci_dev;
-       struct list_head sibling;
-};
-
 /*
  * struct slot - slot information for each *physical* slot
  */
@@ -88,15 +75,9 @@ struct slot {
        u32 power_domain;
        char *name;
        char *location;
-       u8 removable;
-       u8 dev_type;            /* VIO or PCI */
-       struct device_node *dn; /* slot's device_node in OFDT */
-                               /* dn has phb info */
-       struct pci_dev *bridge; /* slot's pci_dev in pci_devices */
-       union {
-               struct list_head *pci_devs; /* pci_devs in PCI slot */
-               struct vio_dev *vio_dev; /* vio_dev in VIO slot */
-       } dev;
+       struct device_node *dn;
+       struct pci_bus *bus;
+       struct list_head *pci_devs;
        struct hotplug_slot *hotplug_slot;
 };
 
@@ -107,13 +88,13 @@ extern int num_slots;
 /* function prototypes */
 
 /* rpaphp_pci.c */
-extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn);
+extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
 extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
 extern int rpaphp_enable_pci_slot(struct slot *slot);
 extern int register_pci_slot(struct slot *slot);
 extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
 extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
-extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev);
+extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
 
 /* rpaphp_core.c */
 extern int rpaphp_add_slot(struct device_node *dn);
@@ -121,12 +102,6 @@ extern int rpaphp_remove_slot(struct slot *slot);
 extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
                char **drc_name, char **drc_type, int *drc_power_domain);
 
-/* rpaphp_vio.c */
-extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
-extern int rpaphp_unconfig_vio_adapter(struct slot *slot);
-extern int register_vio_slot(struct device_node *dn);
-extern int rpaphp_enable_vio_slot(struct slot *slot);
-
 /* rpaphp_slot.c */
 extern void dealloc_slot_struct(struct slot *slot);
 extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
index 29117a3a32874194f72805d4530c2416fbe2eb1e..c830ff0acdc3471202414943dac2b8d2c818d7e6 100644 (file)
@@ -152,17 +152,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
        int retval = 0;
 
        down(&rpaphp_sem);
-       /*  have to go through this */
-       switch (slot->dev_type) {
-       case PCI_DEV:
-               retval = rpaphp_get_pci_adapter_status(slot, 0, value);
-               break;
-       case VIO_DEV:
-               retval = rpaphp_get_vio_adapter_status(slot, 0, value);
-               break;
-       default:
-               retval = -EINVAL;
-       }
+       retval = rpaphp_get_pci_adapter_status(slot, 0, value);
        up(&rpaphp_sem);
        return retval;
 }
@@ -317,34 +307,6 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names,
        return 0;
 }
 
-static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
-               int **types, int **power_domains, int **my_drc_index)
-{
-       int rc;
-
-       *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
-       if(!*my_drc_index)
-               return (0);
-
-       if (!dn->parent)
-               return (0);
-
-       rc = get_children_props(dn->parent, indexes, names, types,
-                               power_domains);
-       return (rc >= 0);
-}
-
-static inline int is_vdevice_root(struct device_node *dn)
-{
-       return !strcmp(dn->name, "vdevice");
-}
-
-int is_dlpar_type(const char *type_str)
-{
-       /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
-       return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
-}
-
 /****************************************************************
  *     rpaphp not only registers PCI hotplug slots(HOTPLUG), 
  *     but also logical DR slots(EMBEDDED).
@@ -356,54 +318,33 @@ int rpaphp_add_slot(struct device_node *dn)
 {
        struct slot *slot;
        int retval = 0;
-       int i, *my_drc_index, slot_type;
+       int i;
        int *indexes, *names, *types, *power_domains;
        char *name, *type;
 
        dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);
 
-       if (dn->parent && is_vdevice_root(dn->parent)) {
-               /* register a VIO device */
-               retval = register_vio_slot(dn);
-               goto exit;
-       }
-
        /* register PCI devices */
        if (dn->name != 0 && strcmp(dn->name, "pci") == 0) {
-               if (is_php_dn(dn, &indexes, &names, &types, &power_domains))  
-                       slot_type = HOTPLUG;
-               else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index)) 
-                       slot_type = EMBEDDED;
-               else goto exit;
+               if (!is_php_dn(dn, &indexes, &names, &types, &power_domains))
+                       goto exit;
 
                name = (char *) &names[1];
                type = (char *) &types[1];
                for (i = 0; i < indexes[0]; i++,
-                       name += (strlen(name) + 1), type += (strlen(type) + 1)) {
-
-                       if (slot_type == HOTPLUG ||
-                           (slot_type == EMBEDDED &&
-                            indexes[i + 1] == my_drc_index[0] &&
-                            is_dlpar_type(type))) {
-                               if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
-                                              power_domains[i + 1]))) {
-                                       retval = -ENOMEM;
-                                       goto exit;
-                               }
-                               if (!strcmp(type, "PHB"))
-                                       slot->type = PHB;
-                               else if (slot_type == EMBEDDED)
-                                       slot->type = EMBEDDED;
-                               else
-                                       slot->type = simple_strtoul(type, NULL, 10);
+                       name += (strlen(name) + 1), type += (strlen(type) + 1))                 {
+
+                       if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
+                                      power_domains[i + 1]))) {
+                               retval = -ENOMEM;
+                               goto exit;
+                       }
+                       slot->type = simple_strtoul(type, NULL, 10);
                                
-                               dbg("    Found drc-index:0x%x drc-name:%s drc-type:%s\n",
+                       dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n",
                                        indexes[i + 1], name, type);
 
-                               retval = register_pci_slot(slot);
-                               if (slot_type == EMBEDDED)
-                                       goto exit;
-                       }
+                       retval = register_pci_slot(slot);
                }
        }
 exit:
@@ -412,31 +353,6 @@ exit:
        return retval;
 }
 
-/*
- * init_slots - initialize 'struct slot' structures for each slot
- *
- */
-static void init_slots(void)
-{
-       struct device_node *dn;
-
-       for (dn = find_all_nodes(); dn; dn = dn->next)
-               rpaphp_add_slot(dn);
-}
-
-static int __init init_rpa(void)
-{
-
-       init_MUTEX(&rpaphp_sem);
-
-       /* initialize internal data structure etc. */
-       init_slots();
-       if (!num_slots)
-               return -ENODEV;
-
-       return 0;
-}
-
 static void __exit cleanup_slots(void)
 {
        struct list_head *tmp, *n;
@@ -458,10 +374,18 @@ static void __exit cleanup_slots(void)
 
 static int __init rpaphp_init(void)
 {
+       struct device_node *dn = NULL;
+
        info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+       init_MUTEX(&rpaphp_sem);
 
-       /* read all the PRA info from the system */
-       return init_rpa();
+       while ((dn = of_find_node_by_type(dn, "pci")))
+               rpaphp_add_slot(dn);
+
+       if (!num_slots)
+               return -ENODEV;
+
+       return 0;
 }
 
 static void __exit rpaphp_exit(void)
@@ -481,16 +405,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
 
        dbg("ENABLING SLOT %s\n", slot->name);
        down(&rpaphp_sem);
-       switch (slot->dev_type) {
-       case PCI_DEV:
-               retval = rpaphp_enable_pci_slot(slot);
-               break;
-       case VIO_DEV:
-               retval = rpaphp_enable_vio_slot(slot);
-               break;
-       default:
-               retval = -EINVAL;
-       }
+       retval = rpaphp_enable_pci_slot(slot);
        up(&rpaphp_sem);
 exit:
        dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
@@ -511,16 +426,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
 
        dbg("DISABLING SLOT %s\n", slot->name);
        down(&rpaphp_sem);
-       switch (slot->dev_type) {
-       case PCI_DEV:
-               retval = rpaphp_unconfig_pci_adapter(slot);
-               break;
-       case VIO_DEV:
-               retval = rpaphp_unconfig_vio_adapter(slot);
-               break;
-       default:
-               retval = -ENODEV;
-       }
+       retval = rpaphp_unconfig_pci_adapter(slot);
        up(&rpaphp_sem);
 exit:
        dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
index d8305a935aab12d2471dd8de7253ba21e19b4136..17a0279ebcb9faf0e3b0c42229d145392aa4cd4c 100644 (file)
 
 #include "rpaphp.h"
 
-struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn)
+static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
+                                       struct device_node *dn)
 {
-       struct pci_dev *dev = NULL;
-       char bus_id[BUS_ID_SIZE];
+       struct pci_bus *child = NULL;
+       struct list_head *tmp;
+       struct device_node *busdn;
+
+       busdn = pci_bus_to_OF_node(bus);
+       if (busdn == dn)
+               return bus;
 
-       sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number,
-               dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn));
-       for_each_pci_dev(dev) {
-               if (!strcmp(pci_name(dev), bus_id)) {
+       list_for_each(tmp, &bus->children) {
+               child = find_bus_among_children(pci_bus_b(tmp), dn);
+               if (child)
                        break;
-               }
        }
-       return dev;
+       return child;
 }
 
-EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev);
+struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn)
+{
+       if (!dn->phb || !dn->phb->bus)
+               return NULL;
+
+       return find_bus_among_children(dn->phb->bus, dn);
+}
+EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
 
 int rpaphp_claim_resource(struct pci_dev *dev, int resource)
 {
@@ -69,11 +80,6 @@ int rpaphp_claim_resource(struct pci_dev *dev, int resource)
 
 EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
 
-static struct pci_dev *rpaphp_find_bridge_pdev(struct slot *slot)
-{
-       return rpaphp_find_pci_dev(slot->dn);
-}
-
 static int rpaphp_get_sensor_state(struct slot *slot, int *state)
 {
        int rc;
@@ -116,39 +122,27 @@ static int rpaphp_get_sensor_state(struct slot *slot, int *state)
  */
 int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
 {
+       struct pci_bus *bus;
        int state, rc;
-       struct device_node *child_dn;
-       struct pci_dev *child_dev = NULL;
 
        *value = NOT_VALID;
        rc = rpaphp_get_sensor_state(slot, &state);
        if (rc)
                goto exit;
 
-       if ((state == EMPTY) || (slot->type == PHB)) {
-               dbg("slot is empty\n");
+       if (state == EMPTY)
                *value = EMPTY;
-       }
        else if (state == PRESENT) {
                if (!is_init) {
                        /* at run-time slot->state can be changed by */
                        /* config/unconfig adapter */
                        *value = slot->state;
                } else {
-                       child_dn = slot->dn->child;
-                       if (child_dn)
-                               child_dev = rpaphp_find_pci_dev(child_dn);
-
-                       if (child_dev)
-                               *value = CONFIGURED;
-                       else if (!child_dn)
-                               dbg("%s: %s is not valid OFDT node\n",
-                                   __FUNCTION__, slot->dn->full_name);
-                       else {
-                               err("%s: can't find pdev of adapter in slot[%s]\n", 
-                                       __FUNCTION__, slot->dn->full_name);
+                       bus = rpaphp_find_pci_bus(slot->dn);
+                       if (bus && !list_empty(&bus->devices))
+                               *value = CONFIGURED;
+                       else
                                *value = NOT_CONFIGURED;
-                       }
                }
        }
 exit:
@@ -186,39 +180,6 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
        }
 }
 
-static int rpaphp_pci_config_bridge(struct pci_dev *dev);
-
-/*****************************************************************************
- rpaphp_pci_config_slot() will  configure all devices under the 
- given slot->dn and return the the first pci_dev.
- *****************************************************************************/
-static struct pci_dev *
-rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus)
-{
-       struct device_node *eads_first_child = dn->child;
-       struct pci_dev *dev = NULL;
-       int num;
-       
-       dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
-
-       if (eads_first_child) {
-               /* pci_scan_slot should find all children of EADs */
-               num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0));
-               if (num) {
-                       rpaphp_fixup_new_pci_devices(bus, 1); 
-                       pci_bus_add_devices(bus);
-               }
-               dev = rpaphp_find_pci_dev(eads_first_child);
-               if (!dev) {
-                       err("No new device found\n");
-                       return NULL;
-               }
-               if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 
-                       rpaphp_pci_config_bridge(dev);
-       }
-       return dev;
-}
-
 static int rpaphp_pci_config_bridge(struct pci_dev *dev)
 {
        u8 sec_busno;
@@ -252,6 +213,42 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
        return 0;
 }
 
+/*****************************************************************************
+ rpaphp_pci_config_slot() will  configure all devices under the
+ given slot->dn and return the the first pci_dev.
+ *****************************************************************************/
+static struct pci_dev *
+rpaphp_pci_config_slot(struct pci_bus *bus)
+{
+       struct device_node *dn = pci_bus_to_OF_node(bus);
+       struct pci_dev *dev = NULL;
+       int slotno;
+       int num;
+
+       dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
+       if (!dn || !dn->child)
+               return NULL;
+
+       slotno = PCI_SLOT(dn->child->devfn);
+
+       /* pci_scan_slot should find all children */
+       num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+       if (num) {
+               rpaphp_fixup_new_pci_devices(bus, 1);
+               pci_bus_add_devices(bus);
+       }
+       if (list_empty(&bus->devices)) {
+               err("%s: No new device found\n", __FUNCTION__);
+               return NULL;
+       }
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+                       rpaphp_pci_config_bridge(dev);
+       }
+
+       return dev;
+}
+
 static void enable_eeh(struct device_node *dn)
 {
        struct device_node *sib;
@@ -263,49 +260,44 @@ static void enable_eeh(struct device_node *dn)
        
 }
 
-static void print_slot_pci_funcs(struct slot *slot)
+static void print_slot_pci_funcs(struct pci_bus *bus)
 {
+       struct device_node *dn;
        struct pci_dev *dev;
 
-       if (slot->dev_type == PCI_DEV) {
-               dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->name);
-               list_for_each_entry (dev, slot->dev.pci_devs, bus_list)
-                       dbg("\t%s\n", pci_name(dev));
-       }
+       dn = pci_bus_to_OF_node(bus);
+       if (!dn)
+               return;
+
+       dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name);
+       list_for_each_entry (dev, &bus->devices, bus_list)
+               dbg("\t%s\n", pci_name(dev));
        return;
 }
 
-static int rpaphp_config_pci_adapter(struct slot *slot)
+int rpaphp_config_pci_adapter(struct pci_bus *bus)
 {
-       struct pci_bus *pci_bus;
+       struct device_node *dn = pci_bus_to_OF_node(bus);
        struct pci_dev *dev;
        int rc = -ENODEV;
 
-       dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
-
-       if (slot->bridge) {
+       dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name);
+       if (!dn)
+               goto exit;
 
-               pci_bus = slot->bridge->subordinate;
-               if (!pci_bus) {
-                       err("%s: can't find bus structure\n", __FUNCTION__);
-                       goto exit;
-               }
-               enable_eeh(slot->dn);
-               dev = rpaphp_pci_config_slot(slot->dn, pci_bus);
-               if (!dev) {
-                       err("%s: can't find any devices.\n", __FUNCTION__);
-                       goto exit;
-               }
-               print_slot_pci_funcs(slot);
-               rc = 0;
-       } else {
-               /* slot is not enabled */
-               err("slot doesn't have pci_dev structure\n");
+       enable_eeh(dn);
+       dev = rpaphp_pci_config_slot(bus);
+       if (!dev) {
+               err("%s: can't find any devices.\n", __FUNCTION__);
+               goto exit;
        }
+       print_slot_pci_funcs(bus);
+       rc = 0;
 exit:
        dbg("Exit %s:  rc=%d\n", __FUNCTION__, rc);
        return rc;
 }
+EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter);
 
 static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
 {
@@ -327,13 +319,14 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
 
 int rpaphp_unconfig_pci_adapter(struct slot *slot)
 {
-       struct pci_dev *dev;
+       struct pci_dev *dev, *tmp;
        int retval = 0;
 
-       list_for_each_entry(dev, slot->dev.pci_devs, bus_list)
+       list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) {
                rpaphp_eeh_remove_bus_device(dev);
+               pci_remove_bus_device(dev);
+       }
 
-       pci_remove_behind_bridge(slot->bridge);
        slot->state = NOT_CONFIGURED;
        info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
             slot->name);
@@ -356,66 +349,41 @@ static int setup_pci_hotplug_slot_info(struct slot *slot)
        return 0;
 }
 
-static int set_phb_slot_name(struct slot *slot)
+static void set_slot_name(struct slot *slot)
 {
-       struct device_node *dn;
-       struct pci_controller *phb;
-       struct pci_bus *bus;
-
-       dn = slot->dn;
-       if (!dn) {
-               return -EINVAL;
-       }
-       phb = dn->phb;
-       if (!phb) {
-               return -EINVAL;
-       }
-       bus = phb->bus;
-       if (!bus) {
-               return -EINVAL;
-       }
+       struct pci_bus *bus = slot->bus;
+       struct pci_dev *bridge;
 
-       sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus),
-                       bus->number, 0, 0);
-       return 0;
+       bridge = bus->self;
+       if (bridge)
+               strcpy(slot->name, pci_name(bridge));
+       else
+               sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
+                       bus->number);
 }
 
 static int setup_pci_slot(struct slot *slot)
 {
+       struct device_node *dn = slot->dn;
        struct pci_bus *bus;
-       int rc;
 
-       if (slot->type == PHB) {
-               rc = set_phb_slot_name(slot);
-               if (rc < 0) {
-                       err("%s: failed to set phb slot name\n", __FUNCTION__);
-                       goto exit_rc;
-               }
-       } else {
-               slot->bridge = rpaphp_find_bridge_pdev(slot);
-               if (!slot->bridge) {
-                       /* slot being added doesn't have pci_dev yet */
-                       err("%s: no pci_dev for bridge dn %s\n",
-                                       __FUNCTION__, slot->name);
-                       goto exit_rc;
-               }
-
-               bus = slot->bridge->subordinate;
-               if (!bus)
-                       goto exit_rc;
-               slot->dev.pci_devs = &bus->devices;
-
-               dbg("%s set slot->name to %s\n",  __FUNCTION__,
-                               pci_name(slot->bridge));
-               strcpy(slot->name, pci_name(slot->bridge));
+       BUG_ON(!dn);
+       bus = rpaphp_find_pci_bus(dn);
+       if (!bus) {
+               err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name);
+               goto exit_rc;
        }
 
+       slot->bus = bus;
+       slot->pci_devs = &bus->devices;
+       set_slot_name(slot);
+
        /* find slot's pci_dev if it's not empty */
        if (slot->hotplug_slot->info->adapter_status == EMPTY) {
                slot->state = EMPTY;    /* slot is empty */
        } else {
                /* slot is occupied */
-               if (!(slot->dn->child)) {
+               if (!dn->child) {
                        /* non-empty slot has to have child */
                        err("%s: slot[%s]'s device_node doesn't have child for adapter\n", 
                                __FUNCTION__, slot->name);
@@ -425,7 +393,7 @@ static int setup_pci_slot(struct slot *slot)
                if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
                        dbg("%s CONFIGURING pci adapter in slot[%s]\n",  
                                __FUNCTION__, slot->name);
-                       if (rpaphp_config_pci_adapter(slot)) {
+                       if (rpaphp_config_pci_adapter(slot->bus)) {
                                err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
                                goto exit_rc;           
                        }
@@ -435,8 +403,8 @@ static int setup_pci_slot(struct slot *slot)
                                __FUNCTION__, slot->name);
                        goto exit_rc;
                }
-               print_slot_pci_funcs(slot);
-               if (!list_empty(slot->dev.pci_devs)) {
+               print_slot_pci_funcs(slot->bus);
+               if (!list_empty(slot->pci_devs)) {
                        slot->state = CONFIGURED;
                } else {
                        /* DLPAR add as opposed to 
@@ -454,11 +422,6 @@ int register_pci_slot(struct slot *slot)
 {
        int rc = -EINVAL;
 
-       slot->dev_type = PCI_DEV;
-       if ((slot->type == EMBEDDED) || (slot->type == PHB))
-               slot->removable = 0;
-       else
-               slot->removable = 1;
        if (setup_pci_hotplug_slot_info(slot))
                goto exit_rc;
        if (setup_pci_slot(slot))
@@ -479,7 +442,7 @@ int rpaphp_enable_pci_slot(struct slot *slot)
        /* if slot is not empty, enable the adapter */
        if (state == PRESENT) {
                dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
-               retval = rpaphp_config_pci_adapter(slot);
+               retval = rpaphp_config_pci_adapter(slot->bus);
                if (!retval) {
                        slot->state = CONFIGURED;
                        dbg("%s: PCI devices in slot[%s] has been configured\n", 
@@ -502,37 +465,3 @@ exit:
        dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
        return retval;
 }
-
-struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev)
-{
-       struct list_head        *tmp, *n;
-       struct slot             *slot;
-
-       list_for_each_safe(tmp, n, &rpaphp_slot_head) {
-               struct pci_bus *bus;
-               struct list_head *ln;
-
-               slot = list_entry(tmp, struct slot, rpaphp_slot_list);
-               if (slot->bridge == NULL) {
-                       if (slot->dev_type == PCI_DEV) {
-                               printk(KERN_WARNING "PCI slot missing bridge %s %s \n", 
-                                                   slot->name, slot->location);
-                       }
-                       continue;
-               }
-
-               bus = slot->bridge->subordinate;
-               if (!bus) {
-                       continue;  /* should never happen? */
-               }
-               for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-                                struct pci_dev *pdev = pci_dev_b(ln);
-                               if (pdev == dev)
-                                       return slot->hotplug_slot;
-               }
-       }
-
-       return NULL;
-}
-
-EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot);
index ff2cbf0652d83879509fa45ed59d1d1c7f4c60b4..0e88154950838fa770e5cd21d172102b7272993f 100644 (file)
 #include <asm/rtas.h>
 #include "rpaphp.h"
 
-static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf)
-{
-       u8 value;
-       int retval = -ENOENT;
-       struct slot *slot = (struct slot *)php_slot->private;
-
-       if (!slot)
-               return retval;
-
-       value = slot->removable;
-       retval = sprintf (buf, "%d\n", value);
-       return retval;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_removable = {
-       .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO},
-       .show = removable_read_file,
-};
-
-static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot)
-{
-       sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
-}
-
-static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot)
-{
-       sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
-}
-
 static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
 {
         char *value;
@@ -176,9 +147,6 @@ int deregister_slot(struct slot *slot)
        /* remove "phy_location" file */
        rpaphp_sysfs_remove_attr_location(php_slot);
 
-       /* remove "phy_removable" file */
-       rpaphp_sysfs_remove_attr_removable(php_slot);
-
        retval = pci_hp_deregister(php_slot);
        if (retval)
                err("Problem unregistering a slot %s\n", slot->name);
@@ -212,21 +180,13 @@ int register_slot(struct slot *slot)
        /* create "phy_locatoin" file */
        rpaphp_sysfs_add_attr_location(slot->hotplug_slot);     
 
-       /* create "phy_removable" file */
-       rpaphp_sysfs_add_attr_removable(slot->hotplug_slot);    
-
        /* add slot to our internal list */
        dbg("%s adding slot[%s] to rpaphp_slot_list\n",
            __FUNCTION__, slot->name);
 
        list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
-
-       if (slot->dev_type == VIO_DEV)
-               info("Slot [%s](VIO location=%s) registered\n",
-                    slot->name, slot->location);
-       else
-               info("Slot [%s](PCI location=%s) registered\n",
-                    slot->name, slot->location);
+       info("Slot [%s](PCI location=%s) registered\n", slot->name,
+                       slot->location);
        num_slots++;
        return 0;
 }
@@ -235,21 +195,17 @@ int rpaphp_get_power_status(struct slot *slot, u8 * value)
 {
        int rc = 0, level;
        
-       if (slot->type == HOTPLUG) {
-               rc = rtas_get_power_level(slot->power_domain, &level);
-               if (!rc) {
-                       dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
-                               __FUNCTION__, slot->name, slot->power_domain, level);
-                       *value = level;
-               } else
-                       err("failed to get power-level for slot(%s), rc=0x%x\n",
-                               slot->location, rc);
-       } else {
-               dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
-                       __FUNCTION__, slot->location);
-               *value = (u8) POWER_ON;
+       rc = rtas_get_power_level(slot->power_domain, &level);
+       if (rc < 0) {
+               err("failed to get power-level for slot(%s), rc=0x%x\n",
+                       slot->location, rc);
+               return rc;
        }
 
+       dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
+               __FUNCTION__, slot->name, slot->power_domain, level);
+       *value = level;
+
        return rc;
 }
 
diff --git a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
deleted file mode 100644 (file)
index 74df6a3..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * RPA Hot Plug Virtual I/O device functions 
- * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
- *
- * All rights reserved.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <lxie@us.ibm.com>
- *
- */
-#include <asm/vio.h>
-#include "rpaphp.h"
-
-/*
- * get_vio_adapter_status - get  the status of a slot
- * 
- * status:
- * 
- * 1-- adapter is configured
- * 2-- adapter is not configured
- * 3-- not valid
- */
-inline int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 *value)
-{
-       *value = slot->state;
-       return 0;
-}
-
-int rpaphp_unconfig_vio_adapter(struct slot *slot)
-{
-       int retval = 0;
-
-       dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
-       if (!slot->dev.vio_dev) {
-               info("%s: no VIOA in slot[%s]\n", __FUNCTION__, slot->name);
-               retval = -EINVAL;
-               goto exit;
-       }
-       /* remove the device from the vio core */
-       vio_unregister_device(slot->dev.vio_dev);
-       slot->state = NOT_CONFIGURED;
-       info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, slot->name);
-exit:
-       dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval);
-       return retval;
-}
-
-static int setup_vio_hotplug_slot_info(struct slot *slot)
-{
-       slot->hotplug_slot->info->power_status = 1;
-       rpaphp_get_vio_adapter_status(slot, 1,
-               &slot->hotplug_slot->info->adapter_status); 
-       return 0;
-}
-
-int register_vio_slot(struct device_node *dn)
-{
-       u32 *index;
-       char *name;
-       int rc = -EINVAL;
-       struct slot *slot = NULL;
-       
-       rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
-       if (rc < 0)
-               goto exit_rc;
-       index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
-       if (!index)
-               goto exit_rc;
-       if (!(slot = alloc_slot_struct(dn, *index, name, 0))) {
-               rc = -ENOMEM;
-               goto exit_rc;
-       }
-       slot->dev_type = VIO_DEV;
-       slot->dev.vio_dev = vio_find_node(dn);
-       if (slot->dev.vio_dev) {
-               /*
-                * rpaphp is the only owner of vio devices and
-                * does not need extra reference taken by
-                * vio_find_node
-                */
-               put_device(&slot->dev.vio_dev->dev);
-       } else
-               slot->dev.vio_dev = vio_register_device_node(dn);
-       if (slot->dev.vio_dev)
-               slot->state = CONFIGURED;
-       else
-               slot->state = NOT_CONFIGURED;
-       if (setup_vio_hotplug_slot_info(slot))
-               goto exit_rc;
-       strcpy(slot->name, slot->dev.vio_dev->dev.bus_id);
-       info("%s: registered VIO device[name=%s vio_dev=%p]\n",
-               __FUNCTION__, slot->name, slot->dev.vio_dev); 
-       rc = register_slot(slot);
-exit_rc:
-       if (rc && slot)
-               dealloc_slot_struct(slot);
-       return (rc);
-}
-
-int rpaphp_enable_vio_slot(struct slot *slot)
-{
-       int retval = 0;
-
-       if ((slot->dev.vio_dev = vio_register_device_node(slot->dn))) {
-               info("%s: VIO adapter %s in slot[%s] has been configured\n",
-                       __FUNCTION__, slot->dn->name, slot->name);
-               slot->state = CONFIGURED;
-       } else {
-               info("%s: no vio_dev struct for adapter in slot[%s]\n",
-                       __FUNCTION__, slot->name);
-               slot->state = NOT_CONFIGURED;
-       }
-       
-       return retval;
-}
index 323041fd41dc19c20ce88e4ae370272cbe09ea97..b1409441c1cde52a605e6daf4e6d40ec173e5e52 100644 (file)
@@ -32,14 +32,15 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
 MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
 
-#define PCIIO_ASIC_TYPE_TIOCA     4
-#define PCI_SLOT_ALREADY_UP       2     /* slot already up */
-#define PCI_SLOT_ALREADY_DOWN     3     /* slot already down */
-#define PCI_L1_ERR                7     /* L1 console command error */
-#define PCI_EMPTY_33MHZ          15     /* empty 33 MHz bus */
-#define PCI_L1_QSIZE            128     /* our L1 message buffer size */
-#define SN_MAX_HP_SLOTS                 32     /* max number of hotplug slots */
-#define SGI_HOTPLUG_PROM_REV   0x0420  /* Min. required PROM version */
+#define PCIIO_ASIC_TYPE_TIOCA          4
+#define PCI_SLOT_ALREADY_UP            2       /* slot already up */
+#define PCI_SLOT_ALREADY_DOWN          3       /* slot already down */
+#define PCI_L1_ERR                     7       /* L1 console command error */
+#define PCI_EMPTY_33MHZ                        15      /* empty 33 MHz bus */
+#define PCI_L1_QSIZE                   128     /* our L1 message buffer size */
+#define SN_MAX_HP_SLOTS                        32      /* max hotplug slots */
+#define SGI_HOTPLUG_PROM_REV           0x0430  /* Min. required PROM version */
+#define SN_SLOT_NAME_SIZE              33      /* size of name string */
 
 /* internal list head */
 static struct list_head sn_hp_list;
@@ -51,6 +52,7 @@ struct slot {
        /* this struct for glue internal only */
        struct hotplug_slot *hotplug_slot;
        struct list_head hp_list;
+       char physical_path[SN_SLOT_NAME_SIZE];
 };
 
 struct pcibr_slot_enable_resp {
@@ -70,7 +72,7 @@ enum sn_pci_req_e {
 
 static int enable_slot(struct hotplug_slot *slot);
 static int disable_slot(struct hotplug_slot *slot);
-static int get_power_status(struct hotplug_slot *slot, u8 *value);
+static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
 
 static struct hotplug_slot_ops sn_hotplug_slot_ops = {
        .owner                  = THIS_MODULE,
@@ -81,6 +83,21 @@ static struct hotplug_slot_ops sn_hotplug_slot_ops = {
 
 static DECLARE_MUTEX(sn_hotplug_sem);
 
+static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot,
+                         char *buf)
+{
+       int retval = -ENOENT;
+       struct slot *slot = bss_hotplug_slot->private;
+
+       if (!slot)
+               return retval;
+
+       retval = sprintf (buf, "%s\n", slot->physical_path);
+       return retval;
+}
+
+static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
+
 static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
 {
        struct pcibus_info *pcibus_info;
@@ -120,15 +137,15 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
        /* Only register slots in I/O Bricks that support hotplug */
        bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
        switch (bricktype) {
-       case L1_BRICKTYPE_IX:
-       case L1_BRICKTYPE_PX:
-       case L1_BRICKTYPE_IA:
-       case L1_BRICKTYPE_PA:
-               return 1;
-               break;
-       default:
-               return -EPERM;
-               break;
+               case L1_BRICKTYPE_IX:
+               case L1_BRICKTYPE_PX:
+               case L1_BRICKTYPE_IA:
+               case L1_BRICKTYPE_PA:
+                       return 1;
+                       break;
+               default:
+                       return -EPERM;
+                       break;
        }
 
        return -EIO;
@@ -142,13 +159,12 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
 
        pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
 
-       bss_hotplug_slot->private = kcalloc(1, sizeof(struct slot),
-                                           GFP_KERNEL);
-       if (!bss_hotplug_slot->private)
+       slot = kcalloc(1, sizeof(*slot), GFP_KERNEL);
+       if (!slot)
                return -ENOMEM;
-       slot = (struct slot *)bss_hotplug_slot->private;
+       bss_hotplug_slot->private = slot;
 
-       bss_hotplug_slot->name = kmalloc(33, GFP_KERNEL);
+       bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
        if (!bss_hotplug_slot->name) {
                kfree(bss_hotplug_slot->private);
                return -ENOMEM;
@@ -156,16 +172,16 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
 
        slot->device_num = device;
        slot->pci_bus = pci_bus;
-
-       sprintf(bss_hotplug_slot->name, "module_%c%c%c%c%.2d_b_%d_s_%d",
+       sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
+               pci_domain_nr(pci_bus),
+               ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
+               device + 1);
+       sprintf(slot->physical_path, "module_%c%c%c%c%.2d",
                '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
                '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
                '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
                MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
-               MODULE_GET_BPOS(pcibus_info->pbi_moduleid),
-               ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
-               device + 1);
-
+               MODULE_GET_BPOS(pcibus_info->pbi_moduleid));
        slot->hotplug_slot = bss_hotplug_slot;
        list_add(&slot->hp_list, &sn_hp_list);
 
@@ -175,14 +191,14 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
 static struct hotplug_slot * sn_hp_destroy(void)
 {
        struct slot *slot;
-       struct list_head *list;
        struct hotplug_slot *bss_hotplug_slot = NULL;
 
-       list_for_each(list, &sn_hp_list) {
-               slot = list_entry(list, struct slot, hp_list);
+       list_for_each_entry(slot, &sn_hp_list, hp_list) {
                bss_hotplug_slot = slot->hotplug_slot;
                list_del(&((struct slot *)bss_hotplug_slot->private)->
                         hp_list);
+               sysfs_remove_file(&bss_hotplug_slot->kobj,
+                                 &sn_slot_path_attr.attr);
                break;
        }
        return bss_hotplug_slot;
@@ -190,7 +206,6 @@ static struct hotplug_slot * sn_hp_destroy(void)
 
 static void sn_bus_alloc_data(struct pci_dev *dev)
 {
-       struct list_head *node;
        struct pci_bus *subordinate_bus;
        struct pci_dev *child;
 
@@ -199,66 +214,29 @@ static void sn_bus_alloc_data(struct pci_dev *dev)
        /* Recursively sets up the sn_irq_info structs */
        if (dev->subordinate) {
                subordinate_bus = dev->subordinate;
-               list_for_each(node, &subordinate_bus->devices) {
-                       child = list_entry(node, struct pci_dev, bus_list);
+               list_for_each_entry(child, &subordinate_bus->devices, bus_list)
                        sn_bus_alloc_data(child);
-               }
        }
 }
 
 static void sn_bus_free_data(struct pci_dev *dev)
 {
-       struct list_head *node;
        struct pci_bus *subordinate_bus;
        struct pci_dev *child;
 
        /* Recursively clean up sn_irq_info structs */
        if (dev->subordinate) {
                subordinate_bus = dev->subordinate;
-               list_for_each(node, &subordinate_bus->devices) {
-                       child = list_entry(node, struct pci_dev, bus_list);
+               list_for_each_entry(child, &subordinate_bus->devices, bus_list)
                        sn_bus_free_data(child);
-               }
        }
        sn_pci_unfixup_slot(dev);
 }
 
-static u8 sn_power_status_get(struct hotplug_slot *bss_hotplug_slot)
-{
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
-       struct pcibus_info *pcibus_info;
-       u8 retval;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-       retval = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
-
-       return retval ? 1 : 0;
-}
-
-static void sn_slot_mark_enable(struct hotplug_slot *bss_hotplug_slot,
-                               int device_num)
-{
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
-       struct pcibus_info *pcibus_info;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-       pcibus_info->pbi_enabled_devices |= (1 << device_num);
-}
-
-static void sn_slot_mark_disable(struct hotplug_slot *bss_hotplug_slot,
-                                int device_num)
-{
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
-       struct pcibus_info *pcibus_info;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-       pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
-}
-
 static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
                          int device_num)
 {
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+       struct slot *slot = bss_hotplug_slot->private;
        struct pcibus_info *pcibus_info;
        struct pcibr_slot_enable_resp resp;
        int rc;
@@ -273,7 +251,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
 
        if (rc == PCI_SLOT_ALREADY_UP) {
                dev_dbg(slot->pci_bus->self, "is already active\n");
-               return -EPERM;
+               return 1; /* return 1 to user */
        }
 
        if (rc == PCI_L1_ERR) {
@@ -290,7 +268,8 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
                return -EIO;
        }
 
-       sn_slot_mark_enable(bss_hotplug_slot, device_num);
+       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+       pcibus_info->pbi_enabled_devices |= (1 << device_num);
 
        return 0;
 }
@@ -298,7 +277,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
 static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
                           int device_num, int action)
 {
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+       struct slot *slot = bss_hotplug_slot->private;
        struct pcibus_info *pcibus_info;
        struct pcibr_slot_disable_resp resp;
        int rc;
@@ -307,43 +286,44 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
 
        rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
 
-       if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_SLOT_ALREADY_DOWN) {
+       if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
+           (rc == PCI_SLOT_ALREADY_DOWN)) {
                dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
-               return -ENODEV;
+               return 1; /* return 1 to user */
        }
 
-       if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_EMPTY_33MHZ) {
+       if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
                dev_dbg(slot->pci_bus->self,
                        "Cannot remove last 33MHz card\n");
                return -EPERM;
        }
 
-       if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_L1_ERR) {
+       if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
                dev_dbg(slot->pci_bus->self,
                        "L1 failure %d with message \n%s\n",
                        resp.resp_sub_errno, resp.resp_l1_msg);
                return -EPERM;
        }
 
-       if (action == PCI_REQ_SLOT_ELIGIBLE && rc) {
+       if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
                dev_dbg(slot->pci_bus->self,
                        "remove failed with error %d sub-error %d\n",
                        rc, resp.resp_sub_errno);
                return -EIO;
        }
 
-       if (action == PCI_REQ_SLOT_ELIGIBLE && !rc)
+       if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
                return 0;
 
-       if (action == PCI_REQ_SLOT_DISABLE && !rc) {
-               sn_slot_mark_disable(bss_hotplug_slot, device_num);
+       if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
+               pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+               pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
                dev_dbg(slot->pci_bus->self, "remove successful\n");
                return 0;
        }
 
-       if (action == PCI_REQ_SLOT_DISABLE && rc) {
+       if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
                dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
-               return rc;
        }
 
        return rc;
@@ -351,7 +331,7 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
 
 static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 {
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+       struct slot *slot = bss_hotplug_slot->private;
        struct pci_bus *new_bus = NULL;
        struct pci_dev *dev;
        int func, num_funcs;
@@ -371,8 +351,8 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
                return rc;
        }
 
-       num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num+1,
-                                                          PCI_FUNC(0)));
+       num_funcs = pci_scan_slot(slot->pci_bus,
+                                 PCI_DEVFN(slot->device_num + 1, 0));
        if (!num_funcs) {
                dev_dbg(slot->pci_bus->self, "no device in slot\n");
                up(&sn_hotplug_sem);
@@ -391,8 +371,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
                dev = pci_get_slot(slot->pci_bus,
                                   PCI_DEVFN(slot->device_num + 1,
                                             PCI_FUNC(func)));
-
-
                if (dev) {
                        if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
                                unsigned char sec_bus;
@@ -431,7 +409,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 
 static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
 {
-       struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+       struct slot *slot = bss_hotplug_slot->private;
        struct pci_dev *dev;
        int func;
        int rc;
@@ -448,7 +426,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
        /* Free the SN resources assigned to the Linux device.*/
        for (func = 0; func < 8;  func++) {
                dev = pci_get_slot(slot->pci_bus,
-                                  PCI_DEVFN(slot->device_num+1,
+                                  PCI_DEVFN(slot->device_num + 1,
                                             PCI_FUNC(func)));
                if (dev) {
                        /*
@@ -477,10 +455,15 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
        return rc;
 }
 
-static int get_power_status(struct hotplug_slot *bss_hotplug_slot, u8 *value)
+static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
+                                  u8 *value)
 {
+       struct slot *slot = bss_hotplug_slot->private;
+       struct pcibus_info *pcibus_info;
+
+       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
        down(&sn_hotplug_sem);
-       *value = sn_power_status_get(bss_hotplug_slot);
+       *value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
        up(&sn_hotplug_sem);
        return 0;
 }
@@ -508,7 +491,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
                if (sn_pci_slot_valid(pci_bus, device) != 1)
                        continue;
 
-               bss_hotplug_slot = kcalloc(1,sizeof(struct hotplug_slot),
+               bss_hotplug_slot = kcalloc(1, sizeof(*bss_hotplug_slot),
                                           GFP_KERNEL);
                if (!bss_hotplug_slot) {
                        rc = -ENOMEM;
@@ -516,7 +499,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
                }
 
                bss_hotplug_slot->info =
-                       kcalloc(1,sizeof(struct hotplug_slot_info),
+                       kcalloc(1, sizeof(struct hotplug_slot_info),
                                GFP_KERNEL);
                if (!bss_hotplug_slot->info) {
                        rc = -ENOMEM;
@@ -535,6 +518,11 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
                rc = pci_hp_register(bss_hotplug_slot);
                if (rc)
                        goto register_err;
+
+               rc = sysfs_create_file(&bss_hotplug_slot->kobj,
+                                      &sn_slot_path_attr.attr);
+               if (rc)
+                       goto register_err;
        }
        dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
        return rc;
@@ -564,14 +552,14 @@ static int sn_pci_hotplug_init(void)
        int rc;
        int registered = 0;
 
-       INIT_LIST_HEAD(&sn_hp_list);
-
        if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) {
-               printk(KERN_ERR "%s: PROM version must be greater than 4.05\n",
+               printk(KERN_ERR "%s: PROM version must be greater than 4.30\n",
                       __FUNCTION__);
                return -EPERM;
        }
 
+       INIT_LIST_HEAD(&sn_hp_list);
+
        while ((pci_bus = pci_find_next_bus(pci_bus))) {
                if (!pci_bus->sysdata)
                        continue;
@@ -584,9 +572,9 @@ static int sn_pci_hotplug_init(void)
                dev_dbg(pci_bus->self, "valid hotplug bus\n");
 
                rc = sn_hotplug_slot_register(pci_bus);
-               if (!rc)
+               if (!rc) {
                        registered = 1;
-               else {
+               else {
                        registered = 0;
                        break;
                }
@@ -599,9 +587,8 @@ static void sn_pci_hotplug_exit(void)
 {
        struct hotplug_slot *bss_hotplug_slot;
 
-       while ((bss_hotplug_slot = sn_hp_destroy())) {
+       while ((bss_hotplug_slot = sn_hp_destroy()))
                pci_hp_deregister(bss_hotplug_slot);
-       }
 
        if (!list_empty(&sn_hp_list))
                printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
index fe4d653da18849f9a7793b62630c45ec009e2139..b7d1c61d6bbbe8aa30674a6fdea8790e527e8a67 100644 (file)
@@ -411,7 +411,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
 
 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
 {
-       snprintf(buffer, buffer_size, "%d", slot->number);
+       snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
 }
 
 enum php_ctlr_type {
index 532f73bb2224af802af190aa0a38ea66242aa188..ee8677bda950e5c95b7b73fe4cb3386b50e41a05 100644 (file)
@@ -439,10 +439,7 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
        }
        if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
                /* PCI Express Endpoint device detected */
-               u16 cmd;
-               pci_read_config_word(dev, PCI_COMMAND, &cmd);
-               cmd |= PCI_COMMAND_INTX_DISABLE;
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
+               pci_intx(dev, 0);  /* disable intx */
        }
 }
 
@@ -461,10 +458,7 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
        }
        if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
                /* PCI Express Endpoint device detected */
-               u16 cmd;
-               pci_read_config_word(dev, PCI_COMMAND, &cmd);
-               cmd &= ~PCI_COMMAND_INTX_DISABLE;
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
+               pci_intx(dev, 1);  /* enable intx */
        }
 }
 
diff --git a/drivers/pci/names.c b/drivers/pci/names.c
deleted file mode 100644 (file)
index ad224aa..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *     PCI Class and Device Name Tables
- *
- *     Copyright 1993--1999 Drew Eckhardt, Frederic Potter,
- *     David Mosberger-Tang, Martin Mares
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#ifdef CONFIG_PCI_NAMES
-
-struct pci_device_info {
-       unsigned short device;
-       unsigned short seen;
-       const char *name;
-};
-
-struct pci_vendor_info {
-       unsigned short vendor;
-       unsigned short nr;
-       const char *name;
-       struct pci_device_info *devices;
-};
-
-/*
- * This is ridiculous, but we want the strings in
- * the .init section so that they don't take up
- * real memory.. Parse the same file multiple times
- * to get all the info.
- */
-#define VENDOR( vendor, name )         static char __vendorstr_##vendor[] __devinitdata = name;
-#define ENDVENDOR()
-#define DEVICE( vendor, device, name )         static char __devicestr_##vendor##device[] __devinitdata = name;
-#include "devlist.h"
-
-
-#define VENDOR( vendor, name )         static struct pci_device_info __devices_##vendor[] __devinitdata = {
-#define ENDVENDOR()                    };
-#define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device },
-#include "devlist.h"
-
-static struct pci_vendor_info __devinitdata pci_vendor_list[] = {
-#define VENDOR( vendor, name )         { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
-#define ENDVENDOR()
-#define DEVICE( vendor, device, name )
-#include "devlist.h"
-};
-
-#define VENDORS (sizeof(pci_vendor_list)/sizeof(struct pci_vendor_info))
-
-void __devinit pci_name_device(struct pci_dev *dev)
-{
-       const struct pci_vendor_info *vendor_p = pci_vendor_list;
-       int i = VENDORS;
-       char *name = dev->pretty_name;
-
-       do {
-               if (vendor_p->vendor == dev->vendor)
-                       goto match_vendor;
-               vendor_p++;
-       } while (--i);
-
-       /* Couldn't find either the vendor nor the device */
-       sprintf(name, "PCI device %04x:%04x", dev->vendor, dev->device);
-       return;
-
-       match_vendor: {
-               struct pci_device_info *device_p = vendor_p->devices;
-               int i = vendor_p->nr;
-
-               while (i > 0) {
-                       if (device_p->device == dev->device)
-                               goto match_device;
-                       device_p++;
-                       i--;
-               }
-
-               /* Ok, found the vendor, but unknown device */
-               sprintf(name, "PCI device %04x:%04x (%." PCI_NAME_HALF "s)",
-                               dev->vendor, dev->device, vendor_p->name);
-               return;
-
-               /* Full match */
-               match_device: {
-                       char *n = name + sprintf(name, "%s %s",
-                                       vendor_p->name, device_p->name);
-                       int nr = device_p->seen + 1;
-                       device_p->seen = nr;
-                       if (nr > 1)
-                               sprintf(n, " (#%d)", nr);
-               }
-       }
-}
-
-/*
- *  Class names. Not in .init section as they are needed in runtime.
- */
-
-static u16 pci_class_numbers[] = {
-#define CLASS(x,y) 0x##x,
-#include "classlist.h"
-};
-
-static char *pci_class_names[] = {
-#define CLASS(x,y) y,
-#include "classlist.h"
-};
-
-char *
-pci_class_name(u32 class)
-{
-       int i;
-
-       for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++)
-               if (pci_class_numbers[i] == class)
-                       return pci_class_names[i];
-       return NULL;
-}
-
-#else
-
-void __devinit pci_name_device(struct pci_dev *dev)
-{
-}
-
-char *
-pci_class_name(u32 class)
-{
-       return NULL;
-}
-
-#endif /* CONFIG_PCI_NAMES */
-
index e4115a0d5ba6152852e43840eb56f702481d8bac..0d0d533894e0737694f01d16dae1b441b95d5247 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/mempolicy.h>
 #include "pci.h"
 
 /*
@@ -163,6 +164,34 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
        return NULL;
 }
 
+static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
+                         const struct pci_device_id *id)
+{
+       int error;
+#ifdef CONFIG_NUMA
+       /* Execute driver initialization on node where the
+          device's bus is attached to.  This way the driver likely
+          allocates its local memory on the right node without
+          any need to change it. */
+       struct mempolicy *oldpol;
+       cpumask_t oldmask = current->cpus_allowed;
+       int node = pcibus_to_node(dev->bus);
+       if (node >= 0 && node_online(node))
+           set_cpus_allowed(current, node_to_cpumask(node));
+       /* And set default memory allocation policy */
+       oldpol = current->mempolicy;
+       current->mempolicy = &default_policy;
+       mpol_get(current->mempolicy);
+#endif
+       error = drv->probe(dev, id);
+#ifdef CONFIG_NUMA
+       set_cpus_allowed(current, oldmask);
+       mpol_free(current->mempolicy);
+       current->mempolicy = oldpol;
+#endif
+       return error;
+}
+
 /**
  * __pci_device_probe()
  * 
@@ -180,7 +209,7 @@ __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
 
                id = pci_match_device(drv, pci_dev);
                if (id)
-                       error = drv->probe(pci_dev, id);
+                       error = pci_call_probe(drv, pci_dev, id);
                if (error >= 0) {
                        pci_dev->driver = drv;
                        error = 0;
@@ -243,17 +272,19 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
 }
 
 
-/* 
+/*
  * Default resume method for devices that have no driver provided resume,
  * or not even a driver at all.
  */
 static void pci_default_resume(struct pci_dev *pci_dev)
 {
+       int retval;
+
        /* restore the PCI config space */
        pci_restore_state(pci_dev);
        /* if the device was enabled before suspend, reenable */
        if (pci_dev->is_enabled)
-               pci_enable_device(pci_dev);
+               retval = pci_enable_device(pci_dev);
        /* if the device was busmaster before the suspend, make it busmaster again */
        if (pci_dev->is_busmaster)
                pci_set_master(pci_dev);
index c62d2f04339714cbf5380aa68dbdddf4aaba46c0..ccff633a3948626d7c797f1b2e586e68d56d04e8 100644 (file)
@@ -221,6 +221,37 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
        return best;
 }
 
+/**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+void
+pci_restore_bars(struct pci_dev *dev)
+{
+       int i, numres;
+
+       switch (dev->hdr_type) {
+       case PCI_HEADER_TYPE_NORMAL:
+               numres = 6;
+               break;
+       case PCI_HEADER_TYPE_BRIDGE:
+               numres = 2;
+               break;
+       case PCI_HEADER_TYPE_CARDBUS:
+               numres = 1;
+               break;
+       default:
+               /* Should never get here, but just in case... */
+               return;
+       }
+
+       for (i = 0; i < numres; i ++)
+               pci_update_resource(dev, &dev->resource[i], i);
+}
+
 /**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
@@ -239,7 +270,7 @@ int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-       int pm;
+       int pm, need_restore = 0;
        u16 pmcsr, pmc;
 
        /* bound the state we're entering */
@@ -263,7 +294,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                return -EIO; 
 
        pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
-       if ((pmc & PCI_PM_CAP_VER_MASK) > 2) {
+       if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
                printk(KERN_DEBUG
                       "PCI: %s has unsupported PM cap regs version (%u)\n",
                       pci_name(dev), pmc & PCI_PM_CAP_VER_MASK);
@@ -271,21 +302,22 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        }
 
        /* check if this device supports the desired state */
-       if (state == PCI_D1 || state == PCI_D2) {
-               if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
-                       return -EIO;
-               else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
-                       return -EIO;
-       }
+       if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
+               return -EIO;
+       else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
+               return -EIO;
+
+       pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
 
        /* If we're in D3, force entire word to 0.
         * This doesn't affect PME_Status, disables PME_En, and
         * sets PowerState to 0.
         */
-       if (dev->current_state >= PCI_D3hot)
+       if (dev->current_state >= PCI_D3hot) {
+               if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+                       need_restore = 1;
                pmcsr = 0;
-       else {
-               pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+       } else {
                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
                pmcsr |= state;
        }
@@ -308,6 +340,22 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                platform_pci_set_power_state(dev, state);
 
        dev->current_state = state;
+
+       /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
+        * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
+        * from D3hot to D0 _may_ perform an internal reset, thereby
+        * going to "D0 Uninitialized" rather than "D0 Initialized".
+        * For example, at least some versions of the 3c905B and the
+        * 3c556B exhibit this behaviour.
+        *
+        * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
+        * devices in a D3hot state at boot.  Consequently, we need to
+        * restore at least the BARs so that the device will be
+        * accessible to its driver.
+        */
+       if (need_restore)
+               pci_restore_bars(dev);
+
        return 0;
 }
 
@@ -394,8 +442,11 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
 {
        int err;
 
-       pci_set_power_state(dev, PCI_D0);
-       if ((err = pcibios_enable_device(dev, bars)) < 0)
+       err = pci_set_power_state(dev, PCI_D0);
+       if (err < 0 && err != -EIO)
+               return err;
+       err = pcibios_enable_device(dev, bars);
+       if (err < 0)
                return err;
        return 0;
 }
@@ -747,6 +798,31 @@ pci_clear_mwi(struct pci_dev *dev)
        }
 }
 
+/**
+ * pci_intx - enables/disables PCI INTx for device dev
+ * @dev: the PCI device to operate on
+ * @enable: boolean
+ *
+ * Enables/disables PCI INTx for device dev
+ */
+void
+pci_intx(struct pci_dev *pdev, int enable)
+{
+       u16 pci_command, new;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+
+       if (enable) {
+               new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+       } else {
+               new = pci_command | PCI_COMMAND_INTX_DISABLE;
+       }
+
+       if (new != pci_command) {
+               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+       }
+}
+
 #ifndef HAVE_ARCH_PCI_SET_DMA_MASK
 /*
  * These can be overridden by arch-specific implementations
@@ -809,6 +885,7 @@ struct pci_dev *isa_bridge;
 EXPORT_SYMBOL(isa_bridge);
 #endif
 
+EXPORT_SYMBOL_GPL(pci_restore_bars);
 EXPORT_SYMBOL(pci_enable_device_bars);
 EXPORT_SYMBOL(pci_enable_device);
 EXPORT_SYMBOL(pci_disable_device);
@@ -823,6 +900,7 @@ EXPORT_SYMBOL(pci_request_region);
 EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
+EXPORT_SYMBOL_GPL(pci_intx);
 EXPORT_SYMBOL(pci_set_dma_mask);
 EXPORT_SYMBOL(pci_set_consistent_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
deleted file mode 100644 (file)
index 1d2ef1e..0000000
+++ /dev/null
@@ -1,10180 +0,0 @@
-#
-#      List of PCI ID's
-#
-#      Maintained by Martin Mares <mj@ucw.cz> and other volunteers from the
-#      Linux PCI ID's Project at http://pciids.sf.net/. New data are always
-#      welcome (if they are accurate), we're eagerly expecting new entries,
-#      so if you have anything to contribute, please visit the home page or
-#      send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
-#
-#      Daily snapshot on Tue 2005-03-08 10:11:48
-#
-
-# Vendors, devices and subsystems. Please keep sorted.
-
-# Syntax:
-# vendor  vendor_name
-#      device  device_name                             <-- single tab
-#              subvendor subdevice  subsystem_name     <-- two tabs
-
-0000  Gammagraphx, Inc.
-001a  Ascend Communications, Inc.
-0033  Paradyne corp.
-003d  Lockheed Martin-Marietta Corp
-# Real TJN ID is e159, but they got it wrong several times --mj
-0059  Tiger Jet Network Inc. (Wrong ID)
-0070  Hauppauge computer works Inc.
-       4000  WinTV PVR-350
-       4001  WinTV PVR-250 (v1)
-       4009  WinTV PVR-250
-       4801  WinTV PVR-250 MCE
-0071  Nebula Electronics Ltd.
-0095  Silicon Image, Inc. (Wrong ID)
-       0680  Ultra ATA/133 IDE RAID CONTROLLER CARD
-0100  Ncipher Corp Ltd
-# 018a is not LevelOne but there is a board misprogrammed
-018a  LevelOne
-       0106  FPC-0106TX misprogrammed [RTL81xx]
-# 021b is not Compaq but there is a board misprogrammed
-021b  Compaq Computer Corporation
-       8139  HNE-300 (RealTek RTL8139c) [iPaq Networking]
-# http://www.davicom.com.tw/
-0291  Davicom Semiconductor, Inc.
-       8212  DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40)
-# SpeedStream is Efficient Networks, Inc, a Siemens Company
-02ac  SpeedStream
-       1012  1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
-0357  TTTech AG
-       000a  TTP-Monitoring Card V2.0
-0432  SCM Microsystems, Inc.
-       0001  Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
-05e3  CyberDoor
-       0701  CBD516
-0675  Dynalink
-       1700  IS64PH ISDN Adapter
-       1702  IS64PH ISDN Adapter
-# Wrong ID used in subsystem ID of VIA USB controllers.
-0925  VIA Technologies, Inc. (Wrong ID)
-09c1  Arris
-       0704  CM 200E Cable Modem
-0a89  BREA Technologies Inc
-0b49  ASCII Corporation
-# see http://homepage1.nifty.com/mcn/lab/machines/trance_vibrator/usbview.vib.txt
-       064f  Trance Vibrator
-0e11  Compaq Computer Corporation
-       0001  PCI to EISA Bridge
-       0002  PCI to ISA Bridge
-       0046  Smart Array 64xx
-               0e11 409a  Smart Array 641
-               0e11 409b  Smart Array 642
-               0e11 409c  Smart Array 6400
-               0e11 409d  Smart Array 6400 EM
-       0049  NC7132 Gigabit Upgrade Module
-       004a  NC6136 Gigabit Server Adapter
-       007c  NC7770 1000BaseTX
-       007d  NC6770 1000BaseTX
-       0085  NC7780 1000BaseTX
-       00bb  NC7760
-       00ca  NC7771
-       00cb  NC7781
-       00cf  NC7772
-       00d0  NC7782
-       00d1  NC7783
-       00e3  NC7761
-       0508  Netelligent 4/16 Token Ring
-       1000  Triflex/Pentium Bridge, Model 1000
-       2000  Triflex/Pentium Bridge, Model 2000
-       3032  QVision 1280/p
-       3033  QVision 1280/p
-       3034  QVision 1280/p
-       4000  4000 [Triflex]
-       4030  SMART-2/P
-       4031  SMART-2SL
-       4032  Smart Array 3200
-       4033  Smart Array 3100ES
-       4034  Smart Array 221
-       4040  Integrated Array
-       4048  Compaq Raid LC2
-       4050  Smart Array 4200
-       4051  Smart Array 4250ES
-       4058  Smart Array 431
-       4070  Smart Array 5300
-       4080  Smart Array 5i
-       4082  Smart Array 532
-       4083  Smart Array 5312
-       4091  Smart Array 6i
-       409a  Smart Array 641
-       409b  Smart Array 642
-       409c  Smart Array 6400
-       409d  Smart Array 6400 EM
-       6010  HotPlug PCI Bridge 6010
-       7020  USB Controller
-       a0ec  Fibre Channel Host Controller
-       a0f0  Advanced System Management Controller
-       a0f3  Triflex PCI to ISA Bridge
-       a0f7  PCI Hotplug Controller
-               8086 002a  PCI Hotplug Controller A
-               8086 002b  PCI Hotplug Controller B
-       a0f8  ZFMicro Chipset USB
-       a0fc  FibreChannel HBA Tachyon
-       ae10  Smart-2/P RAID Controller
-               0e11 4030  Smart-2/P Array Controller
-               0e11 4031  Smart-2SL Array Controller
-               0e11 4032  Smart Array Controller
-               0e11 4033  Smart 3100ES Array Controller
-       ae29  MIS-L
-       ae2a  MPC
-       ae2b  MIS-E
-       ae31  System Management Controller
-       ae32  Netelligent 10/100 TX PCI UTP
-       ae33  Triflex Dual EIDE Controller
-       ae34  Netelligent 10 T PCI UTP
-       ae35  Integrated NetFlex-3/P
-       ae40  Netelligent Dual 10/100 TX PCI UTP
-       ae43  Netelligent Integrated 10/100 TX UTP
-       ae69  CETUS-L
-       ae6c  Northstar
-       ae6d  NorthStar CPU to PCI Bridge
-       b011  Netelligent 10/100 TX Embedded UTP
-       b012  Netelligent 10 T/2 PCI UTP/Coax
-       b01e  NC3120 Fast Ethernet NIC
-       b01f  NC3122 Fast Ethernet NIC
-       b02f  NC1120 Ethernet NIC
-       b030  Netelligent 10/100 TX UTP
-       b04a  10/100 TX PCI Intel WOL UTP Controller
-       b060  Smart Array 5300 Controller
-       b0c6  NC3161 Fast Ethernet NIC
-       b0c7  NC3160 Fast Ethernet NIC
-       b0d7  NC3121 Fast Ethernet NIC
-       b0dd  NC3131 Fast Ethernet NIC
-       b0de  NC3132 Fast Ethernet Module
-       b0df  NC6132 Gigabit Module
-       b0e0  NC6133 Gigabit Module
-       b0e1  NC3133 Fast Ethernet Module
-       b123  NC6134 Gigabit NIC
-       b134  NC3163 Fast Ethernet NIC
-       b13c  NC3162 Fast Ethernet NIC
-       b144  NC3123 Fast Ethernet NIC
-       b163  NC3134 Fast Ethernet NIC
-       b164  NC3165 Fast Ethernet Upgrade Module
-       b178  Smart Array 5i/532
-               0e11 4080  Smart Array 5i
-               0e11 4082  Smart Array 532
-               0e11 4083  Smart Array 5312
-       b1a4  NC7131 Gigabit Server Adapter
-# HP Memory Hot-Plug Controller
-       b200  Memory Hot-Plug Controller
-       b203  Integrated Lights Out Controller
-       b204  Integrated Lights Out  Processor
-       f130  NetFlex-3/P ThunderLAN 1.0
-       f150  NetFlex-3/P ThunderLAN 2.3
-0e55  HaSoTec GmbH
-# Formerly NCR
-1000  LSI Logic / Symbios Logic
-       0001  53c810
-               1000 1000  LSI53C810AE PCI to SCSI I/O Processor
-       0002  53c820
-       0003  53c825
-               1000 1000  LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
-       0004  53c815
-       0005  53c810AP
-       0006  53c860
-               1000 1000  LSI53C860E PCI to Ultra SCSI I/O Processor
-       000a  53c1510
-               1000 1000  LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
-       000b  53C896/897
-               0e11 6004  EOB003 Series SCSI host adapter
-               1000 1000  LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
-               1000 1010  LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
-               1000 1020  LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
-# multifunction PCI card: Dual U2W SCSI, dual 10/100TX, graphics
-               13e9 1000  6221L-4U
-       000c  53c895
-               1000 1010  LSI8951U PCI to Ultra2 SCSI host adapter
-               1000 1020  LSI8952U PCI to Ultra2 SCSI host adapter
-               1de1 3906  DC-390U2B SCSI adapter
-               1de1 3907  DC-390U2W
-       000d  53c885
-       000f  53c875
-               0e11 7004  Embedded Ultra Wide SCSI Controller
-               1000 1000  LSI53C876/E PCI to Dual Channel SCSI Controller
-               1000 1010  LSI22801 PCI to Dual Channel Ultra SCSI host adapter
-               1000 1020  LSI22802 PCI to Dual Channel Ultra SCSI host adapter
-               1092 8760  FirePort 40 Dual SCSI Controller
-               1de1 3904  DC390F/U Ultra Wide SCSI Adapter
-               4c53 1000  CC7/CR7/CP7/VC7/VP7/VR7 mainboard
-               4c53 1050  CT7 mainboard
-       0010  53C1510
-               0e11 4040  Integrated Array Controller
-               0e11 4048  RAID LC2 Controller
-               1000 1000  53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
-       0012  53c895a
-               1000 1000  LSI53C895A PCI to Ultra2 SCSI Controller
-       0013  53c875a
-               1000 1000  LSI53C875A PCI to Ultra SCSI Controller
-       0020  53c1010 Ultra3 SCSI Adapter
-               1000 1000  LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
-               1de1 1020  DC-390U3W
-       0021  53c1010 66MHz  Ultra3 SCSI Adapter
-               1000 1000  LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
-               1000 1010  Asus TR-DLS onboard 53C1010-66
-               124b 1070  PMC-USCSI3
-               4c53 1080  CT8 mainboard
-               4c53 1300  P017 mezzanine (32-bit PMC)
-               4c53 1310  P017 mezzanine (64-bit PMC)
-       0030  53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
-               1028 0123  PowerEdge 2600
-               1028 014a  PowerEdge 1750
-               1028 016c  PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
-               1028 0183  PowerEdge 1800
-               1028 1010  LSI U320 SCSI Controller
-       0031  53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
-       0032  53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
-               1000 1000  LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
-       0033  1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
-       0040  53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
-               1000 0033  MegaRAID SCSI 320-2XR
-               1000 0066  MegaRAID SCSI 320-2XRWS
-       0041  53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
-       008f  53c875J
-               1092 8000  FirePort 40 SCSI Controller
-               1092 8760  FirePort 40 Dual SCSI Host Adapter
-       0407  MegaRAID
-               1000 0530  MegaRAID 530 SCSI 320-0X RAID Controller
-               1000 0531  MegaRAID 531 SCSI 320-4X RAID Controller
-               1000 0532  MegaRAID 532 SCSI 320-2X RAID Controller
-               1028 0531  PowerEdge Expandable RAID Controller 4/QC
-               1028 0533  PowerEdge Expandable RAID Controller 4/QC
-               8086 0530  MegaRAID Intel RAID Controller SRCZCRX
-               8086 0532  MegaRAID Intel RAID Controller SRCU42X
-       0408  MegaRAID
-               1000 0001  MegaRAID SCSI 320-1E RAID Controller
-               1000 0002  MegaRAID SCSI 320-2E RAID Controller
-               1025 004d  MegaRAID ACER ROMB-2E RAID Controller
-               1028 0001  PowerEdge RAID Controller PERC4e/SC
-               1028 0002  PowerEdge RAID Controller PERC4e/DC
-               1734 1065  FSC MegaRAID PCI Express ROMB
-               8086 0002  MegaRAID Intel RAID Controller SRCU42E
-       0409  MegaRAID
-               1000 3004  MegaRAID SATA 300-4X RAID Controller
-               1000 3008  MegaRAID SATA 300-8X RAID Controller
-               8086 3008  MegaRAID RAID Controller SRCS28X
-               8086 3431  MegaRAID RAID Controller Alief SROMBU42E
-               8086 3499  MegaRAID RAID Controller Harwich SROMBU42E
-       0621  FC909 Fibre Channel Adapter
-       0622  FC929 Fibre Channel Adapter
-               1000 1020  44929 O Dual Fibre Channel card
-       0623  FC929 LAN
-       0624  FC919 Fibre Channel Adapter
-       0625  FC919 LAN
-       0626  FC929X Fibre Channel Adapter
-               1000 1010  7202-XP-LC Dual Fibre Channel card
-       0627  FC929X LAN
-       0628  FC919X Fibre Channel Adapter
-       0629  FC919X LAN
-       0701  83C885 NT50 DigitalScape Fast Ethernet
-       0702  Yellowfin G-NIC gigabit ethernet
-               1318 0000  PEI100X
-       0804  SA2010
-       0805  SA2010ZC
-       0806  SA2020
-       0807  SA2020ZC
-       0901  61C102
-       1000  63C815
-       1960  MegaRAID
-               1000 0518  MegaRAID 518 SCSI 320-2 Controller
-               1000 0520  MegaRAID 520 SCSI 320-1 Controller
-               1000 0522  MegaRAID 522 i4 133 RAID Controller
-               1000 0523  MegaRAID SATA 150-6 RAID Controller
-               1000 4523  MegaRAID SATA 150-4 RAID Controller
-               1000 a520  MegaRAID ZCR SCSI 320-0 Controller
-               1028 0518  MegaRAID 518 DELL PERC 4/DC RAID Controller
-               1028 0520  MegaRAID 520 DELL PERC 4/SC RAID Controller
-               1028 0531  PowerEdge Expandable RAID Controller 4/QC
-               1028 0533  PowerEdge Expandable RAID Controller 4/QC
-               8086 0520  MegaRAIDRAID Controller SRCU41L
-               8086 0523  MegaRAID RAID Controller SRCS16
-1001  Kolter Electronic
-       0010  PCI 1616 Measurement card with 32 digital I/O lines
-       0011  OPTO-PCI Opto-Isolated digital I/O board
-       0012  PCI-AD/DA Analogue I/O board
-       0013  PCI-OPTO-RELAIS Digital I/O board with relay outputs
-       0014  PCI-Counter/Timer Counter Timer board
-       0015  PCI-DAC416 Analogue output board
-       0016  PCI-MFB Analogue I/O board
-       0017  PROTO-3 PCI Prototyping board
-       9100  INI-9100/9100W SCSI Host
-1002  ATI Technologies Inc
-       3150  M24 1P [Radeon Mobility X600]
-       3154  M24 1T [FireGL M24 GL]
-       3e50  RV380 0x3e50 [Radeon X600]
-       3e54  RV380 0x3e54 [FireGL V3200]
-       3e70  RV380 [Radeon X600] Secondary
-       4136  Radeon IGP 320 M
-       4137  Radeon IGP330/340/350
-       4144  R300 AD [Radeon 9500 Pro]
-# New PCI ID provided by ATI developer relations (correction to above)
-       4145  R300 AE [Radeon 9700 Pro]
-# New PCI ID provided by ATI developer relations (oops, correction to above)
-       4146  R300 AF [Radeon 9700 Pro]
-       4147  R300 AG [FireGL Z1/X1]
-       4148  R350 AH [Radeon 9800]
-       4149  R350 AI [Radeon 9800]
-       414a  R350 AJ [Radeon 9800]
-       414b  R350 AK [Fire GL X2]
-# New PCI ID provided by ATI developer relations
-       4150  RV350 AP [Radeon 9600]
-               1002 0002  R9600 Pro primary (Asus OEM for HP)
-               1002 0003  R9600 Pro secondary (Asus OEM for HP)
-               1458 4024  Giga-Byte GV-R96128D Primary
-               148c 2064  PowerColor R96A-C3N
-               148c 2066  PowerColor R96A-C3N
-               174b 7c19  Sapphire Atlantis Radeon 9600 Pro
-               174b 7c29  GC-R9600PRO Primary [Sapphire]
-               17ee 2002  Radeon 9600 256Mb Primary
-               18bc 0101  GC-R9600PRO Primary
-# New PCI ID provided by ATI developer relations
-       4151  RV350 AQ [Radeon 9600]
-               1043 c004  A9600SE
-# New PCI ID provided by ATI developer relations
-       4152  RV350 AR [Radeon 9600]
-               1002 0002  Radeon 9600XT
-               1043 c002  Radeon 9600 XT TVD
-               174b 7c29  Sapphire Radeon 9600XT
-               1787 4002  Radeon 9600 XT
-       4153  RV350 AS [Radeon 9600 AS]
-       4154  RV350 AT [Fire GL T2]
-       4155  RV350 AU [Fire GL T2]
-       4156  RV350 AV [Fire GL T2]
-       4157  RV350 AW [Fire GL T2]
-       4158  68800AX [Mach32]
-# The PCI ID is unrelated to any DVI output.
-       4164  R300 AD [Radeon 9500 Pro] (Secondary)
-# New PCI ID info provided by ATI developer relations
-       4165  R300 AE [Radeon 9700 Pro] (Secondary)
-# New PCI ID info provided by ATI developer relations
-       4166  R300 AF [Radeon 9700 Pro] (Secondary)
-# New PCI ID provided by ATI developer relations
-       4168  Radeon R350 [Radeon 9800] (Secondary)
-# New PCI ID provided by ATI developer relations (correction to above)
-       4170  RV350 AP [Radeon 9600] (Secondary)
-               1458 4025  Giga-Byte GV-R96128D Secondary
-               148c 2067  PowerColor R96A-C3N (Secondary)
-               174b 7c28  GC-R9600PRO Secondary [Sapphire]
-               17ee 2003  Radeon 9600 256Mb Secondary
-               18bc 0100  GC-R9600PRO Secondary
-# New PCI ID provided by ATI developer relations (correction to above)
-       4171  RV350 AQ [Radeon 9600] (Secondary)
-               1043 c005  A9600SE (Secondary)
-# New PCI ID provided by ATI developer relations (correction to above)
-       4172  RV350 AR [Radeon 9600] (Secondary)
-               1002 0003  Radeon 9600XT (Secondary)
-               1043 c003  A9600XT (Secondary)
-               174b 7c28  Sapphire Radeon 9600XT (Secondary)
-               1787 4003  Radeon 9600 XT (Secondary)
-       4173  RV350 ?? [Radeon 9550] (Secondary)
-       4237  Radeon 7000 IGP
-       4242  R200 BB [Radeon All in Wonder 8500DV]
-               1002 02aa  Radeon 8500 AIW DV Edition
-       4243  R200 BC [Radeon All in Wonder 8500]
-       4336  Radeon Mobility U1
-               103c 0024  Pavilion ze4400 builtin Video
-       4337  Radeon IGP 330M/340M/350M
-               1014 053a  ThinkPad R40e (2684-HVG) builtin VGA controller
-               103c 0850  Radeon IGP 345M
-       4341  IXP150 AC'97 Audio Controller
-       4345  EHCI USB Controller
-       4347  OHCI USB Controller #1
-       4348  OHCI USB Controller #2
-       4349  ATI Dual Channel Bus Master PCI IDE Controller
-       434d  IXP AC'97 Modem
-       4353  ATI SMBus
-       4354  215CT [Mach64 CT]
-       4358  210888CX [Mach64 CX]
-       4363  ATI SMBus
-       436e  ATI 436E Serial ATA Controller
-       4372  ATI SMBus
-       4376  Standard Dual Channel PCI IDE Controller ATI
-       4379  ATI 4379 Serial ATA Controller
-       437a  ATI 437A Serial ATA Controller
-       4437  Radeon Mobility 7000 IGP
-       4554  210888ET [Mach64 ET]
-       4654  Mach64 VT
-       4742  3D Rage Pro AGP 1X/2X
-               1002 0040  Rage Pro Turbo AGP 2X
-               1002 0044  Rage Pro Turbo AGP 2X
-               1002 0061  Rage Pro AIW AGP 2X
-               1002 0062  Rage Pro AIW AGP 2X
-               1002 0063  Rage Pro AIW AGP 2X
-               1002 0080  Rage Pro Turbo AGP 2X
-               1002 0084  Rage Pro Turbo AGP 2X
-               1002 4742  Rage Pro Turbo AGP 2X
-               1002 8001  Rage Pro Turbo AGP 2X
-               1028 0082  Rage Pro Turbo AGP 2X
-               1028 4082  Optiplex GX1 Onboard Display Adapter
-               1028 8082  Rage Pro Turbo AGP 2X
-               1028 c082  Rage Pro Turbo AGP 2X
-               8086 4152  Xpert 98D AGP 2X
-               8086 464a  Rage Pro Turbo AGP 2X
-       4744  3D Rage Pro AGP 1X
-               1002 4744  Rage Pro Turbo AGP
-       4747  3D Rage Pro
-       4749  3D Rage Pro
-               1002 0061  Rage Pro AIW
-               1002 0062  Rage Pro AIW
-       474c  Rage XC
-       474d  Rage XL AGP 2X
-               1002 0004  Xpert 98 RXL AGP 2X
-               1002 0008  Xpert 98 RXL AGP 2X
-               1002 0080  Rage XL AGP 2X
-               1002 0084  Xpert 98 AGP 2X
-               1002 474d  Rage XL AGP
-               1033 806a  Rage XL AGP
-       474e  Rage XC AGP
-               1002 474e  Rage XC AGP
-       474f  Rage XL
-               1002 0008  Rage XL
-               1002 474f  Rage XL
-       4750  3D Rage Pro 215GP
-               1002 0040  Rage Pro Turbo
-               1002 0044  Rage Pro Turbo
-               1002 0080  Rage Pro Turbo
-               1002 0084  Rage Pro Turbo
-               1002 4750  Rage Pro Turbo
-       4751  3D Rage Pro 215GQ
-       4752  Rage XL
-               1002 0008  Rage XL
-               1002 4752  Rage XL
-               1002 8008  Rage XL
-               1028 00ce  PowerEdge 1400
-               1028 00d1  PowerEdge 2550
-               1028 00d9  PowerEdge 2500
-               8086 3411  SDS2 Mainboard
-               8086 3427  S875WP1-E mainboard
-       4753  Rage XC
-               1002 4753  Rage XC
-       4754  3D Rage I/II 215GT [Mach64 GT]
-       4755  3D Rage II+ 215GTB [Mach64 GTB]
-       4756  3D Rage IIC 215IIC [Mach64 GT IIC]
-               1002 4756  Rage IIC
-       4757  3D Rage IIC AGP
-               1002 4757  Rage IIC AGP
-               1028 0089  Rage 3D IIC
-               1028 4082  Rage 3D IIC
-               1028 8082  Rage 3D IIC
-               1028 c082  Rage 3D IIC
-       4758  210888GX [Mach64 GX]
-       4759  3D Rage IIC
-       475a  3D Rage IIC AGP
-               1002 0084  Rage 3D Pro AGP 2x XPERT 98
-               1002 0087  Rage 3D IIC
-               1002 475a  Rage IIC AGP
-       4964  Radeon RV250 Id [Radeon 9000]
-       4965  Radeon RV250 Ie [Radeon 9000]
-       4966  Radeon RV250 If [Radeon 9000]
-               10f1 0002  RV250 If [Tachyon G9000 PRO]
-               148c 2039  RV250 If [Radeon 9000 Pro "Evil Commando"]
-               1509 9a00  RV250 If [Radeon 9000 "AT009"]
-# New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified.
-               1681 0040  RV250 If [3D prophet 9000]
-               174b 7176  RV250 If [Sapphire Radeon 9000 Pro]
-               174b 7192  RV250 If [Radeon 9000 "Atlantis"]
-               17af 2005  RV250 If [Excalibur Radeon 9000 Pro]
-               17af 2006  RV250 If [Excalibur Radeon 9000]
-       4967  Radeon RV250 Ig [Radeon 9000]
-       496e  Radeon RV250 [Radeon 9000] (Secondary)
-       4a48  R420 JH [Radeon X800]
-       4a49  R420 JI [Radeon X800PRO]
-       4a4a  R420 JJ [Radeon X800SE]
-       4a4b  R420 JK [Radeon X800]
-       4a4c  R420 JL [Radeon X800]
-       4a4d  R420 JM [FireGL X3]
-       4a4e  M18 JN [Radeon Mobility 9800]
-       4a50  R420 JP [Radeon X800XT]
-       4a70  R420 [X800XT-PE] (Secondary)
-       4c42  3D Rage LT Pro AGP-133
-               0e11 b0e7  Rage LT Pro (Compaq Presario 5240)
-               0e11 b0e8  Rage 3D LT Pro
-               0e11 b10e  3D Rage LT Pro (Compaq Armada 1750)
-               1002 0040  Rage LT Pro AGP 2X
-               1002 0044  Rage LT Pro AGP 2X
-               1002 4c42  Rage LT Pro AGP 2X
-               1002 8001  Rage LT Pro AGP 2X
-               1028 0085  Rage 3D LT Pro
-       4c44  3D Rage LT Pro AGP-66
-       4c45  Rage Mobility M3 AGP
-       4c46  Rage Mobility M3 AGP 2x
-               1028 00b1  Latitude C600
-       4c47  3D Rage LT-G 215LG
-       4c49  3D Rage LT Pro
-               1002 0004  Rage LT Pro
-               1002 0040  Rage LT Pro
-               1002 0044  Rage LT Pro
-               1002 4c49  Rage LT Pro
-       4c4d  Rage Mobility P/M AGP 2x
-               0e11 b111  Armada M700
-               0e11 b160  Armada E500
-               1002 0084  Xpert 98 AGP 2X (Mobility)
-               1014 0154  ThinkPad A20m
-               1028 00aa  Latitude CPt
-               1028 00bb  Latitude CPx
-       4c4e  Rage Mobility L AGP 2x
-       4c50  3D Rage LT Pro
-               1002 4c50  Rage LT Pro
-       4c51  3D Rage LT Pro
-       4c52  Rage Mobility P/M
-               1033 8112  Versa Note VXi
-       4c53  Rage Mobility L
-       4c54  264LT [Mach64 LT]
-       4c57  Radeon Mobility M7 LW [Radeon Mobility 7500]
-               1014 0517  ThinkPad T30
-               1028 00e6  Radeon Mobility M7 LW (Dell Inspiron 8100)
-               1028 012a  Latitude C640
-               144d c006  Radeon Mobility M7 LW in vpr Matrix 170B4
-       4c58  Radeon RV200 LX [Mobility FireGL 7800 M7]
-       4c59  Radeon Mobility M6 LY
-               1014 0235  ThinkPad A30/A30p (2652/2653)
-               1014 0239  ThinkPad X22/X23/X24
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-       4c5a  Radeon Mobility M6 LZ
-       4c64  Radeon R250 Ld [Radeon Mobility 9000 M9]
-       4c65  Radeon R250 Le [Radeon Mobility 9000 M9]
-       4c66  Radeon R250 Lf [FireGL 9000]
-       4c67  Radeon R250 Lg [Radeon Mobility 9000 M9]
-# Secondary chip to the Lf
-       4c6e  Radeon R250 Ln [Radeon Mobility 9000 M9] [Secondary]
-       4d46  Rage Mobility M4 AGP
-       4d4c  Rage Mobility M4 AGP
-       4e44  Radeon R300 ND [Radeon 9700 Pro]
-       4e45  Radeon R300 NE [Radeon 9500 Pro]
-               1002 0002  Radeon R300 NE [Radeon 9500 Pro]
-               1681 0002  Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
-# New PCI ID provided by ATI developer relations (correction to above)
-       4e46  RV350 NF [Radeon 9600]
-       4e47  Radeon R300 NG [FireGL X1]
-# (added pro)
-       4e48  Radeon R350 [Radeon 9800 Pro]
-# New PCI ID provided by ATI developer relations
-       4e49  Radeon R350 [Radeon 9800]
-       4e4a  RV350 NJ [Radeon 9800 XT]
-       4e4b  R350 NK [Fire GL X2]
-# New PCI ID provided by ATI developer relations
-       4e50  RV350 [Mobility Radeon 9600 M10]
-               1025 005a  TravelMate 290
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1734 1055  Amilo M1420W
-       4e51  M10 NQ [Radeon Mobility 9600]
-       4e52  RV350 [Mobility Radeon 9600 M10]
-       4e53  M10 NS [Radeon Mobility 9600]
-       4e54  M10 NT [FireGL Mobility T2]
-       4e56  M11 NV [FireGL Mobility T2e]
-       4e64  Radeon R300 [Radeon 9700 Pro] (Secondary)
-       4e65  Radeon R300 [Radeon 9500 Pro] (Secondary)
-               1002 0003  Radeon R300 NE [Radeon 9500 Pro]
-               1681 0003  Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
-# New PCI ID provided by ATI developer relations (correction to above)
-       4e66  RV350 NF [Radeon 9600] (Secondary)
-       4e67  Radeon R300 [FireGL X1] (Secondary)
-# (added pro)
-       4e68  Radeon R350 [Radeon 9800 Pro] (Secondary)
-# New PCI ID provided by ATI developer relations
-       4e69  Radeon R350 [Radeon 9800] (Secondary)
-       4e6a  RV350 NJ [Radeon 9800 XT] (Secondary)
-               1002 4e71  ATI Technologies Inc M10 NQ [Radeon Mobility 9600]
-       5041  Rage 128 PA/PRO
-       5042  Rage 128 PB/PRO AGP 2x
-       5043  Rage 128 PC/PRO AGP 4x
-       5044  Rage 128 PD/PRO TMDS
-               1002 0028  Rage 128 AIW
-               1002 0029  Rage 128 AIW
-       5045  Rage 128 PE/PRO AGP 2x TMDS
-       5046  Rage 128 PF/PRO AGP 4x TMDS
-               1002 0004  Rage Fury Pro
-               1002 0008  Rage Fury Pro/Xpert 2000 Pro
-               1002 0014  Rage Fury Pro
-               1002 0018  Rage Fury Pro/Xpert 2000 Pro
-               1002 0028  Rage 128 Pro AIW AGP
-               1002 002a  Rage 128 Pro AIW AGP
-               1002 0048  Rage Fury Pro
-               1002 2000  Rage Fury MAXX AGP 4x (TMDS) (VGA device)
-               1002 2001  Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
-       5047  Rage 128 PG/PRO
-       5048  Rage 128 PH/PRO AGP 2x
-       5049  Rage 128 PI/PRO AGP 4x
-       504a  Rage 128 PJ/PRO TMDS
-       504b  Rage 128 PK/PRO AGP 2x TMDS
-       504c  Rage 128 PL/PRO AGP 4x TMDS
-       504d  Rage 128 PM/PRO
-       504e  Rage 128 PN/PRO AGP 2x
-       504f  Rage 128 PO/PRO AGP 4x
-       5050  Rage 128 PP/PRO TMDS [Xpert 128]
-               1002 0008  Xpert 128
-       5051  Rage 128 PQ/PRO AGP 2x TMDS
-       5052  Rage 128 PR/PRO AGP 4x TMDS
-       5053  Rage 128 PS/PRO
-       5054  Rage 128 PT/PRO AGP 2x
-       5055  Rage 128 PU/PRO AGP 4x
-       5056  Rage 128 PV/PRO TMDS
-       5057  Rage 128 PW/PRO AGP 2x TMDS
-       5058  Rage 128 PX/PRO AGP 4x TMDS
-       5144  Radeon R100 QD [Radeon 7200]
-               1002 0008  Radeon 7000/Radeon VE
-               1002 0009  Radeon 7000/Radeon
-               1002 000a  Radeon 7000/Radeon
-               1002 001a  Radeon 7000/Radeon
-               1002 0029  Radeon AIW
-               1002 0038  Radeon 7000/Radeon
-               1002 0039  Radeon 7000/Radeon
-               1002 008a  Radeon 7000/Radeon
-               1002 00ba  Radeon 7000/Radeon
-               1002 0139  Radeon 7000/Radeon
-               1002 028a  Radeon 7000/Radeon
-               1002 02aa  Radeon AIW
-               1002 053a  Radeon 7000/Radeon
-       5145  Radeon R100 QE
-       5146  Radeon R100 QF
-       5147  Radeon R100 QG
-       5148  Radeon R200 QH [Radeon 8500]
-               1002 010a  FireGL 8800 64Mb
-               1002 0152  FireGL 8800 128Mb
-               1002 0162  FireGL 8700 32Mb
-               1002 0172  FireGL 8700 64Mb
-       5149  Radeon R200 QI
-       514a  Radeon R200 QJ
-       514b  Radeon R200 QK
-       514c  Radeon R200 QL [Radeon 8500 LE]
-               1002 003a  Radeon R200 QL [Radeon 8500 LE]
-               1002 013a  Radeon 8500
-               148c 2026  R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
-               1681 0010  Radeon 8500 [3D Prophet 8500 128Mb]
-               174b 7149  Radeon R200 QL [Sapphire Radeon 8500 LE]
-       514d  Radeon R200 QM [Radeon 9100]
-       514e  Radeon R200 QN [Radeon 8500LE]
-       514f  Radeon R200 QO [Radeon 8500LE]
-       5154  R200 QT [Radeon 8500]
-       5155  R200 QU [Radeon 9100]
-       5157  Radeon RV200 QW [Radeon 7500]
-               1002 013a  Radeon 7500
-               1002 103a  Dell Optiplex GX260
-               1458 4000  RV200 QW [RADEON 7500 PRO MAYA AR]
-               148c 2024  RV200 QW [Radeon 7500LE Dual Display]
-               148c 2025  RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
-               148c 2036  RV200 QW [Radeon 7500 PCI Dual Display]
-               174b 7146  RV200 QW [Radeon 7500 LE]
-               174b 7147  RV200 QW [Sapphire Radeon 7500LE]
-               174b 7161  Radeon RV200 QW [Radeon 7500 LE]
-               17af 0202  RV200 QW [Excalibur Radeon 7500LE]
-       5158  Radeon RV200 QX [Radeon 7500]
-       5159  Radeon RV100 QY [Radeon 7000/VE]
-               1002 000a  Radeon 7000/Radeon VE
-               1002 000b  Radeon 7000
-               1002 0038  Radeon 7000/Radeon VE
-               1002 003a  Radeon 7000/Radeon VE
-               1002 00ba  Radeon 7000/Radeon VE
-               1002 013a  Radeon 7000/Radeon VE
-               1458 4002  RV100 QY [RADEON 7000 PRO MAYA AV Series]
-               148c 2003  RV100 QY [Radeon 7000 Multi-Display Edition]
-               148c 2023  RV100 QY [Radeon 7000 Evil Master Multi-Display]
-               174b 7112  RV100 QY [Sapphire Radeon VE 7000]
-               174b 7c28  Sapphire Radeon VE 7000 DDR
-               1787 0202  RV100 QY [Excalibur Radeon 7000]
-       515a  Radeon RV100 QZ [Radeon 7000/VE]
-       5168  Radeon R200 Qh
-       5169  Radeon R200 Qi
-       516a  Radeon R200 Qj
-       516b  Radeon R200 Qk
-# This one is not in ATI documentation, but is in XFree86 source code
-       516c  Radeon R200 Ql
-       5245  Rage 128 RE/SG
-               1002 0008  Xpert 128
-               1002 0028  Rage 128 AIW
-               1002 0029  Rage 128 AIW
-               1002 0068  Rage 128 AIW
-       5246  Rage 128 RF/SG AGP
-               1002 0004  Magnum/Xpert 128/Xpert 99
-               1002 0008  Magnum/Xpert128/X99/Xpert2000
-               1002 0028  Rage 128 AIW AGP
-               1002 0044  Rage Fury/Xpert 128/Xpert 2000
-               1002 0068  Rage 128 AIW AGP
-               1002 0448  Rage Fury
-       5247  Rage 128 RG
-       524b  Rage 128 RK/VR
-       524c  Rage 128 RL/VR AGP
-               1002 0008  Xpert 99/Xpert 2000
-               1002 0088  Xpert 99
-       5345  Rage 128 SE/4x
-       5346  Rage 128 SF/4x AGP 2x
-               1002 0048  RAGE 128 16MB VGA TVOUT AMC PAL
-       5347  Rage 128 SG/4x AGP 4x
-       5348  Rage 128 SH
-       534b  Rage 128 SK/4x
-       534c  Rage 128 SL/4x AGP 2x
-       534d  Rage 128 SM/4x AGP 4x
-               1002 0008  Xpert 99/Xpert 2000
-               1002 0018  Xpert 2000
-       534e  Rage 128 4x
-       5354  Mach 64 VT
-               1002 5654  Mach 64 reference
-       5446  Rage 128 Pro Ultra TF
-               1002 0004  Rage Fury Pro
-               1002 0008  Rage Fury Pro/Xpert 2000 Pro
-               1002 0018  Rage Fury Pro/Xpert 2000 Pro
-               1002 0028  Rage 128 AIW Pro AGP
-               1002 0029  Rage 128 AIW
-               1002 002a  Rage 128 AIW Pro AGP
-               1002 002b  Rage 128 AIW
-               1002 0048  Xpert 2000 Pro
-       544c  Rage 128 Pro Ultra TL
-       5452  Rage 128 Pro Ultra TR
-               1002 001c  Rage 128 Pro 4XL
-               103c 1279  Rage 128 Pro 4XL
-       5453  Rage 128 Pro Ultra TS
-       5454  Rage 128 Pro Ultra TT
-       5455  Rage 128 Pro Ultra TU
-       5460  M22 [Radeon Mobility M300]
-       5464  M22 [FireGL GL]
-       5548  R423 UH [Radeon X800 (PCIE)]
-       5549  R423 UI [Radeon X800PRO (PCIE)]
-       554a  R423 UJ [Radeon X800LE (PCIE)]
-       554b  R423 UK [Radeon X800SE (PCIE)]
-       5551  R423 UQ [FireGL V7200 (PCIE)]
-       5552  R423 UR [FireGL V5100 (PCIE)]
-       5554  R423 UT [FireGL V7100 (PCIE)]
-       556b  Radeon R423 UK (PCIE) [X800 SE] (Secondary)
-       5654  264VT [Mach64 VT]
-               1002 5654  Mach64VT Reference
-       5655  264VT3 [Mach64 VT3]
-       5656  264VT4 [Mach64 VT4]
-       5830  RS300 Host Bridge
-       5831  RS300 Host Bridge
-       5832  RS300 Host Bridge
-       5833  Radeon 9100 IGP Host Bridge
-       5834  Radeon 9100 IGP
-       5835  RS300M AGP [Radeon Mobility 9100IGP]
-       5838  Radeon 9100 IGP AGP Bridge
-       5941  RV280 [Radeon 9200] (Secondary)
-               1458 4019  Gigabyte Radeon 9200
-               174b 7c12  Sapphire Radeon 9200
-# http://www.hightech.com.hk/html/9200.htm
-               17af 200d  Excalibur Radeon 9200
-               18bc 0050  GeXcube GC-R9200-C3 (Secondary)
-       5944  RV280 [Radeon 9200 SE (PCI)]
-       5960  RV280 [Radeon 9200 PRO]
-       5961  RV280 [Radeon 9200]
-               1002 2f72  All-in-Wonder 9200 Series
-               1019 4c30  Radeon 9200 VIVO
-               12ab 5961  YUAN SMARTVGA Radeon 9200
-               1458 4018  Gigabyte Radeon 9200
-               174b 7c13  Sapphire Radeon 9200
-# http://www.hightech.com.hk/html/9200.htm
-               17af 200c  Excalibur Radeon 9200
-               18bc 0050  Radeon 9200 Game Buster
-               18bc 0051  GeXcube GC-R9200-C3
-               18bc 0053  Radeon 9200 Game Buster VIVO
-       5962  RV280 [Radeon 9200]
-       5964  RV280 [Radeon 9200 SE]
-               1043 c006  ASUS Radeon 9200 SE / TD / 128M
-               1458 4018  Radeon 9200 SE
-               148c 2073  CN-AG92E
-               174b 7c13  Sapphire Radeon 9200 SE
-               1787 5964  Excalibur 9200SE VIVO 128M
-               17af 2012  Radeon 9200 SE Excalibur
-               18bc 0170  Sapphire Radeon 9200 SE 128MB Game Buster
-# 128MB DDR, DVI/VGA/TV out
-               18bc 0173  GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
-       5b60  RV370 5B60 [Radeon X300 (PCIE)]
-               1043 002a  Extreme AX300SE-X
-               1043 032e  Extreme AX300/TD
-       5b62  RV370 5B62 [Radeon X600 (PCIE)]
-       5b64  RV370 5B64 [FireGL V3100 (PCIE)]
-       5b65  RV370 5B65 [FireGL D1100 (PCIE)]
-       5c61  M9+ 5C61 [Radeon Mobility 9200 (AGP)]
-       5c63  M9+ 5C63 [Radeon Mobility 9200 (AGP)]
-       5d44  RV280 [Radeon 9200 SE] (Secondary)
-               1458 4019  Radeon 9200 SE (Secondary)
-               174b 7c12  Sapphire Radeon 9200 SE (Secondary)
-               1787 5965  Excalibur 9200SE VIVO 128M (Secondary)
-               17af 2013  Radeon 9200 SE Excalibur (Secondary)
-               18bc 0171  Radeon 9200 SE 128MB Game Buster (Secondary)
-               18bc 0172  GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
-       5d4d  R480 [Radeon X850XT Platinum]
-       5d57  R423 5F57 [Radeon X800XT (PCIE)]
-       700f  PCI Bridge [IGP 320M]
-       7010  PCI Bridge [IGP 340M]
-       7834  Radeon 9100 PRO IGP
-       7835  Radeon Mobility 9200 IGP
-       7c37  RV350 AQ [Radeon 9600 SE]
-       cab0  AGP Bridge [IGP 320M]
-       cab2  RS200/RS200M AGP Bridge [IGP 340M]
-       cbb2  RS200/RS200M AGP Bridge [IGP 340M]
-1003  ULSI Systems
-       0201  US201
-1004  VLSI Technology Inc
-       0005  82C592-FC1
-       0006  82C593-FC1
-       0007  82C594-AFC2
-       0008  82C596/7 [Wildcat]
-       0009  82C597-AFC2
-       000c  82C541 [Lynx]
-       000d  82C543 [Lynx]
-       0101  82C532
-       0102  82C534 [Eagle]
-       0103  82C538
-       0104  82C535
-       0105  82C147
-       0200  82C975
-       0280  82C925
-       0304  QSound ThunderBird PCI Audio
-               1004 0304  QSound ThunderBird PCI Audio
-               122d 1206  DSP368 Audio
-               1483 5020  XWave Thunder 3D Audio
-       0305  QSound ThunderBird PCI Audio Gameport
-               1004 0305  QSound ThunderBird PCI Audio Gameport
-               122d 1207  DSP368 Audio Gameport
-               1483 5021  XWave Thunder 3D Audio Gameport
-       0306  QSound ThunderBird PCI Audio Support Registers
-               1004 0306  QSound ThunderBird PCI Audio Support Registers
-               122d 1208  DSP368 Audio Support Registers
-               1483 5022  XWave Thunder 3D Audio Support Registers
-       0307  Thunderbird
-       0308  Thunderbird
-       0702  VAS96011 [Golden Gate II]
-       0703  Tollgate
-1005  Avance Logic Inc. [ALI]
-       2064  ALG2032/2064
-       2128  ALG2364A
-       2301  ALG2301
-       2302  ALG2302
-       2364  ALG2364
-       2464  ALG2364A
-       2501  ALG2564A/25128A
-1006  Reply Group
-1007  NetFrame Systems Inc
-1008  Epson
-100a  Phoenix Technologies
-100b  National Semiconductor Corporation
-       0001  DP83810
-       0002  87415/87560 IDE
-       000e  87560 Legacy I/O
-       000f  FireWire Controller
-       0011  NS87560 National PCI System I/O
-       0012  USB Controller
-       0020  DP83815 (MacPhyter) Ethernet Controller
-               103c 0024  Pavilion ze4400 builtin Network
-               1385 f311  FA311 / FA312 (FA311 with WoL HW)
-       0022  DP83820 10/100/1000 Ethernet Controller
-       0028  Geode GX2 Host Bridge
-       002a  CS5535 South Bridge
-       002b  CS5535 ISA bridge
-       002d  CS5535 IDE
-       002e  CS5535 Audio
-       002f  CS5535 USB
-       0030  Geode GX2 Graphics Processor
-       0035  DP83065 [Saturn] 10/100/1000 Ethernet Controller
-       0500  SCx200 Bridge
-       0501  SCx200 SMI
-       0502  SCx200 IDE
-       0503  SCx200 Audio
-       0504  SCx200 Video
-       0505  SCx200 XBus
-       0510  SC1100 Bridge
-       0511  SC1100 SMI
-       0515  SC1100 XBus
-       d001  87410 IDE
-100c  Tseng Labs Inc
-       3202  ET4000/W32p rev A
-       3205  ET4000/W32p rev B
-       3206  ET4000/W32p rev C
-       3207  ET4000/W32p rev D
-       3208  ET6000
-       4702  ET6300
-100d  AST Research Inc
-100e  Weitek
-       9000  P9000 Viper
-       9001  P9000 Viper
-       9002  P9000 Viper
-       9100  P9100 Viper Pro/SE
-1010  Video Logic, Ltd.
-1011  Digital Equipment Corporation
-       0001  DECchip 21050
-       0002  DECchip 21040 [Tulip]
-       0004  DECchip 21030 [TGA]
-       0007  NVRAM [Zephyr NVRAM]
-       0008  KZPSA [KZPSA]
-       0009  DECchip 21140 [FasterNet]
-               1025 0310  21140 Fast Ethernet
-               10b8 2001  SMC9332BDT EtherPower 10/100
-               10b8 2002  SMC9332BVT EtherPower T4 10/100
-               10b8 2003  SMC9334BDT EtherPower 10/100 (1-port)
-               1109 2400  ANA-6944A/TX Fast Ethernet
-               1112 2300  RNS2300 Fast Ethernet
-               1112 2320  RNS2320 Fast Ethernet
-               1112 2340  RNS2340 Fast Ethernet
-               1113 1207  EN-1207-TX Fast Ethernet
-               1186 1100  DFE-500TX Fast Ethernet
-               1186 1112  DFE-570TX Fast Ethernet
-               1186 1140  DFE-660 Cardbus Ethernet 10/100
-               1186 1142  DFE-660 Cardbus Ethernet 10/100
-               11f6 0503  Freedomline Fast Ethernet
-               1282 9100  AEF-380TXD Fast Ethernet
-               1385 1100  FA310TX Fast Ethernet
-               2646 0001  KNE100TX Fast Ethernet
-       000a  21230 Video Codec
-       000d  PBXGB [TGA2]
-       000f  DEFPA
-       0014  DECchip 21041 [Tulip Pass 3]
-               1186 0100  DE-530+
-       0016  DGLPB [OPPO]
-       0017  PV-PCI Graphics Controller (ZLXp-L)
-       0019  DECchip 21142/43
-               1011 500a  DE500A Fast Ethernet
-               1011 500b  DE500B Fast Ethernet
-               1014 0001  10/100 EtherJet Cardbus
-               1025 0315  ALN315 Fast Ethernet
-               1033 800c  PC-9821-CS01 100BASE-TX Interface Card
-               1033 800d  PC-9821NR-B06 100BASE-TX Interface Card
-               108d 0016  Rapidfire 2327 10/100 Ethernet
-               108d 0017  GoCard 2250 Ethernet 10/100 Cardbus
-               10b8 2005  SMC8032DT Extreme Ethernet 10/100
-               10b8 8034  SMC8034 Extreme Ethernet 10/100
-               10ef 8169  Cardbus Fast Ethernet
-               1109 2a00  ANA-6911A/TX Fast Ethernet
-               1109 2b00  ANA-6911A/TXC Fast Ethernet
-               1109 3000  ANA-6922/TX Fast Ethernet
-               1113 1207  Cheetah Fast Ethernet
-               1113 2220  Cardbus Fast Ethernet
-               115d 0002  Cardbus Ethernet 10/100
-               1179 0203  Fast Ethernet
-               1179 0204  Cardbus Fast Ethernet
-               1186 1100  DFE-500TX Fast Ethernet
-               1186 1101  DFE-500TX Fast Ethernet
-               1186 1102  DFE-500TX Fast Ethernet
-               1186 1112  DFE-570TX Quad Fast Ethernet
-               1259 2800  AT-2800Tx Fast Ethernet
-               1266 0004  Eagle Fast EtherMAX
-               12af 0019  NetFlyer Cardbus Fast Ethernet
-               1374 0001  Cardbus Ethernet Card 10/100
-               1374 0002  Cardbus Ethernet Card 10/100
-               1374 0007  Cardbus Ethernet Card 10/100
-               1374 0008  Cardbus Ethernet Card 10/100
-               1385 2100  FA510
-               1395 0001  10/100 Ethernet CardBus PC Card
-               13d1 ab01  EtherFast 10/100 Cardbus (PCMPC200)
-               14cb 0100  LNDL-100N 100Base-TX Ethernet PC Card
-               8086 0001  EtherExpress PRO/100 Mobile CardBus 32
-       001a  Farallon PN9000SX Gigabit Ethernet
-       0021  DECchip 21052
-       0022  DECchip 21150
-       0023  DECchip 21150
-       0024  DECchip 21152
-       0025  DECchip 21153
-       0026  DECchip 21154
-       0034  56k Modem Cardbus
-               1374 0003  56k Modem Cardbus
-       0045  DECchip 21553
-       0046  DECchip 21554
-               0e11 4050  Integrated Smart Array
-               0e11 4051  Integrated Smart Array
-               0e11 4058  Integrated Smart Array
-               103c 10c2  Hewlett-Packard NetRAID-4M
-               12d9 000a  IP Telephony card
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-               9005 0364  5400S (Mustang)
-               9005 0365  5400S (Mustang)
-               9005 1364  Dell PowerEdge RAID Controller 2
-               9005 1365  Dell PowerEdge RAID Controller 2
-               e4bf 1000  CC8-1-BLUES
-       1065  StrongARM DC21285
-               1069 0020  DAC960P / DAC1164P
-1012  Micronics Computers Inc
-1013  Cirrus Logic
-       0038  GD 7548
-       0040  GD 7555 Flat Panel GUI Accelerator
-       004c  GD 7556 Video/Graphics LCD/CRT Ctrlr
-       00a0  GD 5430/40 [Alpine]
-       00a2  GD 5432 [Alpine]
-       00a4  GD 5434-4 [Alpine]
-       00a8  GD 5434-8 [Alpine]
-       00ac  GD 5436 [Alpine]
-       00b0  GD 5440
-       00b8  GD 5446
-       00bc  GD 5480
-               1013 00bc  CL-GD5480
-       00d0  GD 5462
-       00d2  GD 5462 [Laguna I]
-       00d4  GD 5464 [Laguna]
-       00d5  GD 5464 BD [Laguna]
-       00d6  GD 5465 [Laguna]
-               13ce 8031  Barco Metheus 2 Megapixel, Dual Head
-               13cf 8031  Barco Metheus 2 Megapixel, Dual Head
-       00e8  GD 5436U
-       1100  CL 6729
-       1110  PD 6832 PCMCIA/CardBus Ctrlr
-       1112  PD 6834 PCMCIA/CardBus Ctrlr
-       1113  PD 6833 PCMCIA/CardBus Ctrlr
-       1200  GD 7542 [Nordic]
-       1202  GD 7543 [Viking]
-       1204  GD 7541 [Nordic Light]
-       4000  MD 5620 [CLM Data Fax Voice]
-       4400  CD 4400
-       6001  CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
-               1014 1010  CS4610 SoundFusion Audio Accelerator
-       6003  CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
-               1013 4280  Crystal SoundFusion PCI Audio Accelerator
-               153b 1136  SiXPack 5.1+
-               1681 0050  Game Theater XP
-               1681 a011  Fortissimo III 7.1
-       6004  CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
-       6005  Crystal CS4281 PCI Audio
-               1013 4281  Crystal CS4281 PCI Audio
-               10cf 10a8  Crystal CS4281 PCI Audio
-               10cf 10a9  Crystal CS4281 PCI Audio
-               10cf 10aa  Crystal CS4281 PCI Audio
-               10cf 10ab  Crystal CS4281 PCI Audio
-               10cf 10ac  Crystal CS4281 PCI Audio
-               10cf 10ad  Crystal CS4281 PCI Audio
-               10cf 10b4  Crystal CS4281 PCI Audio
-               1179 0001  Crystal CS4281 PCI Audio
-               14c0 000c  Crystal CS4281 PCI Audio
-1014  IBM
-       0002  PCI to MCA Bridge
-       0005  Alta Lite
-       0007  Alta MP
-       000a  Fire Coral
-       0017  CPU to PCI Bridge
-       0018  TR Auto LANstreamer
-       001b  GXT-150P
-       001c  Carrera
-       001d  82G2675
-       0020  GXT1000 Graphics Adapter
-       0022  IBM27-82351
-       002d  Python
-# [official name in AIX 5]
-       002e  SCSI RAID Adapter [ServeRAID]
-               1014 002e  ServeRAID-3x
-               1014 022e  ServeRAID-4H
-       0031  2 Port Serial Adapter
-# AS400 iSeries PCI sync serial card
-               1014 0031  2721 WAN IOA - 2 Port Sync Serial Adapter
-       0036  Miami
-       0037  82660 CPU to PCI Bridge
-       003a  CPU to PCI Bridge
-       003c  GXT250P/GXT255P Graphics Adapter
-       003e  16/4 Token ring UTP/STP controller
-               1014 003e  Token-Ring Adapter
-               1014 00cd  Token-Ring Adapter + Wake-On-LAN
-               1014 00ce  16/4 Token-Ring Adapter 2
-               1014 00cf  16/4 Token-Ring Adapter Special
-               1014 00e4  High-Speed 100/16/4 Token-Ring Adapter
-               1014 00e5  16/4 Token-Ring Adapter 2 + Wake-On-LAN
-               1014 016d  iSeries 2744 Card
-       0045  SSA Adapter
-       0046  MPIC interrupt controller
-       0047  PCI to PCI Bridge
-       0048  PCI to PCI Bridge
-       0049  Warhead SCSI Controller
-       004e  ATM Controller (14104e00)
-       004f  ATM Controller (14104f00)
-       0050  ATM Controller (14105000)
-       0053  25 MBit ATM Controller
-       0054  GXT500P/GXT550P Graphics Adapter
-       0057  MPEG PCI Bridge
-       005c  i82557B 10/100
-       005e  GXT800P Graphics Adapter
-       007c  ATM Controller (14107c00)
-       007d  3780IDSP [MWave]
-       008b  EADS PCI to PCI Bridge
-       008e  GXT3000P Graphics Adapter
-       0090  GXT 3000P
-               1014 008e  GXT-3000P
-       0091  SSA Adapter
-       0095  20H2999 PCI Docking Bridge
-       0096  Chukar chipset SCSI controller
-               1014 0097  iSeries 2778 DASD IOA
-               1014 0098  iSeries 2763 DASD IOA
-               1014 0099  iSeries 2748 DASD IOA
-       009f  PCI 4758 Cryptographic Accelerator
-       00a5  ATM Controller (1410a500)
-       00a6  ATM 155MBPS MM Controller (1410a600)
-       00b7  256-bit Graphics Rasterizer [Fire GL1]
-               1092 00b8  FireGL1 AGP 32Mb
-       00b8  GXT2000P Graphics Adapter
-       00be  ATM 622MBPS Controller (1410be00)
-       00dc  Advanced Systems Management Adapter (ASMA)
-       00fc  CPC710 Dual Bridge and Memory Controller (PCI-64)
-       0104  Gigabit Ethernet-SX Adapter
-       0105  CPC710 Dual Bridge and Memory Controller (PCI-32)
-       010f  Remote Supervisor Adapter (RSA)
-       0142  Yotta Video Compositor Input
-               1014 0143  Yotta Input Controller (ytin)
-       0144  Yotta Video Compositor Output
-               1014 0145  Yotta Output Controller (ytout)
-       0156  405GP PLB to PCI Bridge
-       015e  622Mbps ATM PCI Adapter
-       0160  64bit/66MHz PCI ATM 155 MMF
-       016e  GXT4000P Graphics Adapter
-       0170  GXT6000P Graphics Adapter
-       017d  GXT300P Graphics Adapter
-       0180  Snipe chipset SCSI controller
-               1014 0241  iSeries 2757 DASD IOA
-               1014 0264  Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
-       0188  EADS-X PCI-X to PCI-X Bridge
-       01a7  PCI-X to PCI-X Bridge
-       01bd  ServeRAID Controller
-               1014 01be  ServeRAID-4M
-               1014 01bf  ServeRAID-4L
-               1014 0208  ServeRAID-4Mx
-               1014 020e  ServeRAID-4Lx
-               1014 022e  ServeRAID-4H
-               1014 0258  ServeRAID-5i
-               1014 0259  ServeRAID-5i
-       01c1  64bit/66MHz PCI ATM 155 UTP
-       01e6  Cryptographic Accelerator
-       01ff  10/100 Mbps Ethernet
-       0219  Multiport Serial Adapter
-               1014 021a  Dual RVX
-               1014 0251  Internal Modem/RVX
-               1014 0252  Quad Internal Modem
-       021b  GXT6500P Graphics Adapter
-       021c  GXT4500P Graphics Adapter
-       0233  GXT135P Graphics Adapter
-       0266  PCI-X Dual Channel SCSI
-       0268  Gigabit Ethernet-SX Adapter (PCI-X)
-       0269  10/100/1000 Base-TX Ethernet Adapter (PCI-X)
-       028c  Citrine chipset SCSI controller
-               1014 028D  Dual Channel PCI-X DDR SAS RAID Adapter (572E)
-               1014 02BE  Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
-               1014 02C0  Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
-       0302  X-Architecture Bridge [Summit]
-       0314  ZISC 036 Neural accelerator card
-       ffff  MPIC-2 interrupt controller
-1015  LSI Logic Corp of Canada
-1016  ICL Personal Systems
-1017  SPEA Software AG
-       5343  SPEA 3D Accelerator
-1018  Unisys Systems
-1019  Elitegroup Computer Systems
-101a  AT&T GIS (NCR)
-       0005  100VG ethernet
-101b  Vitesse Semiconductor
-101c  Western Digital
-       0193  33C193A
-       0196  33C196A
-       0197  33C197A
-       0296  33C296A
-       3193  7193
-       3197  7197
-       3296  33C296A
-       4296  34C296
-       9710  Pipeline 9710
-       9712  Pipeline 9712
-       c24a  90C
-101e  American Megatrends Inc.
-       1960  MegaRAID
-               101e 0471  MegaRAID 471 Enterprise 1600 RAID Controller
-               101e 0475  MegaRAID 475 Express 500/500LC RAID Controller
-               101e 0477  MegaRAID 477 Elite 3100 RAID Controller
-               101e 0493  MegaRAID 493 Elite 1600 RAID Controller
-               101e 0494  MegaRAID 494 Elite 1650 RAID Controller
-               101e 0503  MegaRAID 503 Enterprise 1650 RAID Controller
-               101e 0511  MegaRAID 511 i4 IDE RAID Controller
-               101e 0522  MegaRAID 522 i4133 RAID Controller
-               1028 0471  PowerEdge RAID Controller 3/QC
-               1028 0475  PowerEdge RAID Controller 3/SC
-               1028 0493  PowerEdge RAID Controller 3/DC
-               1028 0511  PowerEdge Cost Effective RAID Controller ATA100/4Ch
-       9010  MegaRAID 428 Ultra RAID Controller
-       9030  EIDE Controller
-       9031  EIDE Controller
-       9032  EIDE & SCSI Controller
-       9033  SCSI Controller
-       9040  Multimedia card
-       9060  MegaRAID 434 Ultra GT RAID Controller
-       9063  MegaRAC
-               101e 0767  Dell Remote Assistant Card 2
-101f  PictureTel
-1020  Hitachi Computer Products
-1021  OKI Electric Industry Co. Ltd.
-1022  Advanced Micro Devices [AMD]
-       1100  K8 [Athlon64/Opteron] HyperTransport Technology Configuration
-       1101  K8 [Athlon64/Opteron] Address Map
-       1102  K8 [Athlon64/Opteron] DRAM Controller
-       1103  K8 [Athlon64/Opteron] Miscellaneous Control
-       2000  79c970 [PCnet32 LANCE]
-               1014 2000  NetFinity 10/100 Fast Ethernet
-               1022 2000  PCnet - Fast 79C971
-               103c 104c  Ethernet with LAN remote power Adapter
-               103c 1064  Ethernet with LAN remote power Adapter
-               103c 1065  Ethernet with LAN remote power Adapter
-               103c 106c  Ethernet with LAN remote power Adapter
-               103c 106e  Ethernet with LAN remote power Adapter
-               103c 10ea  Ethernet with LAN remote power Adapter
-               1113 1220  EN1220 10/100 Fast Ethernet
-               1259 2450  AT-2450 10/100 Fast Ethernet
-               1259 2454  AT-2450v4 10Mb Ethernet Adapter
-               1259 2700  AT-2700TX 10/100 Fast Ethernet
-               1259 2701  AT-2700FX 100Mb Ethernet
-               4c53 1000  CC7/CR7/CP7/VC7/VP7/VR7 mainboard
-               4c53 1010  CP5/CR6 mainboard
-               4c53 1020  VR6 mainboard
-               4c53 1030  PC5 mainboard
-               4c53 1040  CL7 mainboard
-               4c53 1060  PC7 mainboard
-       2001  79c978 [HomePNA]
-               1092 0a78  Multimedia Home Network Adapter
-               1668 0299  ActionLink Home Network Adapter
-       2003  Am 1771 MBW [Alchemy]
-       2020  53c974 [PCscsi]
-       2040  79c974
-       3000  ELanSC520 Microcontroller
-       7006  AMD-751 [Irongate] System Controller
-       7007  AMD-751 [Irongate] AGP Bridge
-       700a  AMD-IGR4 AGP Host to PCI Bridge
-       700b  AMD-IGR4 PCI to PCI Bridge
-       700c  AMD-760 MP [IGD4-2P] System Controller
-       700d  AMD-760 MP [IGD4-2P] AGP Bridge
-       700e  AMD-760 [IGD4-1P] System Controller
-       700f  AMD-760 [IGD4-1P] AGP Bridge
-       7400  AMD-755 [Cobra] ISA
-       7401  AMD-755 [Cobra] IDE
-       7403  AMD-755 [Cobra] ACPI
-       7404  AMD-755 [Cobra] USB
-       7408  AMD-756 [Viper] ISA
-       7409  AMD-756 [Viper] IDE
-       740b  AMD-756 [Viper] ACPI
-       740c  AMD-756 [Viper] USB
-       7410  AMD-766 [ViperPlus] ISA
-       7411  AMD-766 [ViperPlus] IDE
-       7413  AMD-766 [ViperPlus] ACPI
-       7414  AMD-766 [ViperPlus] USB
-       7440  AMD-768 [Opus] ISA
-               1043 8044  A7M-D Mainboard
-       7441  AMD-768 [Opus] IDE
-       7443  AMD-768 [Opus] ACPI
-               1043 8044  A7M-D Mainboard
-       7445  AMD-768 [Opus] Audio
-       7446  AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible)
-       7448  AMD-768 [Opus] PCI
-       7449  AMD-768 [Opus] USB
-       7450  AMD-8131 PCI-X Bridge
-       7451  AMD-8131 PCI-X APIC
-       7454  AMD-8151 System Controller
-       7455  AMD-8151 AGP Bridge
-       7460  AMD-8111 PCI
-               161f 3017  HDAMB
-       7461  AMD-8111 USB
-       7462  AMD-8111 Ethernet
-       7464  AMD-8111 USB
-               161f 3017  HDAMB
-       7468  AMD-8111 LPC
-               161f 3017  HDAMB
-       7469  AMD-8111 IDE
-               161f 3017  HDAMB
-       746a  AMD-8111 SMBus 2.0
-       746b  AMD-8111 ACPI
-               161f 3017  HDAMB
-       746d  AMD-8111 AC97 Audio
-               161f 3017  HDAMB
-       746e  AMD-8111 MC97 Modem
-       756b  AMD-8111 ACPI
-1023  Trident Microsystems
-       0194  82C194
-       2000  4DWave DX
-       2001  4DWave NX
-               122d 1400  Trident PCI288-Q3DII (NX)
-       2100  CyberBlade XP4m32
-       2200  XGI Volari XP5
-       8400  CyberBlade/i7
-               1023 8400  CyberBlade i7 AGP
-       8420  CyberBlade/i7d
-               0e11 b15a  CyberBlade i7 AGP
-       8500  CyberBlade/i1
-       8520  CyberBlade i1
-               0e11 b16e  CyberBlade i1 AGP
-               1023 8520  CyberBlade i1 AGP
-       8620  CyberBlade/i1
-               1014 0502  ThinkPad R30/T30
-       8820  CyberBlade XPAi1
-       9320  TGUI 9320
-       9350  GUI Accelerator
-       9360  Flat panel GUI Accelerator
-       9382  Cyber 9382 [Reference design]
-       9383  Cyber 9383 [Reference design]
-       9385  Cyber 9385 [Reference design]
-       9386  Cyber 9386
-       9388  Cyber 9388
-       9397  Cyber 9397
-       939a  Cyber 9397DVD
-       9420  TGUI 9420
-       9430  TGUI 9430
-       9440  TGUI 9440
-       9460  TGUI 9460
-       9470  TGUI 9470
-       9520  Cyber 9520
-       9525  Cyber 9525
-               10cf 1094  Lifebook C6155
-       9540  Cyber 9540
-       9660  TGUI 9660/938x/968x
-       9680  TGUI 9680
-       9682  TGUI 9682
-       9683  TGUI 9683
-       9685  ProVIDIA 9685
-       9750  3DImage 9750
-               1014 9750  3DImage 9750
-               1023 9750  3DImage 9750
-       9753  TGUI 9753
-       9754  TGUI 9754
-       9759  TGUI 975
-       9783  TGUI 9783
-       9785  TGUI 9785
-       9850  3DImage 9850
-       9880  Blade 3D PCI/AGP
-               1023 9880  Blade 3D
-       9910  CyberBlade/XP
-       9930  CyberBlade/XPm
-1024  Zenith Data Systems
-1025  Acer Incorporated [ALI]
-       1435  M1435
-       1445  M1445
-       1449  M1449
-       1451  M1451
-       1461  M1461
-       1489  M1489
-       1511  M1511
-       1512  ALI M1512 Aladdin
-       1513  M1513
-       1521  ALI M1521 Aladdin III CPU Bridge
-               10b9 1521  ALI M1521 Aladdin III CPU Bridge
-       1523  ALI M1523 ISA Bridge
-               10b9 1523  ALI M1523 ISA Bridge
-       1531  M1531 Northbridge [Aladdin IV/IV+]
-       1533  M1533 PCI-to-ISA Bridge
-               10b9 1533  ALI M1533 Aladdin IV/V ISA South Bridge
-       1535  M1535 PCI Bridge + Super I/O + FIR
-       1541  M1541 Northbridge [Aladdin V]
-               10b9 1541  ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
-       1542  M1542 Northbridge [Aladdin V]
-       1543  M1543 PCI-to-ISA Bridge + Super I/O + FIR
-       1561  M1561 Northbridge [Aladdin 7]
-       1621  M1621 Northbridge [Aladdin-Pro II]
-       1631  M1631 Northbridge+3D Graphics [Aladdin TNT2]
-       1641  M1641 Northbridge [Aladdin-Pro IV]
-       1647  M1647 [MaGiK1] PCI North Bridge
-       1671  M1671 Northbridge [ALADDiN-P4]
-       1672  Northbridge [CyberALADDiN-P4]
-       3141  M3141
-       3143  M3143
-       3145  M3145
-       3147  M3147
-       3149  M3149
-       3151  M3151
-       3307  M3307 MPEG-I Video Controller
-       3309  M3309 MPEG-II Video w/ Software Audio Decoder
-       3321  M3321 MPEG-II Audio/Video Decoder
-       5212  M4803
-       5215  ALI PCI EIDE Controller
-       5217  M5217H
-       5219  M5219
-       5225  M5225
-       5229  M5229
-       5235  M5235
-       5237  M5237 PCI USB Host Controller
-       5240  EIDE Controller
-       5241  PCMCIA Bridge
-       5242  General Purpose Controller
-       5243  PCI to PCI Bridge Controller
-       5244  Floppy Disk Controller
-       5247  M1541 PCI to PCI Bridge
-       5251  M5251 P1394 Controller
-       5427  PCI to AGP Bridge
-       5451  M5451 PCI AC-Link Controller Audio Device
-       5453  M5453 PCI AC-Link Controller Modem Device
-       7101  M7101 PCI PMU Power Management Controller
-               10b9 7101  M7101 PCI PMU Power Management Controller
-1028  Dell
-       0001  PowerEdge Expandable RAID Controller 2/Si
-               1028 0001  PowerEdge 2400
-       0002  PowerEdge Expandable RAID Controller 3/Di
-               1028 0002  PowerEdge 4400
-       0003  PowerEdge Expandable RAID Controller 3/Si
-               1028 0003  PowerEdge 2450
-       0006  PowerEdge Expandable RAID Controller 3/Di
-       0007  Remote Access Card III
-       0008  Remote Access Card III
-       0009  Remote Access Card III: BMC/SMIC device not present
-       000a  PowerEdge Expandable RAID Controller 3/Di
-       000c  Embedded Remote Access or ERA/O
-       000d  Embedded Remote Access: BMC/SMIC device
-       000e  PowerEdge Expandable RAID controller 4/Di
-       000f  PowerEdge Expandable RAID controller 4/Di
-       0010  Remote Access Card 4
-       0011  Remote Access Card 4 Daughter Card
-       0012  Remote Access Card 4 Daughter Card Virtual UART
-       0013  PowerEdge Expandable RAID controller 4
-               1028 016c  PowerEdge Expandable RAID Controller 4e/Si
-               1028 016d  PowerEdge Expandable RAID Controller 4e/Di
-               1028 016e  PowerEdge Expandable RAID Controller 4e/Di
-               1028 016f  PowerEdge Expandable RAID Controller 4e/Di
-               1028 0170  PowerEdge Expandable RAID Controller 4e/Di
-       0014  Remote Access Card 4 Daughter Card SMIC interface
-1029  Siemens Nixdorf IS
-102a  LSI Logic
-       0000  HYDRA
-       0010  ASPEN
-       001f  AHA-2940U2/U2W /7890/7891 SCSI Controllers
-               9005 000f  2940U2W SCSI Controller
-               9005 0106  2940U2W SCSI Controller
-               9005 a180  2940U2W SCSI Controller
-       00c5  AIC-7899 U160/m SCSI Controller
-               1028 00c5  PowerEdge 2550/2650/4600
-       00cf  AIC-7899P U160/m
-               1028 0106  PowerEdge 4600
-               1028 0121  PowerEdge 2650
-102b  Matrox Graphics, Inc.
-# DJ: I've a suspicion that 0010 is a duplicate of 0d10.
-       0010  MGA-I [Impression?]
-       0100  MGA 1064SG [Mystique]
-       0518  MGA-II [Athena]
-       0519  MGA 2064W [Millennium]
-       051a  MGA 1064SG [Mystique]
-               102b 0100  MGA-1064SG Mystique
-               102b 1100  MGA-1084SG Mystique
-               102b 1200  MGA-1084SG Mystique
-               1100 102b  MGA-1084SG Mystique
-               110a 0018  Scenic Pro C5 (D1025)
-       051b  MGA 2164W [Millennium II]
-               102b 051b  MGA-2164W Millennium II
-               102b 1100  MGA-2164W Millennium II
-               102b 1200  MGA-2164W Millennium II
-       051e  MGA 1064SG [Mystique] AGP
-       051f  MGA 2164W [Millennium II] AGP
-       0520  MGA G200
-               102b dbc2  G200 Multi-Monitor
-               102b dbc8  G200 Multi-Monitor
-               102b dbe2  G200 Multi-Monitor
-               102b dbe8  G200 Multi-Monitor
-               102b ff03  Millennium G200 SD
-               102b ff04  Marvel G200
-       0521  MGA G200 AGP
-               1014 ff03  Millennium G200 AGP
-               102b 48e9  Mystique G200 AGP
-               102b 48f8  Millennium G200 SD AGP
-               102b 4a60  Millennium G200 LE AGP
-               102b 4a64  Millennium G200 AGP
-               102b c93c  Millennium G200 AGP
-               102b c9b0  Millennium G200 AGP
-               102b c9bc  Millennium G200 AGP
-               102b ca60  Millennium G250 LE AGP
-               102b ca6c  Millennium G250 AGP
-               102b dbbc  Millennium G200 AGP
-               102b dbc2  Millennium G200 MMS (Dual G200)
-               102b dbc3  G200 Multi-Monitor
-               102b dbc8  Millennium G200 MMS (Dual G200)
-               102b dbd2  G200 Multi-Monitor
-               102b dbd3  G200 Multi-Monitor
-               102b dbd4  G200 Multi-Monitor
-               102b dbd5  G200 Multi-Monitor
-               102b dbd8  G200 Multi-Monitor
-               102b dbd9  G200 Multi-Monitor
-               102b dbe2  Millennium G200 MMS (Quad G200)
-               102b dbe3  G200 Multi-Monitor
-               102b dbe8  Millennium G200 MMS (Quad G200)
-               102b dbf2  G200 Multi-Monitor
-               102b dbf3  G200 Multi-Monitor
-               102b dbf4  G200 Multi-Monitor
-               102b dbf5  G200 Multi-Monitor
-               102b dbf8  G200 Multi-Monitor
-               102b dbf9  G200 Multi-Monitor
-               102b f806  Mystique G200 Video AGP
-               102b ff00  MGA-G200 AGP
-               102b ff02  Mystique G200 AGP
-               102b ff03  Millennium G200 AGP
-               102b ff04  Marvel G200 AGP
-               110a 0032  MGA-G200 AGP
-       0525  MGA G400 AGP
-               0e11 b16f  MGA-G400 AGP
-               102b 0328  Millennium G400 16Mb SDRAM
-               102b 0338  Millennium G400 16Mb SDRAM
-               102b 0378  Millennium G400 32Mb SDRAM
-               102b 0541  Millennium G450 Dual Head
-               102b 0542  Millennium G450 Dual Head LX
-               102b 0543  Millennium G450 Single Head LX
-               102b 0641  Millennium G450 32Mb SDRAM Dual Head
-               102b 0642  Millennium G450 32Mb SDRAM Dual Head LX
-               102b 0643  Millennium G450 32Mb SDRAM Single Head LX
-               102b 07c0  Millennium G450 Dual Head LE
-               102b 07c1  Millennium G450 SDR Dual Head LE
-               102b 0d41  Millennium G450 Dual Head PCI
-               102b 0d42  Millennium G450 Dual Head LX PCI
-               102b 0d43  Millennium G450 32Mb Dual Head PCI
-               102b 0e00  Marvel G450 eTV
-               102b 0e01  Marvel G450 eTV
-               102b 0e02  Marvel G450 eTV
-               102b 0e03  Marvel G450 eTV
-               102b 0f80  Millennium G450 Low Profile
-               102b 0f81  Millennium G450 Low Profile
-               102b 0f82  Millennium G450 Low Profile DVI
-               102b 0f83  Millennium G450 Low Profile DVI
-               102b 19d8  Millennium G400 16Mb SGRAM
-               102b 19f8  Millennium G400 32Mb SGRAM
-               102b 2159  Millennium G400 Dual Head 16Mb
-               102b 2179  Millennium G400 MAX/Dual Head 32Mb
-               102b 217d  Millennium G400 Dual Head Max
-               102b 23c0  Millennium G450
-               102b 23c1  Millennium G450
-               102b 23c2  Millennium G450 DVI
-               102b 23c3  Millennium G450 DVI
-               102b 2f58  Millennium G400
-               102b 2f78  Millennium G400
-               102b 3693  Marvel G400 AGP
-               102b 5dd0  4Sight II
-               102b 5f50  4Sight II
-               102b 5f51  4Sight II
-               102b 5f52  4Sight II
-               102b 9010  Millennium G400 Dual Head
-               1458 0400  GA-G400
-               1705 0001  Millennium G450 32MB SGRAM
-               1705 0002  Millennium G450 16MB SGRAM
-               1705 0003  Millennium G450 32MB
-               1705 0004  Millennium G450 16MB
-       0527  MGA Parhelia AGP
-               102b 0840  Parhelia 128Mb
-       0d10  MGA Ultima/Impression
-       1000  MGA G100 [Productiva]
-               102b ff01  Productiva G100
-               102b ff05  Productiva G100 Multi-Monitor
-       1001  MGA G100 [Productiva] AGP
-               102b 1001  MGA-G100 AGP
-               102b ff00  MGA-G100 AGP
-               102b ff01  MGA-G100 Productiva AGP
-               102b ff03  Millennium G100 AGP
-               102b ff04  MGA-G100 AGP
-               102b ff05  MGA-G100 Productiva AGP Multi-Monitor
-               110a 001e  MGA-G100 AGP
-       2007  MGA Mistral
-       2527  MGA G550 AGP
-               102b 0f83  Millennium G550
-               102b 0f84  Millennium G550 Dual Head DDR 32Mb
-               102b 1e41  Millennium G550
-       2537  MGA G650 AGP
-       4536  VIA Framegrabber
-       6573  Shark 10/100 Multiport SwitchNIC
-102c  Chips and Technologies
-       00b8  F64310
-       00c0  F69000 HiQVideo
-               102c 00c0  F69000 HiQVideo
-               4c53 1000  CC7/CR7/CP7/VC7/VP7/VR7 mainboard
-               4c53 1010  CP5/CR6 mainboard
-               4c53 1020  VR6 mainboard
-               4c53 1030  PC5 mainboard
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-       00d0  F65545
-       00d8  F65545
-       00dc  F65548
-       00e0  F65550
-       00e4  F65554
-       00e5  F65555 HiQVPro
-               0e11 b049  Armada 1700 Laptop Display Controller
-       00f0  F68554
-       00f4  F68554 HiQVision
-       00f5  F68555
-       0c30  F69030
-               4c53 1000  CC7/CR7/CP7/VC7/VP7/VR7 mainboard
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-# C5C project cancelled
-               4c53 1080  CT8 mainboard
-102d  Wyse Technology Inc.
-       50dc  3328 Audio
-102e  Olivetti Advanced Technology
-102f  Toshiba America
-       0009  r4x00
-       000a  TX3927 MIPS RISC PCI Controller
-       0020  ATM Meteor 155
-               102f 00f8  ATM Meteor 155
-       0030  TC35815CF PCI 10/100 Mbit Ethernet Controller
-       0031  TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL
-       0105  TC86C001 [goku-s] IDE
-       0106  TC86C001 [goku-s] USB 1.1 Host
-       0107  TC86C001 [goku-s] USB Device Controller
-       0108  TC86C001 [goku-s] I2C/SIO/GPIO Controller
-       0180  TX4927/38 MIPS RISC PCI Controller
-       0181  TX4925 MIPS RISC PCI Controller
-       0182  TX4937 MIPS RISC PCI Controller
-1030  TMC Research
-1031  Miro Computer Products AG
-       5601  DC20 ASIC
-       5607  Video I/O & motion JPEG compressor
-       5631  Media 3D
-       6057  MiroVideo DC10/DC30+
-1032  Compaq
-1033  NEC Corporation
-       0000  Vr4181A USB Host or Function Control Unit
-       0001  PCI to 486-like bus Bridge
-       0002  PCI to VL98 Bridge
-       0003  ATM Controller
-       0004  R4000 PCI Bridge
-       0005  PCI to 486-like bus Bridge
-       0006  PC-9800 Graphic Accelerator
-       0007  PCI to UX-Bus Bridge
-       0008  PC-9800 Graphic Accelerator
-       0009  PCI to PC9800 Core-Graph Bridge
-       0016  PCI to VL Bridge
-       001a  [Nile II]
-       0021  Vrc4373 [Nile I]
-       0029  PowerVR PCX1
-       002a  PowerVR 3D
-       002c  Star Alpha 2
-       002d  PCI to C-bus Bridge
-       0035  USB
-               1179 0001  USB
-               12ee 7000  Root Hub
-               1799 0001  Root Hub
-               807d 0035  PCI-USB2 (OHCI subsystem)
-       003b  PCI to C-bus Bridge
-       003e  NAPCCARD Cardbus Controller
-       0046  PowerVR PCX2 [midas]
-       005a  Vrc5074 [Nile 4]
-       0063  Firewarden
-       0067  PowerVR Neon 250 Chipset
-               1010 0020  PowerVR Neon 250 AGP 32Mb
-               1010 0080  PowerVR Neon 250 AGP 16Mb
-               1010 0088  PowerVR Neon 250 16Mb
-               1010 0090  PowerVR Neon 250 AGP 16Mb
-               1010 0098  PowerVR Neon 250 16Mb
-               1010 00a0  PowerVR Neon 250 AGP 32Mb
-               1010 00a8  PowerVR Neon 250 32Mb
-               1010 0120  PowerVR Neon 250 AGP 32Mb
-       0072  uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
-       0074  56k Voice Modem
-               1033 8014  RCV56ACF 56k Voice Modem
-       009b  Vrc5476
-       00a5  VRC4173
-       00a6  VRC5477 AC97
-       00cd  IEEE 1394 [OrangeLink] Host Controller
-               12ee 8011  Root hub
-       00ce  IEEE 1394 Host Controller
-       00df  Vr4131
-       00e0  USB 2.0
-               0ee4 3383  Sitecom IEEE 1394 / USB2.0 Combo Card
-               12ee 7001  Root hub
-               1799 0002  Root Hub
-               807d 1043  PCI-USB2 (EHCI subsystem)
-       00e7  IEEE 1394 Host Controller
-       00f2  uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
-       00f3  uPD6113x Multimedia Decoder/Processor [EMMA2]
-       010c  VR7701
-1034  Framatome Connectors USA Inc.
-1035  Comp. & Comm. Research Lab
-1036  Future Domain Corp.
-       0000  TMC-18C30 [36C70]
-1037  Hitachi Micro Systems
-1038  AMP, Inc
-1039  Silicon Integrated Systems [SiS]
-       0001  Virtual PCI-to-PCI bridge (AGP)
-       0002  SG86C202
-       0006  85C501/2/3
-       0008  SiS85C503/5513 (LPC Bridge)
-       0009  ACPI
-# source: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
-       0016  SiS961/2 SMBus Controller
-       0018  SiS85C503/5513 (LPC Bridge)
-# Controller for 2 PATA and 2 SATA channels
-       0180  RAID bus controller 180 SATA/PATA  [SiS]
-       0181  SiS SATA
-       0200  5597/5598/6326 VGA
-               1039 0000  SiS5597 SVGA (Shared RAM)
-       0204  82C204
-       0205  SG86C205
-       0300  300/305 PCI/AGP VGA Display Adapter
-               107d 2720  Leadtek WinFast VR300
-       0310  315H PCI/AGP VGA Display Adapter
-       0315  315 PCI/AGP VGA Display Adapter
-       0325  315PRO PCI/AGP VGA Display Adapter
-       0330  330 [Xabre] PCI/AGP VGA Display Adapter
-       0406  85C501/2
-       0496  85C496
-       0530  530 Host
-       0540  540 Host
-       0550  550 Host
-       0597  5513C
-       0601  85C601
-       0620  620 Host
-       0630  630 Host
-       0633  633 Host
-       0635  635 Host
-       0645  SiS645 Host & Memory & AGP Controller
-       0646  SiS645DX Host & Memory & AGP Controller
-       0648  SiS 645xx
-       0650  650/M650 Host
-       0651  651 Host
-       0655  655 Host
-       0660  660 Host
-       0661  661FX/M661FX/M661MX Host
-       0730  730 Host
-       0733  733 Host
-       0735  735 Host
-       0740  740 Host
-       0741  741/741GX/M741 Host
-       0745  745 Host
-       0746  746 Host
-       0755  755 Host
-       0760  760/M760 Host
-       0900  SiS900 PCI Fast Ethernet
-               1019 0a14  K7S5A motherboard
-               1039 0900  SiS900 10/100 Ethernet Adapter
-               1043 8035  CUSI-FX motherboard
-       0961  SiS961 [MuTIOL Media IO]
-       0962  SiS962 [MuTIOL Media IO]
-       0963  SiS963 [MuTIOL Media IO]
-       0964  SiS964 [MuTIOL Media IO]
-       0965  SiS965 [MuTIOL Media IO]
-       3602  83C602
-       5107  5107
-       5300  SiS540 PCI Display Adapter
-       5315  550 PCI/AGP VGA Display Adapter
-       5401  486 PCI Chipset
-       5511  5511/5512
-       5513  5513 [IDE]
-               1019 0970  P6STP-FL motherboard
-               1039 5513  SiS5513 EIDE Controller (A,B step)
-               1043 8035  CUSI-FX motherboard
-       5517  5517
-       5571  5571
-       5581  5581 Pentium Chipset
-       5582  5582
-       5591  5591/5592 Host
-       5596  5596 Pentium Chipset
-       5597  5597 [SiS5582]
-       5600  5600 Host
-       6204  Video decoder & MPEG interface
-       6205  VGA Controller
-       6236  6236 3D-AGP
-       6300  630/730 PCI/AGP VGA Display Adapter
-               1019 0970  P6STP-FL motherboard
-               1043 8035  CUSI-FX motherboard
-       6306  530/620 PCI/AGP VGA Display Adapter
-               1039 6306  SiS530,620 GUI Accelerator+3D
-       6325  65x/M650/740 PCI/AGP VGA Display Adapter
-       6326  86C326 5598/6326
-               1039 6326  SiS6326 GUI Accelerator
-               1092 0a50  SpeedStar A50
-               1092 0a70  SpeedStar A70
-               1092 4910  SpeedStar A70
-               1092 4920  SpeedStar A70
-               1569 6326  SiS6326 GUI Accelerator
-       6330  661/741/760 PCI/AGP VGA Display Adapter
-               1039 6330  [M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
-       7001  USB 1.0 Controller
-               1019 0a14  K7S5A motherboard
-               1039 7000  Onboard USB Controller
-       7002  USB 2.0 Controller
-               1509 7002  Onboard USB Controller
-       7007  FireWire Controller
-       7012  Sound Controller
-# There are may be different modem codecs here (Intel537 compatible and incompatible)
-       7013  AC'97 Modem Controller
-       7016  SiS7016 PCI Fast Ethernet Adapter
-               1039 7016  SiS7016 10/100 Ethernet Adapter
-       7018  SiS PCI Audio Accelerator
-               1014 01b6  SiS PCI Audio Accelerator
-               1014 01b7  SiS PCI Audio Accelerator
-               1019 7018  SiS PCI Audio Accelerator
-               1025 000e  SiS PCI Audio Accelerator
-               1025 0018  SiS PCI Audio Accelerator
-               1039 7018  SiS PCI Audio Accelerator
-               1043 800b  SiS PCI Audio Accelerator
-               1054 7018  SiS PCI Audio Accelerator
-               107d 5330  SiS PCI Audio Accelerator
-               107d 5350  SiS PCI Audio Accelerator
-               1170 3209  SiS PCI Audio Accelerator
-               1462 400a  SiS PCI Audio Accelerator
-               14a4 2089  SiS PCI Audio Accelerator
-               14cd 2194  SiS PCI Audio Accelerator
-               14ff 1100  SiS PCI Audio Accelerator
-               152d 8808  SiS PCI Audio Accelerator
-               1558 1103  SiS PCI Audio Accelerator
-               1558 2200  SiS PCI Audio Accelerator
-               1563 7018  SiS PCI Audio Accelerator
-               15c5 0111  SiS PCI Audio Accelerator
-               270f a171  SiS PCI Audio Accelerator
-               a0a0 0022  SiS PCI Audio Accelerator
-       7019  SiS7019 Audio Accelerator
-103a  Seiko Epson Corporation
-103b  Tatung Co. of America
-103c  Hewlett-Packard Company
-       1005  A4977A Visualize EG
-       1006  Visualize FX6
-       1008  Visualize FX4
-       100a  Visualize FX2
-       1028  Tach TL Fibre Channel Host Adapter
-       1029  Tach XL2 Fibre Channel Host Adapter
-               107e 000f  Interphase 5560 Fibre Channel Adapter
-               9004 9210  1Gb/2Gb Family Fibre Channel Controller
-               9004 9211  1Gb/2Gb Family Fibre Channel Controller
-       102a  Tach TS Fibre Channel Host Adapter
-               107e 000e  Interphase 5540/5541 Fibre Channel Adapter
-               9004 9110  1Gb/2Gb Family Fibre Channel Controller
-               9004 9111  1Gb/2Gb Family Fibre Channel Controller
-       1030  J2585A DeskDirect 10/100VG NIC
-       1031  J2585B HP 10/100VG PCI LAN Adapter
-               103c 1040  J2973A DeskDirect 10BaseT NIC
-               103c 1041  J2585B DeskDirect 10/100VG NIC
-               103c 1042  J2970A DeskDirect 10BaseT/2 NIC
-       1040  J2973A DeskDirect 10BaseT NIC
-       1041  J2585B DeskDirect 10/100 NIC
-       1042  J2970A DeskDirect 10BaseT/2 NIC
-       1048  Diva Serial [GSP] Multiport UART
-               103c 1049  Tosca Console
-               103c 104a  Tosca Secondary
-               103c 104b  Maestro SP2
-               103c 1223  Superdome Console
-               103c 1226  Keystone SP2
-               103c 1227  Powerbar SP2
-               103c 1282  Everest SP2
-               103c 1301  Diva RMP3
-       1054  PCI Local Bus Adapter
-       1064  79C970 PCnet Ethernet Controller
-       108b  Visualize FXe
-       10c1  NetServer Smart IRQ Router
-       10ed  TopTools Remote Control
-       10f0  rio System Bus Adapter
-       10f1  rio I/O Controller
-       1200  82557B 10/100 NIC
-       1219  NetServer PCI Hot-Plug Controller
-       121a  NetServer SMIC Controller
-       121b  NetServer Legacy COM Port Decoder
-       121c  NetServer PCI COM Port Decoder
-       1229  zx1 System Bus Adapter
-       122a  zx1 I/O Controller
-       122e  zx1 Local Bus Adapter
-       127c  sx1000 I/O Controller
-       1290  Auxiliary Diva Serial Port
-       12b4  zx1 QuickSilver AGP8x Local Bus Adapter
-       2910  E2910A PCIBus Exerciser
-       2925  E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
-103e  Solliday Engineering
-103f  Synopsys/Logic Modeling Group
-1040  Accelgraphics Inc.
-1041  Computrend
-1042  Micron
-       1000  PC Tech RZ1000
-       1001  PC Tech RZ1001
-       3000  Samurai_0
-       3010  Samurai_1
-       3020  Samurai_IDE
-1043  ASUSTeK Computer Inc.
-       0675  ISDNLink P-IN100-ST-D
-       4015  v7100 SDRAM [GeForce2 MX]
-       4021  v7100 Combo Deluxe [GeForce2 MX + TV tuner]
-       4057  v8200 GeForce 3
-       8043  v8240 PAL 128M [P4T] Motherboard
-       807b  v9280/TD [Geforce4 TI4200 8X With TV-Out and DVI]
-       80bb  v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out]
-       80c5  nForce3 chipset motherboard [SK8N]
-       80df  v9520 Magic/T
-1044  Adaptec (formerly DPT)
-       1012  Domino RAID Engine
-       a400  SmartCache/Raid I-IV Controller
-       a500  PCI Bridge
-       a501  SmartRAID V Controller
-               1044 c001  PM1554U2 Ultra2 Single Channel
-               1044 c002  PM1654U2 Ultra2 Single Channel
-               1044 c003  PM1564U3 Ultra3 Single Channel
-               1044 c004  PM1564U3 Ultra3 Dual Channel
-               1044 c005  PM1554U2 Ultra2 Single Channel (NON ACPI)
-               1044 c00a  PM2554U2 Ultra2 Single Channel
-               1044 c00b  PM2654U2 Ultra2 Single Channel
-               1044 c00c  PM2664U3 Ultra3 Single Channel
-               1044 c00d  PM2664U3 Ultra3 Dual Channel
-               1044 c00e  PM2554U2 Ultra2 Single Channel (NON ACPI)
-               1044 c00f  PM2654U2 Ultra2 Single Channel (NON ACPI)
-               1044 c014  PM3754U2 Ultra2 Single Channel (NON ACPI)
-               1044 c015  PM3755U2B Ultra2 Single Channel (NON ACPI)
-               1044 c016  PM3755F Fibre Channel (NON ACPI)
-               1044 c01e  PM3757U2 Ultra2 Single Channel
-               1044 c01f  PM3757U2 Ultra2 Dual Channel
-               1044 c020  PM3767U3 Ultra3 Dual Channel
-               1044 c021  PM3767U3 Ultra3 Quad Channel
-               1044 c028  PM2865U3 Ultra3 Single Channel
-               1044 c029  PM2865U3 Ultra3 Dual Channel
-               1044 c02a  PM2865F Fibre Channel
-               1044 c03c  2000S Ultra3 Single Channel
-               1044 c03d  2000S Ultra3 Dual Channel
-               1044 c03e  2000F Fibre Channel
-               1044 c046  3000S Ultra3 Single Channel
-               1044 c047  3000S Ultra3 Dual Channel
-               1044 c048  3000F Fibre Channel
-               1044 c050  5000S Ultra3 Single Channel
-               1044 c051  5000S Ultra3 Dual Channel
-               1044 c052  5000F Fibre Channel
-               1044 c05a  2400A UDMA Four Channel
-               1044 c05b  2400A UDMA Four Channel DAC
-               1044 c064  3010S Ultra3 Dual Channel
-               1044 c065  3410S Ultra160 Four Channel
-               1044 c066  3010S Fibre Channel
-       a511  SmartRAID V Controller
-               1044 c032  ASR-2005S I2O Zero Channel
-1045  OPTi Inc.
-       a0f8  82C750 [Vendetta] USB Controller
-       c101  92C264
-       c178  92C178
-       c556  82X556 [Viper]
-       c557  82C557 [Viper-M]
-       c558  82C558 [Viper-M ISA+IDE]
-       c567  82C750 [Vendetta], device 0
-       c568  82C750 [Vendetta], device 1
-       c569  82C579 [Viper XPress+ Chipset]
-       c621  82C621 [Viper-M/N+]
-       c700  82C700 [FireStar]
-       c701  82C701 [FireStar Plus]
-       c814  82C814 [Firebridge 1]
-       c822  82C822
-       c824  82C824
-       c825  82C825 [Firebridge 2]
-       c832  82C832
-       c861  82C861
-       c895  82C895
-       c935  EV1935 ECTIVA MachOne PCIAudio
-       d568  82C825 [Firebridge 2]
-       d721  IDE [FireStar]
-1046  IPC Corporation, Ltd.
-1047  Genoa Systems Corp
-1048  Elsa AG
-       0c60  Gladiac MX
-       0d22  Quadro4 900XGL [ELSA GLoria4 900XGL]
-       1000  QuickStep 1000
-       3000  QuickStep 3000
-       8901  Gloria XL
-1049  Fountain Technologies, Inc.
-# # nee SGS Thomson Microelectronics
-104a  STMicroelectronics
-       0008  STG 2000X
-       0009  STG 1764X
-       0010  STG4000 [3D Prophet Kyro Series]
-       0209  STPC Consumer/Industrial North- and Southbridge
-       020a  STPC Atlas/ConsumerS/Consumer IIA Northbridge
-# From <http://gatekeeper.dec.com/pub/BSD/FreeBSD/FreeBSD-stable/src/share/misc/pci_vendors>
-       0210  STPC Atlas ISA Bridge
-       021a  STPC Consumer S Southbridge
-       021b  STPC Consumer IIA Southbridge
-       0500  ST70137 [Unicorn] ADSL DMT Transceiver
-       0564  STPC Client Northbridge
-       0981  21x4x DEC-Tulip compatible 10/100 Ethernet
-       1746  STG 1764X
-       2774  21x4x DEC-Tulip compatible 10/100 Ethernet
-       3520  MPEG-II decoder card
-       55cc  STPC Client Southbridge
-104b  BusLogic
-       0140  BT-946C (old) [multimaster  01]
-       1040  BT-946C (BA80C30) [MultiMaster 10]
-       8130  Flashpoint LT
-104c  Texas Instruments
-       0500  100 MBit LAN Controller
-       0508  TMS380C2X Compressor Interface
-       1000  Eagle i/f AS
-       104c  PCI1510 PC card Cardbus Controller
-       3d04  TVP4010 [Permedia]
-       3d07  TVP4020 [Permedia 2]
-               1011 4d10  Comet
-               1040 000f  AccelStar II
-               1040 0011  AccelStar II
-               1048 0a31  WINNER 2000
-               1048 0a32  GLoria Synergy
-               1048 0a35  GLoria Synergy
-               107d 2633  WinFast 3D L2300
-               1092 0127  FIRE GL 1000 PRO
-               1092 0136  FIRE GL 1000 PRO
-               1092 0141  FIRE GL 1000 PRO
-               1092 0146  FIRE GL 1000 PRO
-               1092 0148  FIRE GL 1000 PRO
-               1092 0149  FIRE GL 1000 PRO
-               1092 0152  FIRE GL 1000 PRO
-               1092 0154  FIRE GL 1000 PRO
-               1092 0155  FIRE GL 1000 PRO
-               1092 0156  FIRE GL 1000 PRO
-               1092 0157  FIRE GL 1000 PRO
-               1097 3d01  Jeronimo Pro
-               1102 100f  Graphics Blaster Extreme
-               3d3d 0100  Reference Permedia 2 3D
-       8000  PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
-               e4bf 1010  CF1-1-SNARE
-               e4bf 1020  CF1-2-SNARE
-       8009  FireWire Controller
-               104d 8032  8032 OHCI i.LINK (IEEE 1394) Controller
-       8017  PCI4410 FireWire Controller
-       8019  TSB12LV23 IEEE-1394 Controller
-               11bd 000a  Studio DV500-1394
-               11bd 000e  Studio DV
-               e4bf 1010  CF2-1-CYMBAL
-       8020  TSB12LV26 IEEE-1394 Controller (Link)
-               11bd 000f  Studio DV500-1394
-       8021  TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
-               104d 80df  Vaio PCG-FX403
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-       8022  TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link)
-       8023  TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
-               103c 088c  nc8000 laptop
-       8024  TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
-       8025  TSB82AA2 IEEE-1394b Link Layer Controller
-               55aa 55aa  FireWire 800 PCI Card
-       8026  TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
-       8027  PCI4451 IEEE-1394 Controller
-               1028 00e6  PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
-       8029  PCI4510 IEEE-1394 Controller
-               1028 0163  Latitude D505
-               1071 8160  MIM2900
-       802b  PCI7410,7510,7610 OHCI-Lynx Controller
-               1028 014e  PCI7410,7510,7610 OHCI-Lynx Controller (Dell Latitude D800)
-       802e  PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
-       8031  Texas Instruments PCIxx21/x515 Cardbus Controller
-       8032  Texas Instruments OHCI Compliant IEEE 1394 Host Controller
-       8033  Texas Instruments PCIxx21 Integrated FlashMedia Controller
-       8034  Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Secure Digital (SD) Controller
-       8035  Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Smart Card Controller (SMC)
-       8201  PCI1620 Firmware Loading Function
-       8204  PCI7410,7510,7610 PCI Firmware Loading Function
-               1028 014e  Latitude D800
-       8400  ACX 100 22Mbps Wireless Interface
-               00fc 16ec  U.S. Robotics 22 Mbps Wireless PC Card (model 2210)
-               00fd 16ec  U.S. Robotics 22Mbps Wireless PCI Adapter (model 2216)
-               1186 3b00  DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
-               1186 3b01  DWL-520+ 22Mbps PCI Wireless Adapter
-       8401  ACX 100 22Mbps Wireless Interface
-# OK, this info is almost useless as is, but at least it's known that it's a wireless card. More info requested from reporter (whi
-       9000  Wireless Interface (of unknown type)
-       9066  ACX 111 54Mbps Wireless Interface
-       a001  TDC1570
-       a100  TDC1561
-       a102  TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
-       a106  TMS320C6205 Fixed Point DSP
-               175c 5000  ASI50xx Audio Adapter
-               175c 8700  ASI87xx Radio Tuner card
-       ac10  PCI1050
-       ac11  PCI1053
-       ac12  PCI1130
-       ac13  PCI1031
-       ac15  PCI1131
-       ac16  PCI1250
-               1014 0092  ThinkPad 600
-       ac17  PCI1220
-       ac18  PCI1260
-       ac19  PCI1221
-       ac1a  PCI1210
-       ac1b  PCI1450
-               0e11 b113  Armada M700
-       ac1c  PCI1225
-               0e11 b121  Armada E500
-               1028 0088  Dell  Computer Corporation  Latitude CPi A400XT
-       ac1d  PCI1251A
-       ac1e  PCI1211
-       ac1f  PCI1251B
-       ac20  TI 2030
-       ac21  PCI2031
-       ac22  PCI2032 PCI Docking Bridge
-       ac23  PCI2250 PCI-to-PCI Bridge
-       ac28  PCI2050 PCI-to-PCI Bridge
-       ac30  PCI1260 PC card Cardbus Controller
-       ac40  PCI4450 PC card Cardbus Controller
-       ac41  PCI4410 PC card Cardbus Controller
-       ac42  PCI4451 PC card Cardbus Controller
-               1028 00e6  PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
-       ac44  PCI4510 PC card Cardbus Controller
-               1028 0163  Latitude D505
-               1071 8160  MIM2000
-       ac46  PCI4520 PC card Cardbus Controller
-       ac47  PCI7510 PC card Cardbus Controller
-               1028 014e  Latitude D800
-       ac4a  PCI7510,7610 PC card Cardbus Controller
-               1028 014e  Latitude D800
-       ac50  PCI1410 PC card Cardbus Controller
-       ac51  PCI1420
-               1014 023b  ThinkPad T23 (2647-4MG)
-               1028 00b1  Latitude C600
-               1028 012a  Latitude C640
-               1033 80cd  Versa Note VXi
-               10cf 1095  Lifebook C6155
-               e4bf 1000  CP2-2-HIPHOP
-       ac52  PCI1451 PC card Cardbus Controller
-       ac53  PCI1421 PC card Cardbus Controller
-       ac54  PCI1620 PC Card Controller
-       ac55  PCI1520 PC card Cardbus Controller
-               1014 0512  ThinkPad T30/T40
-       ac56  PCI1510 PC card Cardbus Controller
-               1014 0528  ThinkPad R40e (2684-HVG) Cardbus Controller
-       ac60  PCI2040 PCI to DSP Bridge Controller
-               175c 5100  ASI51xx Audio Adapter
-               175c 6100  ASI61xx Audio Adapter
-               175c 6200  ASI62xx Audio Adapter
-       ac8d  PCI 7620
-       ac8e  PCI7420 CardBus Controller
-       ac8f  PCI7420/PCI7620 Dual Socket CardBus and Smart Card Cont. w/ 1394a-2000 OHCI Two-Port  PHY/Link-Layer Cont. and SD/MS-Pro Sockets
-       fe00  FireWire Host Controller
-       fe03  12C01A FireWire Host Controller
-104d  Sony Corporation
-       8004  DTL-H2500 [Playstation development board]
-       8009  CXD1947Q i.LINK Controller
-       8039  CXD3222 i.LINK Controller
-       8056  Rockwell HCF 56K modem
-       808a  Memory Stick Controller
-104e  Oak Technology, Inc
-       0017  OTI-64017
-       0107  OTI-107 [Spitfire]
-       0109  Video Adapter
-       0111  OTI-64111 [Spitfire]
-       0217  OTI-64217
-       0317  OTI-64317
-104f  Co-time Computer Ltd
-1050  Winbond Electronics Corp
-       0000  NE2000
-       0001  W83769F
-       0105  W82C105
-       0840  W89C840
-               1050 0001  W89C840 Ethernet Adapter
-               1050 0840  W89C840 Ethernet Adapter
-       0940  W89C940
-       5a5a  W89C940F
-       6692  W6692
-       9921  W99200F MPEG-1 Video Encoder
-       9922  W99200F/W9922PF MPEG-1/2 Video Encoder
-       9970  W9970CF
-1051  Anigma, Inc.
-1052  ?Young Micro Systems
-1053  Young Micro Systems
-1054  Hitachi, Ltd
-1055  Efar Microsystems
-       9130  SLC90E66 [Victory66] IDE
-       9460  SLC90E66 [Victory66] ISA
-       9462  SLC90E66 [Victory66] USB
-       9463  SLC90E66 [Victory66] ACPI
-1056  ICL
-# Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
-1057  Motorola
-       0001  MPC105 [Eagle]
-       0002  MPC106 [Grackle]
-       0003  MPC8240 [Kahlua]
-       0004  MPC107
-       0006  MPC8245 [Unity]
-       0008  MPC8540
-       0009  MPC8560
-       0100  MC145575 [HFC-PCI]
-       0431  KTI829c 100VG
-       1801  DSP56301 Digital Signal Processor
-               14fb 0101  Transas Radar Imitator Board [RIM]
-               14fb 0102  Transas Radar Imitator Board [RIM-2]
-               14fb 0202  Transas Radar Integrator Board [RIB-2]
-               14fb 0611  1 channel CAN bus Controller [CanPci-1]
-               14fb 0612  2 channels CAN bus Controller [CanPci-2]
-               14fb 0613  3 channels CAN bus Controller [CanPci-3]
-               14fb 0614  4 channels CAN bus Controller [CanPci-4]
-               14fb 0621  1 channel CAN bus Controller [CanPci2-1]
-               14fb 0622  2 channels CAN bus Controller [CanPci2-2]
-               14fb 0810  Transas VTS Radar Integrator Board [RIB-4]
-               175c 4200  ASI4215 Audio Adapter
-               175c 4300  ASI43xx Audio Adapter
-               175c 4400  ASI4401 Audio Adapter
-               ecc0 0010  Darla
-               ecc0 0020  Gina
-               ecc0 0030  Layla rev.0
-               ecc0 0031  Layla rev.1
-               ecc0 0040  Darla24 rev.0
-               ecc0 0041  Darla24 rev.1
-               ecc0 0050  Gina24 rev.0
-               ecc0 0051  Gina24 rev.1
-               ecc0 0070  Mona rev.0
-               ecc0 0071  Mona rev.1
-               ecc0 0072  Mona rev.2
-       18c0  MPC8265A/MPC8266
-       18c1  MPC8271/MPC8272
-       3410  DSP56361 Digital Signal Processor
-               ecc0 0050  Gina24 rev.0
-               ecc0 0051  Gina24 rev.1
-               ecc0 0060  Layla24
-               ecc0 0070  Mona rev.0
-               ecc0 0071  Mona rev.1
-               ecc0 0072  Mona rev.2
-               ecc0 0080  Mia rev.0
-               ecc0 0081  Mia rev.1
-               ecc0 0090  Indigo
-               ecc0 00a0  Indigo IO
-               ecc0 00b0  Indigo DJ
-               ecc0 0100  3G
-       4801  Raven
-       4802  Falcon
-       4803  Hawk
-       4806  CPX8216
-       4d68  20268
-       5600  SM56 PCI Modem
-               1057 0300  SM56 PCI Speakerphone Modem
-               1057 0301  SM56 PCI Voice Modem
-               1057 0302  SM56 PCI Fax Modem
-               1057 5600  SM56 PCI Voice modem
-               13d2 0300  SM56 PCI Speakerphone Modem
-               13d2 0301  SM56 PCI Voice modem
-               13d2 0302  SM56 PCI Fax Modem
-               1436 0300  SM56 PCI Speakerphone Modem
-               1436 0301  SM56 PCI Voice modem
-               1436 0302  SM56 PCI Fax Modem
-               144f 100c  SM56 PCI Fax Modem
-               1494 0300  SM56 PCI Speakerphone Modem
-               1494 0301  SM56 PCI Voice modem
-               14c8 0300  SM56 PCI Speakerphone Modem
-               14c8 0302  SM56 PCI Fax Modem
-               1668 0300  SM56 PCI Speakerphone Modem
-               1668 0302  SM56 PCI Fax Modem
-       5803  MPC5200
-       6400  MPC190 Security Processor (S1 family, encryption)
-       6405  MPC184 Security Processor (S1 family)
-1058  Electronics & Telecommunications RSH
-1059  Teknor Industrial Computers Inc
-105a  Promise Technology, Inc.
-# more correct description from promise linux sources
-       0d30  PDC20265 (FastTrak100 Lite/Ultra100)
-               105a 4d33  Ultra100
-       0d38  20263
-               105a 4d39  Fasttrak66
-       1275  20275
-       3318  PDC20318 (SATA150 TX4)
-       3319  PDC20319 (FastTrak S150 TX4)
-               8086 3427  S875WP1-E mainboard
-       3371  PDC20371 (FastTrak S150 TX2plus)
-       3373  PDC20378 (FastTrak 378/SATA 378)
-               1043 80f5  K8V Deluxe/PC-DL Deluxe motherboard
-               1462 702e  K8T NEO FIS2R motherboard
-       3375  PDC20375 (SATA150 TX2plus)
-       3376  PDC20376 (FastTrak 376)
-               1043 809e  A7V8X motherboard
-       3574  PDC20579 SATAII 150 IDE Controller
-       3d18  PDC20518/PDC40518 (SATAII 150 TX4)
-       3d75  PDC20575 (SATAII150 TX2plus)
-       4d30  PDC20267 (FastTrak100/Ultra100)
-               105a 4d33  Ultra100
-               105a 4d39  FastTrak100
-       4d33  20246
-               105a 4d33  20246 IDE Controller
-       4d38  PDC20262 (FastTrak66/Ultra66)
-               105a 4d30  Ultra Device on SuperTrak
-               105a 4d33  Ultra66
-               105a 4d39  FastTrak66
-       4d68  PDC20268 (Ultra100 TX2)
-               105a 4d68  Ultra100TX2
-       4d69  20269
-               105a 4d68  Ultra133TX2
-       5275  PDC20276 (MBFastTrak133 Lite)
-               105a 0275  SuperTrak SX6000 IDE
-               105a 1275  MBFastTrak133 Lite (tm) Controller (RAID mode)
-               1458 b001  MBUltra 133
-       5300  DC5300
-       6268  PDC20270 (FastTrak100 LP/TX2/TX4)
-               105a 4d68  FastTrak100 TX2
-       6269  PDC20271 (FastTrak TX2000)
-               105a 6269  FastTrak TX2/TX2000
-       6621  PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite)
-       6622  PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller
-       6626  PDC20618 (Ultra 618)
-       6629  PDC20619 (FastTrak TX4000)
-       7275  PDC20277 (SBFastTrak133 Lite)
-105b  Foxconn International, Inc.
-105c  Wipro Infotech Limited
-105d  Number 9 Computer Company
-       2309  Imagine 128
-       2339  Imagine 128-II
-               105d 0000  Imagine 128 series 2 4Mb VRAM
-               105d 0001  Imagine 128 series 2 4Mb VRAM
-               105d 0002  Imagine 128 series 2 4Mb VRAM
-               105d 0003  Imagine 128 series 2 4Mb VRAM
-               105d 0004  Imagine 128 series 2 4Mb VRAM
-               105d 0005  Imagine 128 series 2 4Mb VRAM
-               105d 0006  Imagine 128 series 2 4Mb VRAM
-               105d 0007  Imagine 128 series 2 4Mb VRAM
-               105d 0008  Imagine 128 series 2e 4Mb DRAM
-               105d 0009  Imagine 128 series 2e 4Mb DRAM
-               105d 000a  Imagine 128 series 2 8Mb VRAM
-               105d 000b  Imagine 128 series 2 8Mb H-VRAM
-               11a4 000a  Barco Metheus 5 Megapixel
-               13cc 0000  Barco Metheus 5 Megapixel
-               13cc 0004  Barco Metheus 5 Megapixel
-               13cc 0005  Barco Metheus 5 Megapixel
-               13cc 0006  Barco Metheus 5 Megapixel
-               13cc 0008  Barco Metheus 5 Megapixel
-               13cc 0009  Barco Metheus 5 Megapixel
-               13cc 000a  Barco Metheus 5 Megapixel
-               13cc 000c  Barco Metheus 5 Megapixel
-       493d  Imagine 128 T2R [Ticket to Ride]
-               11a4 000a  Barco Metheus 5 Megapixel, Dual Head
-               11a4 000b  Barco Metheus 5 Megapixel, Dual Head
-               13cc 0002  Barco Metheus 4 Megapixel, Dual Head
-               13cc 0003  Barco Metheus 5 Megapixel, Dual Head
-               13cc 0007  Barco Metheus 5 Megapixel, Dual Head
-               13cc 0008  Barco Metheus 5 Megapixel, Dual Head
-               13cc 0009  Barco Metheus 5 Megapixel, Dual Head
-               13cc 000a  Barco Metheus 5 Megapixel, Dual Head
-       5348  Revolution 4
-               105d 0037  Revolution IV-FP AGP (For SGI 1600SW)
-105e  Vtech Computers Ltd
-105f  Infotronic America Inc
-1060  United Microelectronics [UMC]
-       0001  UM82C881
-       0002  UM82C886
-       0101  UM8673F
-       0881  UM8881
-       0886  UM8886F
-       0891  UM8891A
-       1001  UM886A
-       673a  UM8886BF
-       673b  EIDE Master/DMA
-       8710  UM8710
-       886a  UM8886A
-       8881  UM8881F
-       8886  UM8886F
-       888a  UM8886A
-       8891  UM8891A
-       9017  UM9017F
-       9018  UM9018
-       9026  UM9026
-       e881  UM8881N
-       e886  UM8886N
-       e88a  UM8886N
-       e891  UM8891N
-1061  I.I.T.
-       0001  AGX016
-       0002  IIT3204/3501
-1062  Maspar Computer Corp
-1063  Ocean Office Automation
-1064  Alcatel
-1065  Texas Microsystems
-1066  PicoPower Technology
-       0000  PT80C826
-       0001  PT86C521 [Vesuvius v1] Host Bridge
-       0002  PT86C523 [Vesuvius v3] PCI-ISA Bridge Master
-       0003  PT86C524 [Nile] PCI-to-PCI Bridge
-       0004  PT86C525 [Nile-II] PCI-to-PCI Bridge
-       0005  National PC87550 System Controller
-       8002  PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave
-1067  Mitsubishi Electric
-       0301  AccelGraphics AccelECLIPSE
-       0304  AccelGALAXY A2100 [OEM Evans & Sutherland]
-       0308  Tornado 3000 [OEM Evans & Sutherland]
-       1002  VG500 [VolumePro Volume Rendering Accelerator]
-1068  Diversified Technology
-1069  Mylex Corporation
-       0001  DAC960P
-       0002  DAC960PD
-       0010  DAC960PG
-       0020  DAC960LA
-       0050  AcceleRAID 352/170/160 support Device
-       b166  Gemstone chipset SCSI controller
-               1014 0242  iSeries 2872 DASD IOA
-               1014 0266  Dual Channel PCI-X U320 SCSI Adapter
-               1014 0278  Dual Channel PCI-X U320 SCSI RAID Adapter
-               1014 02d3  Dual Channel PCI-X U320 SCSI Adapter
-               1014 02d4  Dual Channel PCI-X U320 SCSI RAID Adapter
-       ba55  eXtremeRAID 1100 support Device
-       ba56  eXtremeRAID 2000/3000 support Device
-106a  Aten Research Inc
-106b  Apple Computer Inc.
-       0001  Bandit PowerPC host bridge
-       0002  Grand Central I/O
-       0003  Control Video
-       0004  PlanB Video-In
-       0007  O'Hare I/O
-       000c  DOS on Mac
-       000e  Hydra Mac I/O
-       0010  Heathrow Mac I/O
-       0017  Paddington Mac I/O
-       0018  UniNorth FireWire
-       0019  KeyLargo USB
-       001e  UniNorth Internal PCI
-       001f  UniNorth PCI
-       0020  UniNorth AGP
-       0021  UniNorth GMAC (Sun GEM)
-       0022  KeyLargo Mac I/O
-       0024  UniNorth/Pangea GMAC (Sun GEM)
-       0025  KeyLargo/Pangea Mac I/O
-       0026  KeyLargo/Pangea USB
-       0027  UniNorth/Pangea AGP
-       0028  UniNorth/Pangea PCI
-       0029  UniNorth/Pangea Internal PCI
-       002d  UniNorth 1.5 AGP
-       002e  UniNorth 1.5 PCI
-       002f  UniNorth 1.5 Internal PCI
-       0030  UniNorth/Pangea FireWire
-       0031  UniNorth 2 FireWire
-       0032  UniNorth 2 GMAC (Sun GEM)
-       0033  UniNorth 2 ATA/100
-       0034  UniNorth 2 AGP
-       0035  UniNorth 2 PCI
-       0036  UniNorth 2 Internal PCI
-       003b  UniNorth/Intrepid ATA/100
-       003e  KeyLargo/Intrepid Mac I/O
-       003f  KeyLargo/Intrepid USB
-       0040  K2 KeyLargo USB
-       0041  K2 KeyLargo Mac/IO
-       0042  K2 FireWire
-       0043  K2 ATA/100
-       0045  K2 HT-PCI Bridge
-       0046  K2 HT-PCI Bridge
-       0047  K2 HT-PCI Bridge
-       0048  K2 HT-PCI Bridge
-       0049  K2 HT-PCI Bridge
-       004b  U3 AGP
-       004c  K2 GMAC (Sun GEM)
-       004f  Shasta Mac I/O
-       0050  Shasta IDE
-       0051  Shasta (Sun GEM)
-       0052  Shasta Firewire
-       0053  Shasta PCI Bridge
-       0054  Shasta PCI Bridge
-       0055  Shasta PCI Bridge
-       0058  U3L AGP Bridge
-       1645  Tigon3 Gigabit Ethernet NIC (BCM5701)
-106c  Hynix Semiconductor
-       8801  Dual Pentium ISA/PCI Motherboard
-       8802  PowerPC ISA/PCI Motherboard
-       8803  Dual Window Graphics Accelerator
-       8804  LAN Controller
-       8805  100-BaseT LAN
-106d  Sequent Computer Systems
-106e  DFI, Inc
-106f  City Gate Development Ltd
-1070  Daewoo Telecom Ltd
-1071  Mitac
-       8160  Mitac 8060B Mobile Platform
-1072  GIT Co Ltd
-1073  Yamaha Corporation
-       0001  3D GUI Accelerator
-       0002  YGV615 [RPA3 3D-Graphics Controller]
-       0003  YMF-740
-       0004  YMF-724
-               1073 0004  YMF724-Based PCI Audio Adapter
-       0005  DS1 Audio
-               1073 0005  DS-XG PCI Audio CODEC
-       0006  DS1 Audio
-       0008  DS1 Audio
-               1073 0008  DS-XG PCI Audio CODEC
-       000a  DS1L Audio
-               1073 0004  DS-XG PCI Audio CODEC
-               1073 000a  DS-XG PCI Audio CODEC
-       000c  YMF-740C [DS-1L Audio Controller]
-               107a 000c  DS-XG PCI Audio CODEC
-       000d  YMF-724F [DS-1 Audio Controller]
-               1073 000d  DS-XG PCI Audio CODEC
-       0010  YMF-744B [DS-1S Audio Controller]
-               1073 0006  DS-XG PCI Audio CODEC
-               1073 0010  DS-XG PCI Audio CODEC
-       0012  YMF-754 [DS-1E Audio Controller]
-               1073 0012  DS-XG PCI Audio Codec
-       0020  DS-1 Audio
-       2000  DS2416 Digital Mixing Card
-               1073 2000  DS2416 Digital Mixing Card
-1074  NexGen Microsystems
-       4e78  82c500/1
-1075  Advanced Integrations Research
-1076  Chaintech Computer Co. Ltd
-1077  QLogic Corp.
-       1016  ISP10160 Single Channel Ultra3 SCSI Processor
-       1020  ISP1020 Fast-wide SCSI
-       1022  ISP1022 Fast-wide SCSI
-       1080  ISP1080 SCSI Host Adapter
-       1216  ISP12160 Dual Channel Ultra3 SCSI Processor
-               101e 8471  QLA12160 on AMI MegaRAID
-               101e 8493  QLA12160 on AMI MegaRAID
-       1240  ISP1240 SCSI Host Adapter
-       1280  ISP1280 SCSI Host Adapter
-       2020  ISP2020A Fast!SCSI Basic Adapter
-       2100  QLA2100 64-bit Fibre Channel Adapter
-               1077 0001  QLA2100 64-bit Fibre Channel Adapter
-       2200  QLA2200 64-bit Fibre Channel Adapter
-               1077 0002  QLA2200
-       2300  QLA2300 64-bit Fibre Channel Adapter
-       2312  QLA2312 Fibre Channel Adapter
-1078  Cyrix Corporation
-       0000  5510 [Grappa]
-       0001  PCI Master
-       0002  5520 [Cognac]
-       0100  5530 Legacy [Kahlua]
-       0101  5530 SMI [Kahlua]
-       0102  5530 IDE [Kahlua]
-       0103  5530 Audio [Kahlua]
-       0104  5530 Video [Kahlua]
-       0400  ZFMicro PCI Bridge
-       0401  ZFMicro Chipset SMI
-       0402  ZFMicro Chipset IDE
-       0403  ZFMicro Expansion Bus
-1079  I-Bus
-107a  NetWorth
-107b  Gateway 2000
-107c  LG Electronics [Lucky Goldstar Co. Ltd]
-107d  LeadTek Research Inc.
-       0000  P86C850
-       2134  WinFast 3D S320 II
-       2971  [GeForce FX 5900] WinFast A350 TDH MyViVo
-107e  Interphase Corporation
-       0001  5515 ATM Adapter [Flipper]
-       0002  100 VG AnyLan Controller
-       0004  5526 Fibre Channel Host Adapter
-       0005  x526 Fibre Channel Host Adapter
-       0008  5525/5575 ATM Adapter (155 Mbit) [Atlantic]
-       9003  5535-4P-BRI-ST
-       9007  5535-4P-BRI-U
-       9008  5535-1P-SR
-       900c  5535-1P-SR-ST
-       900e  5535-1P-SR-U
-       9011  5535-1P-PRI
-       9013  5535-2P-PRI
-       9023  5536-4P-BRI-ST
-       9027  5536-4P-BRI-U
-       9031  5536-1P-PRI
-       9033  5536-2P-PRI
-107f  Data Technology Corporation
-       0802  SL82C105
-1080  Contaq Microsystems
-       0600  82C599
-       c691  Cypress CY82C691
-       c693  82c693
-1081  Supermac Technology
-       0d47  Radius PCI to NuBUS Bridge
-1082  EFA Corporation of America
-1083  Forex Computer Corporation
-       0001  FR710
-1084  Parador
-1085  Tulip Computers Int.B.V.
-1086  J. Bond Computer Systems
-1087  Cache Computer
-1088  Microcomputer Systems (M) Son
-1089  Data General Corporation
-# Formerly Bit3 Computer Corp.
-108a  SBS Technologies
-       0001  VME Bridge Model 617
-       0010  VME Bridge Model 618
-       0040  dataBLIZZARD
-       3000  VME Bridge Model 2706
-108c  Oakleigh Systems Inc.
-108d  Olicom
-       0001  Token-Ring 16/4 PCI Adapter (3136/3137)
-       0002  16/4 Token Ring
-       0004  RapidFire 3139 Token-Ring 16/4 PCI Adapter
-               108d 0004  OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
-       0005  GoCard 3250 Token-Ring 16/4 CardBus PC Card
-       0006  OC-3530 RapidFire Token-Ring 100
-       0007  RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
-               108d 0007  OC-3141 RapidFire Token-Ring 16/4 Adapter
-       0008  RapidFire 3540 HSTR 100/16/4 PCI Adapter
-               108d 0008  OC-3540 RapidFire HSTR 100/16/4 Adapter
-       0011  OC-2315
-       0012  OC-2325
-       0013  OC-2183/2185
-       0014  OC-2326
-       0019  OC-2327/2250 10/100 Ethernet Adapter
-               108d 0016  OC-2327 Rapidfire 10/100 Ethernet Adapter
-               108d 0017  OC-2250 GoCard 10/100 Ethernet Adapter
-       0021  OC-6151/6152 [RapidFire ATM 155]
-       0022  ATM Adapter
-108e  Sun Microsystems Computer Corp.
-       0001  EBUS
-       1000  EBUS
-       1001  Happy Meal
-       1100  RIO EBUS
-       1101  RIO GEM
-       1102  RIO 1394
-       1103  RIO USB
-       1648  [bge] Gigabit Ethernet
-       2bad  GEM
-       5000  Simba Advanced PCI Bridge
-       5043  SunPCI Co-processor
-       8000  Psycho PCI Bus Module
-       8001  Schizo PCI Bus Module
-       8002  Schizo+ PCI Bus Module
-       a000  Ultra IIi
-       a001  Ultra IIe
-       a801  Tomatillo PCI Bus Module
-       abba  Cassini 10/100/1000
-108f  Systemsoft
-1090  Encore Computer Corporation
-1091  Intergraph Corporation
-       0020  3D graphics processor
-       0021  3D graphics processor w/Texturing
-       0040  3D graphics frame buffer
-       0041  3D graphics frame buffer
-       0060  Proprietary bus bridge
-       00e4  Powerstorm 4D50T
-       0720  Motion JPEG codec
-       07a0  Sun Expert3D-Lite Graphics Accelerator
-       1091  Sun Expert3D Graphics Accelerator
-1092  Diamond Multimedia Systems
-       00a0  Speedstar Pro SE
-       00a8  Speedstar 64
-       0550  Viper V550
-       08d4  Supra 2260 Modem
-       094c  SupraExpress 56i Pro
-       1092  Viper V330
-       6120  Maximum DVD
-       8810  Stealth SE
-       8811  Stealth 64/SE
-       8880  Stealth
-       8881  Stealth
-       88b0  Stealth 64
-       88b1  Stealth 64
-       88c0  Stealth 64
-       88c1  Stealth 64
-       88d0  Stealth 64
-       88d1  Stealth 64
-       88f0  Stealth 64
-       88f1  Stealth 64
-       9999  DMD-I0928-1 "Monster sound" sound chip
-1093  National Instruments
-       0160  PCI-DIO-96
-       0162  PCI-MIO-16XE-50
-       1170  PCI-MIO-16XE-10
-       1180  PCI-MIO-16E-1
-       1190  PCI-MIO-16E-4
-       1310  PCI-6602
-       1330  PCI-6031E
-       1350  PCI-6071E
-       14e0  PCI-6110
-       14f0  PCI-6111
-       17d0  PCI-6503
-       1870  PCI-6713
-       1880  PCI-6711
-       18b0  PCI-6052E
-       2410  PCI-6733
-       2890  PCI-6036E
-       2a60  PCI-6023E
-       2a70  PCI-6024E
-       2a80  PCI-6025E
-       2c80  PCI-6035E
-       2ca0  PCI-6034E
-       70b8  PCI-6251 [M Series - High Speed Multifunction DAQ]
-       b001  IMAQ-PCI-1408
-       b011  IMAQ-PXI-1408
-       b021  IMAQ-PCI-1424
-       b031  IMAQ-PCI-1413
-       b041  IMAQ-PCI-1407
-       b051  IMAQ-PXI-1407
-       b061  IMAQ-PCI-1411
-       b071  IMAQ-PCI-1422
-       b081  IMAQ-PXI-1422
-       b091  IMAQ-PXI-1411
-       c801  PCI-GPIB
-       c831  PCI-GPIB bridge
-1094  First International Computers [FIC]
-1095  Silicon Image, Inc. (formerly CMD Technology Inc)
-       0240  Adaptec AAR-1210SA SATA HostRAID Controller
-       0640  PCI0640
-       0643  PCI0643
-       0646  PCI0646
-       0647  PCI0647
-       0648  PCI0648
-       0649  SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
-               0e11 005d  Integrated Ultra ATA-100 Dual Channel Controller
-               0e11 007e  Integrated Ultra ATA-100 IDE RAID Controller
-               101e 0649  AMI MegaRAID IDE 100 Controller
-       0650  PBC0650A
-       0670  USB0670
-               1095 0670  USB0670
-       0673  USB0673
-       0680  PCI0680 Ultra ATA-133 Host Controller
-               1095 3680  Winic W-680 (Silicon Image 680 based)
-       3112  SiI 3112 [SATALink/SATARaid] Serial ATA Controller
-               1095 3112  SiI 3112 SATALink Controller
-               1095 6112  SiI 3112 SATARaid Controller
-       3114  SiI 3114 [SATALink/SATARaid] Serial ATA Controller
-               1095 3114  SiI 3114 SATALink Controller
-               1095 6114  SiI 3114 SATARaid Controller
-       3124  SiI 3124 PCI-X Serial ATA Controller
-               1095 3124  SiI 3124 PCI-X Serial ATA Controller
-       3512  SiI 3512 [SATALink/SATARaid] Serial ATA Controller
-               1095 3512  SiI 3512 SATALink Controller
-               1095 6512  SiI 3512 SATARaid Controller
-1096  Alacron
-1097  Appian Technology
-1098  Quantum Designs (H.K.) Ltd
-       0001  QD-8500
-       0002  QD-8580
-1099  Samsung Electronics Co., Ltd
-109a  Packard Bell
-109b  Gemlight Computer Ltd.
-109c  Megachips Corporation
-109d  Zida Technologies Ltd.
-109e  Brooktree Corporation
-       0350  Bt848 Video Capture
-       0351  Bt849A Video capture
-       0369  Bt878 Video Capture
-               1002 0001  TV-Wonder
-               1002 0003  TV-Wonder/VE
-       036c  Bt879(??) Video Capture
-               13e9 0070  Win/TV (Video Section)
-       036e  Bt878 Video Capture
-               0070 13eb  WinTV Series
-               0070 ff01  Viewcast Osprey 200
-               0071 0101  DigiTV PCI
-               107d 6606  WinFast TV 2000
-               11bd 0012  PCTV pro (TV + FM stereo receiver)
-               11bd 001c  PCTV Sat (DBC receiver)
-               127a 0001  Bt878 Mediastream Controller NTSC
-               127a 0002  Bt878 Mediastream Controller PAL BG
-               127a 0003  Bt878a Mediastream Controller PAL BG
-               127a 0048  Bt878/832 Mediastream Controller
-               144f 3000  MagicTView CPH060 - Video
-               1461 0002  TV98 Series (TV/No FM/Remote)
-               1461 0003  AverMedia UltraTV PCI 350
-               1461 0004  AVerTV WDM Video Capture
-               1461 0761  AverTV DVB-T
-               14f1 0001  Bt878 Mediastream Controller NTSC
-               14f1 0002  Bt878 Mediastream Controller PAL BG
-               14f1 0003  Bt878a Mediastream Controller PAL BG
-               14f1 0048  Bt878/832 Mediastream Controller
-               1822 0001  VisionPlus DVB card
-               1851 1850  FlyVideo'98 - Video
-               1851 1851  FlyVideo II
-               1852 1852  FlyVideo'98 - Video (with FM Tuner)
-               270f fc00  Digitop DTT-1000
-               bd11 1200  PCTV pro (TV + FM stereo receiver)
-       036f  Bt879 Video Capture
-               127a 0044  Bt879 Video Capture NTSC
-               127a 0122  Bt879 Video Capture PAL I
-               127a 0144  Bt879 Video Capture NTSC
-               127a 0222  Bt879 Video Capture PAL BG
-               127a 0244  Bt879a Video Capture NTSC
-               127a 0322  Bt879 Video Capture NTSC
-               127a 0422  Bt879 Video Capture NTSC
-               127a 1122  Bt879 Video Capture PAL I
-               127a 1222  Bt879 Video Capture PAL BG
-               127a 1322  Bt879 Video Capture NTSC
-               127a 1522  Bt879a Video Capture PAL I
-               127a 1622  Bt879a Video Capture PAL BG
-               127a 1722  Bt879a Video Capture NTSC
-               14f1 0044  Bt879 Video Capture NTSC
-               14f1 0122  Bt879 Video Capture PAL I
-               14f1 0144  Bt879 Video Capture NTSC
-               14f1 0222  Bt879 Video Capture PAL BG
-               14f1 0244  Bt879a Video Capture NTSC
-               14f1 0322  Bt879 Video Capture NTSC
-               14f1 0422  Bt879 Video Capture NTSC
-               14f1 1122  Bt879 Video Capture PAL I
-               14f1 1222  Bt879 Video Capture PAL BG
-               14f1 1322  Bt879 Video Capture NTSC
-               14f1 1522  Bt879a Video Capture PAL I
-               14f1 1622  Bt879a Video Capture PAL BG
-               14f1 1722  Bt879a Video Capture NTSC
-               1851 1850  FlyVideo'98 - Video
-               1851 1851  FlyVideo II
-               1852 1852  FlyVideo'98 - Video (with FM Tuner)
-       0370  Bt880 Video Capture
-               1851 1850  FlyVideo'98
-               1851 1851  FlyVideo'98 EZ - video
-               1852 1852  FlyVideo'98 (with FM Tuner)
-       0878  Bt878 Audio Capture
-               0070 13eb  WinTV Series
-               0070 ff01  Viewcast Osprey 200
-               0071 0101  DigiTV PCI
-               1002 0001  TV-Wonder
-               1002 0003  TV-Wonder/VE
-               11bd 0012  PCTV pro (TV + FM stereo receiver, audio section)
-               11bd 001c  PCTV Sat (DBC receiver)
-               127a 0001  Bt878 Video Capture (Audio Section)
-               127a 0002  Bt878 Video Capture (Audio Section)
-               127a 0003  Bt878 Video Capture (Audio Section)
-               127a 0048  Bt878 Video Capture (Audio Section)
-               13e9 0070  Win/TV (Audio Section)
-               144f 3000  MagicTView CPH060 - Audio
-               1461 0004  AVerTV WDM Audio Capture
-               1461 0761  AVerTV DVB-T
-               14f1 0001  Bt878 Video Capture (Audio Section)
-               14f1 0002  Bt878 Video Capture (Audio Section)
-               14f1 0003  Bt878 Video Capture (Audio Section)
-               14f1 0048  Bt878 Video Capture (Audio Section)
-               1822 0001  VisionPlus DVB Card
-               270f fc00  Digitop DTT-1000
-               bd11 1200  PCTV pro (TV + FM stereo receiver, audio section)
-       0879  Bt879 Audio Capture
-               127a 0044  Bt879 Video Capture (Audio Section)
-               127a 0122  Bt879 Video Capture (Audio Section)
-               127a 0144  Bt879 Video Capture (Audio Section)
-               127a 0222  Bt879 Video Capture (Audio Section)
-               127a 0244  Bt879 Video Capture (Audio Section)
-               127a 0322  Bt879 Video Capture (Audio Section)
-               127a 0422  Bt879 Video Capture (Audio Section)
-               127a 1122  Bt879 Video Capture (Audio Section)
-               127a 1222  Bt879 Video Capture (Audio Section)
-               127a 1322  Bt879 Video Capture (Audio Section)
-               127a 1522  Bt879 Video Capture (Audio Section)
-               127a 1622  Bt879 Video Capture (Audio Section)
-               127a 1722  Bt879 Video Capture (Audio Section)
-               14f1 0044  Bt879 Video Capture (Audio Section)
-               14f1 0122  Bt879 Video Capture (Audio Section)
-               14f1 0144  Bt879 Video Capture (Audio Section)
-               14f1 0222  Bt879 Video Capture (Audio Section)
-               14f1 0244  Bt879 Video Capture (Audio Section)
-               14f1 0322  Bt879 Video Capture (Audio Section)
-               14f1 0422  Bt879 Video Capture (Audio Section)
-               14f1 1122  Bt879 Video Capture (Audio Section)
-               14f1 1222  Bt879 Video Capture (Audio Section)
-               14f1 1322  Bt879 Video Capture (Audio Section)
-               14f1 1522  Bt879 Video Capture (Audio Section)
-               14f1 1622  Bt879 Video Capture (Audio Section)
-               14f1 1722  Bt879 Video Capture (Audio Section)
-       0880  Bt880 Audio Capture
-       2115  BtV 2115 Mediastream controller
-       2125  BtV 2125 Mediastream controller
-       2164  BtV 2164
-       2165  BtV 2165
-       8230  Bt8230 ATM Segment/Reassembly Ctrlr (SRC)
-       8472  Bt8472
-       8474  Bt8474
-109f  Trigem Computer Inc.
-10a0  Meidensha Corporation
-10a1  Juko Electronics Ind. Co. Ltd
-10a2  Quantum Corporation
-10a3  Everex Systems Inc
-10a4  Globe Manufacturing Sales
-10a5  Smart Link Ltd.
-       3052  SmartPCI562 56K Modem
-       5449  SmartPCI561 modem
-10a6  Informtech Industrial Ltd.
-10a7  Benchmarq Microelectronics
-10a8  Sierra Semiconductor
-       0000  STB Horizon 64
-10a9  Silicon Graphics, Inc.
-       0001  Crosstalk to PCI Bridge
-       0002  Linc I/O controller
-       0003  IOC3 I/O controller
-       0004  O2 MACE
-       0005  RAD Audio
-       0006  HPCEX
-       0007  RPCEX
-       0008  DiVO VIP
-       0009  AceNIC Gigabit Ethernet
-               10a9 8002  AceNIC Gigabit Ethernet
-       0010  AMP Video I/O
-       0011  GRIP
-       0012  SGH PSHAC GSN
-       1001  Magic Carpet
-       1002  Lithium
-       1003  Dual JPEG 1
-       1004  Dual JPEG 2
-       1005  Dual JPEG 3
-       1006  Dual JPEG 4
-       1007  Dual JPEG 5
-       1008  Cesium
-       100a  IOC4 I/O controller
-       2001  Fibre Channel
-       2002  ASDE
-       8001  O2 1394
-       8002  G-net NT
-10aa  ACC Microelectronics
-       0000  ACCM 2188
-10ab  Digicom
-10ac  Honeywell IAC
-10ad  Symphony Labs
-       0001  W83769F
-       0003  SL82C103
-       0005  SL82C105
-       0103  SL82c103
-       0105  SL82c105
-       0565  W83C553
-10ae  Cornerstone Technology
-10af  Micro Computer Systems Inc
-10b0  CardExpert Technology
-10b1  Cabletron Systems Inc
-10b2  Raytheon Company
-10b3  Databook Inc
-       3106  DB87144
-       b106  DB87144
-10b4  STB Systems Inc
-       1b1d  Velocity 128 3D
-               10b4 237e  Velocity 4400
-10b5  PLX Technology, Inc.
-       0001  i960 PCI bus interface
-       1076  VScom 800 8 port serial adaptor
-       1077  VScom 400 4 port serial adaptor
-       1078  VScom 210 2 port serial and 1 port parallel adaptor
-       1103  VScom 200 2 port serial adaptor
-       1146  VScom 010 1 port parallel adaptor
-       1147  VScom 020 2 port parallel adaptor
-       2724  Thales PCSM Security Card
-       8516  PEX 8516  Versatile PCI Express Switch
-       8532  PEX 8532  Versatile PCI Express Switch
-       9030  PCI <-> IOBus Bridge Hot Swap
-               10b5 2862  Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
-               10b5 2906  Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
-               10b5 2940  Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
-               10b5 3025  Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
-               10b5 3068  Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
-               15ed 1002  MCCS 8-port Serial Hot Swap
-               15ed 1003  MCCS 16-port Serial Hot Swap
-       9036  9036
-       9050  PCI <-> IOBus Bridge
-               10b5 1067  IXXAT CAN i165
-               10b5 1172  IK220 (Heidenhain)
-               10b5 2036  SatPak GPS
-               10b5 2221  Alpermann+Velte PCL PCI LV: Timecode Reader Board
-               10b5 2273  SH-ARC SoHard ARCnet card
-               10b5 2431  Alpermann+Velte PCL PCI D: Timecode Reader Board
-               10b5 2905  Alpermann+Velte PCI TS: Time Synchronisation Board
-               10b5 9050  MP9050
-               1498 0362  TPMC866 8 Channel Serial Card
-               1522 0001  RockForce 4 Port V.90 Data/Fax/Voice Modem
-               1522 0002  RockForce 2 Port V.90 Data/Fax/Voice Modem
-               1522 0003  RockForce 6 Port V.90 Data/Fax/Voice Modem
-               1522 0004  RockForce 8 Port V.90 Data/Fax/Voice Modem
-               1522 0010  RockForce2000 4 Port V.90 Data/Fax/Voice Modem
-               1522 0020  RockForce2000 2 Port V.90 Data/Fax/Voice Modem
-               15ed 1000  Macrolink MCCS 8-port Serial
-               15ed 1001  Macrolink MCCS 16-port Serial
-               15ed 1002  Macrolink MCCS 8-port Serial Hot Swap
-               15ed 1003  Macrolink MCCS 16-port Serial Hot Swap
-# Sorry, there was a typo
-               5654 2036  OpenSwitch 6 Telephony card
-# Sorry, there was a typo
-               5654 3132  OpenSwitch 12 Telephony card
-               5654 5634  OpenLine4 Telephony Card
-               d531 c002  PCIntelliCAN 2xSJA1000 CAN bus
-               d84d 4006  EX-4006 1P
-               d84d 4008  EX-4008 1P EPP/ECP
-               d84d 4014  EX-4014 2P
-               d84d 4018  EX-4018 3P EPP/ECP
-               d84d 4025  EX-4025 1S(16C550) RS-232
-               d84d 4027  EX-4027 1S(16C650) RS-232
-               d84d 4028  EX-4028 1S(16C850) RS-232
-               d84d 4036  EX-4036 2S(16C650) RS-232
-               d84d 4037  EX-4037 2S(16C650) RS-232
-               d84d 4038  EX-4038 2S(16C850) RS-232
-               d84d 4052  EX-4052 1S(16C550) RS-422/485
-               d84d 4053  EX-4053 2S(16C550) RS-422/485
-               d84d 4055  EX-4055 4S(16C550) RS-232
-               d84d 4058  EX-4055 4S(16C650) RS-232
-               d84d 4065  EX-4065 8S(16C550) RS-232
-               d84d 4068  EX-4068 8S(16C650) RS-232
-               d84d 4078  EX-4078 2S(16C552) RS-232+1P
-       9054  PCI <-> IOBus Bridge
-               10b5 2455  Wessex Techology PHIL-PCI
-               10b5 2696  Innes Corp AM Radcap card
-               10b5 2717  Innes Corp Auricon card
-               10b5 2844  Innes Corp TVS Encoder card
-               12d9 0002  PCI Prosody Card rev 1.5
-               16df 0011  PIKA PrimeNet MM PCI
-               16df 0012  PIKA PrimeNet MM cPCI 8
-               16df 0013  PIKA PrimeNet MM cPCI 8 (without CAS Signaling Option)
-               16df 0014  PIKA PrimeNet MM cPCI 4
-               16df 0015  PIKA Daytona MM
-               16df 0016  PIKA InLine MM
-       9056  Francois
-               10b5 2979  CellinkBlade 11 - CPCI board VoATM AAL1
-       9060  9060
-       906d  9060SD
-               125c 0640  Aries 16000P
-       906e  9060ES
-       9080  9080
-               103c 10eb  (Agilent) E2777B 83K Series PCI based Optical Communication Interface
-               103c 10ec  (Agilent) E6978-66442 PCI CIC
-               10b5 9080  9080 [real subsystem ID not set]
-               129d 0002  Aculab PCI Prosidy card
-               12d9 0002  PCI Prosody Card
-               12df 4422  4422PCI ["Do-All" Telemetry Data Aquisition System]
-       bb04  B&B 3PCIOSD1A Isolated PCI Serial
-10b6  Madge Networks
-       0001  Smart 16/4 PCI Ringnode
-       0002  Smart 16/4 PCI Ringnode Mk2
-               10b6 0002  Smart 16/4 PCI Ringnode Mk2
-               10b6 0006  16/4 CardBus Adapter
-       0003  Smart 16/4 PCI Ringnode Mk3
-               0e11 b0fd  Compaq NC4621 PCI, 4/16, WOL
-               10b6 0003  Smart 16/4 PCI Ringnode Mk3
-               10b6 0007  Presto PCI Plus Adapter
-       0004  Smart 16/4 PCI Ringnode Mk1
-       0006  16/4 Cardbus Adapter
-               10b6 0006  16/4 CardBus Adapter
-       0007  Presto PCI Adapter
-               10b6 0007  Presto PCI
-       0009  Smart 100/16/4 PCI-HS Ringnode
-               10b6 0009  Smart 100/16/4 PCI-HS Ringnode
-       000a  Smart 100/16/4 PCI Ringnode
-               10b6 000a  Smart 100/16/4 PCI Ringnode
-       000b  16/4 CardBus Adapter Mk2
-               10b6 0008  16/4 CardBus Adapter Mk2
-               10b6 000b  16/4 Cardbus Adapter Mk2
-       000c  RapidFire 3140V2 16/4 TR Adapter
-               10b6 000c  RapidFire 3140V2 16/4 TR Adapter
-       1000  Collage 25/155 ATM Client Adapter
-       1001  Collage 155 ATM Server Adapter
-10b7  3Com Corporation
-       0001  3c985 1000BaseSX (SX/TX)
-       0013  AR5212 802.11abg NIC (3CRDAG675)
-               10b7 2031  3CRDAG675 11a/b/g Wireless PCI Adapter
-       0910  3C910-A01
-       1006  MINI PCI type 3B Data Fax Modem
-       1007  Mini PCI 56k Winmodem
-               10b7 615c  Mini PCI 56K Modem
-       1201  3c982-TXM 10/100baseTX Dual Port A [Hydra]
-       1202  3c982-TXM 10/100baseTX Dual Port B [Hydra]
-       1700  3c940 10/100/1000Base-T [Marvell]
-               1043 80eb  P4P800/K8V Deluxe motherboard
-               10b7 0010  3C940 Gigabit LOM Ethernet Adapter
-               10b7 0020  3C941 Gigabit LOM Ethernet Adapter
-               147b 1407  KV8-MAX3 motherboard
-       3390  3c339 TokenLink Velocity
-       3590  3c359 TokenLink Velocity XL
-               10b7 3590  TokenLink Velocity XL Adapter (3C359/359B)
-       4500  3c450 HomePNA [Tornado]
-       5055  3c555 Laptop Hurricane
-       5057  3c575 Megahertz 10/100 LAN CardBus [Boomerang]
-               10b7 5a57  3C575 Megahertz 10/100 LAN Cardbus PC Card
-       5157  3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
-               10b7 5b57  3C575 Megahertz 10/100 LAN Cardbus PC Card
-       5257  3cCFE575CT CardBus [Cyclone]
-               10b7 5c57  FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
-       5900  3c590 10BaseT [Vortex]
-       5920  3c592 EISA 10mbps Demon/Vortex
-       5950  3c595 100BaseTX [Vortex]
-       5951  3c595 100BaseT4 [Vortex]
-       5952  3c595 100Base-MII [Vortex]
-       5970  3c597 EISA Fast Demon/Vortex
-       5b57  3c595 Megahertz 10/100 LAN CardBus [Boomerang]
-               10b7 5b57  3C575 Megahertz 10/100 LAN Cardbus PC Card
-       6000  3CRSHPW796 [OfficeConnect Wireless CardBus]
-       6001  3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]
-       6055  3c556 Hurricane CardBus [Cyclone]
-       6056  3c556B CardBus [Tornado]
-               10b7 6556  10/100 Mini PCI Ethernet Adapter
-       6560  3cCFE656 CardBus [Cyclone]
-               10b7 656a  3CCFEM656 10/100 LAN+56K Modem CardBus
-       6561  3cCFEM656 10/100 LAN+56K Modem CardBus
-               10b7 656b  3CCFEM656 10/100 LAN+56K Modem CardBus
-       6562  3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
-               10b7 656b  3CCFEM656B 10/100 LAN+56K Modem CardBus
-       6563  3cCFEM656B 10/100 LAN+56K Modem CardBus
-               10b7 656b  3CCFEM656 10/100 LAN+56K Modem CardBus
-       6564  3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
-       7646  3cSOHO100-TX Hurricane
-       7770  3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect]
-       7940  3c803 FDDILink UTP Controller
-       7980  3c804 FDDILink SAS Controller
-       7990  3c805 FDDILink DAS Controller
-       80eb  3c940B 10/100/1000Base-T
-       8811  Token ring
-       9000  3c900 10BaseT [Boomerang]
-       9001  3c900 10Mbps Combo [Boomerang]
-       9004  3c900B-TPO Etherlink XL [Cyclone]
-               10b7 9004  3C900B-TPO Etherlink XL TPO 10Mb
-       9005  3c900B-Combo Etherlink XL [Cyclone]
-               10b7 9005  3C900B-Combo Etherlink XL Combo
-       9006  3c900B-TPC Etherlink XL [Cyclone]
-       900a  3c900B-FL 10base-FL [Cyclone]
-       9050  3c905 100BaseTX [Boomerang]
-       9051  3c905 100BaseT4 [Boomerang]
-       9055  3c905B 100BaseTX [Cyclone]
-               1028 0080  3C905B Fast Etherlink XL 10/100
-               1028 0081  3C905B Fast Etherlink XL 10/100
-               1028 0082  3C905B Fast Etherlink XL 10/100
-               1028 0083  3C905B Fast Etherlink XL 10/100
-               1028 0084  3C905B Fast Etherlink XL 10/100
-               1028 0085  3C905B Fast Etherlink XL 10/100
-               1028 0086  3C905B Fast Etherlink XL 10/100
-               1028 0087  3C905B Fast Etherlink XL 10/100
-               1028 0088  3C905B Fast Etherlink XL 10/100
-               1028 0089  3C905B Fast Etherlink XL 10/100
-               1028 0090  3C905B Fast Etherlink XL 10/100
-               1028 0091  3C905B Fast Etherlink XL 10/100
-               1028 0092  3C905B Fast Etherlink XL 10/100
-               1028 0093  3C905B Fast Etherlink XL 10/100
-               1028 0094  3C905B Fast Etherlink XL 10/100
-               1028 0095  3C905B Fast Etherlink XL 10/100
-               1028 0096  3C905B Fast Etherlink XL 10/100
-               1028 0097  3C905B Fast Etherlink XL 10/100
-               1028 0098  3C905B Fast Etherlink XL 10/100
-               1028 0099  3C905B Fast Etherlink XL 10/100
-               10b7 9055  3C905B Fast Etherlink XL 10/100
-       9056  3c905B-T4 Fast EtherLink XL [Cyclone]
-       9058  3c905B Deluxe Etherlink 10/100/BNC [Cyclone]
-       905a  3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]
-       9200  3c905C-TX/TX-M [Tornado]
-               1028 0095  3C920 Integrated Fast Ethernet Controller
-               1028 0097  3C920 Integrated Fast Ethernet Controller
-               1028 00fe  Optiplex GX240
-               1028 012a  3C920 Integrated Fast Ethernet Controller [Latitude C640]
-               10b7 1000  3C905C-TX Fast Etherlink for PC Management NIC
-               10b7 7000  10/100 Mini PCI Ethernet Adapter
-               10f1 2466  Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
-       9201  3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
-               1043 80ab  A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
-       9202  3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
-       9210  3C920B-EMB-WNM Integrated Fast Ethernet Controller
-       9300  3CSOHO100B-TX 910-A01 [tulip]
-       9800  3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
-               10b7 9800  3c980-TX Fast Etherlink XL Server Adapter
-       9805  3c980-C 10/100baseTX NIC [Python-T]
-               10b7 1201  EtherLink Server 10/100 Dual Port A
-               10b7 1202  EtherLink Server 10/100 Dual Port B
-               10b7 9805  3c980 10/100baseTX NIC [Python-T]
-               10f1 2462  Thunder K7 S2462
-       9900  3C990-TX [Typhoon]
-       9902  3CR990-TX-95 [Typhoon 56-bit]
-       9903  3CR990-TX-97 [Typhoon 168-bit]
-       9904  3C990B-TX-M/3C990BSVR [Typhoon2]
-               10b7 1000  3CR990B-TX-M [Typhoon2]
-               10b7 2000  3CR990BSVR [Typhoon2 Server]
-       9905  3CR990-FX-95/97/95 [Typhon Fiber]
-               10b7 1101  3CR990-FX-95 [Typhoon Fiber 56-bit]
-               10b7 1102  3CR990-FX-97 [Typhoon Fiber 168-bit]
-               10b7 2101  3CR990-FX-95 Server [Typhoon Fiber 56-bit]
-               10b7 2102  3CR990-FX-97 Server [Typhoon Fiber 168-bit]
-       9908  3CR990SVR95 [Typhoon Server 56-bit]
-       9909  3CR990SVR97 [Typhoon Server 168-bit]
-       990a  3C990SVR [Typhoon Server]
-       990b  3C990SVR [Typhoon Server]
-10b8  Standard Microsystems Corp [SMC]
-       0005  83c170 EPIC/100 Fast Ethernet Adapter
-               1055 e000  LANEPIC 10/100 [EVB171Q-PCI]
-               1055 e002  LANEPIC 10/100 [EVB171G-PCI]
-               10b8 a011  EtherPower II 10/100
-               10b8 a014  EtherPower II 10/100
-               10b8 a015  EtherPower II 10/100
-               10b8 a016  EtherPower II 10/100
-               10b8 a017  EtherPower II 10/100
-       0006  83c175 EPIC/100 Fast Ethernet Adapter
-               1055 e100  LANEPIC Cardbus Fast Ethernet Adapter
-               1055 e102  LANEPIC Cardbus Fast Ethernet Adapter
-               1055 e300  LANEPIC Cardbus Fast Ethernet Adapter
-               1055 e302  LANEPIC Cardbus Fast Ethernet Adapter
-               10b8 a012  LANEPIC Cardbus Fast Ethernet Adapter
-               13a2 8002  LANEPIC Cardbus Fast Ethernet Adapter
-               13a2 8006  LANEPIC Cardbus Fast Ethernet Adapter
-       1000  FDC 37c665
-       1001  FDC 37C922
-# 802.11g card
-       2802  SMC2802W [EZ Connect g]
-       a011  83C170QF
-       b106  SMC34C90
-10b9  ALi Corporation
-       0101  CMI8338/C3DX PCI Audio Device
-       0111  C-Media CMI8738/C3DX Audio Device (OEM)
-               10b9 0111  C-Media CMI8738/C3DX Audio Device (OEM)
-       0780  Multi-IO Card
-       0782  Multi-IO Card
-       1435  M1435
-       1445  M1445
-       1449  M1449
-       1451  M1451
-       1461  M1461
-       1489  M1489
-       1511  M1511 [Aladdin]
-       1512  M1512 [Aladdin]
-       1513  M1513 [Aladdin]
-       1521  M1521 [Aladdin III]
-               10b9 1521  ALI M1521 Aladdin III CPU Bridge
-       1523  M1523
-               10b9 1523  ALI M1523 ISA Bridge
-       1531  M1531 [Aladdin IV]
-       1533  M1533 PCI to ISA Bridge [Aladdin IV]
-               1014 053b  ThinkPad R40e (2684-HVG) PCI to ISA Bridge
-               10b9 1533  ALI M1533 Aladdin IV ISA Bridge
-       1541  M1541
-               10b9 1541  ALI M1541 Aladdin V/V+ AGP System Controller
-       1543  M1543
-       1563  M1563 HyperTransport South Bridge
-       1621  M1621
-       1631  ALI M1631 PCI North Bridge Aladdin Pro III
-       1632  M1632M Northbridge+Trident
-       1641  ALI M1641 PCI North Bridge Aladdin Pro IV
-       1644  M1644/M1644T Northbridge+Trident
-       1646  M1646 Northbridge+Trident
-       1647  M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
-       1651  M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
-       1671  M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
-       1672  M1672 Northbridge [CyberALADDiN-P4]
-       1681  M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
-       1687  M1687 K8 Northbridge [AGP8X and HyperTransport]
-       1689  M1689 K8 Northbridge [Super K8 Single Chip]
-       3141  M3141
-       3143  M3143
-       3145  M3145
-       3147  M3147
-       3149  M3149
-       3151  M3151
-       3307  M3307
-       3309  M3309
-       3323  M3325 Video/Audio Decoder
-       5212  M4803
-       5215  MS4803
-       5217  M5217H
-       5219  M5219
-       5225  M5225
-       5228  M5228 ALi ATA/RAID Controller
-       5229  M5229 IDE
-               1014 050f  ThinkPad R30
-               1014 053d  ThinkPad R40e (2684-HVG) builtin IDE
-               103c 0024  Pavilion ze4400 builtin IDE
-               1043 8053  A7A266 Motherboard IDE
-       5235  M5225
-       5237  USB 1.1 Controller
-               1014 0540  ThinkPad R40e (2684-HVG) builtin USB
-               103c 0024  Pavilion ze4400 builtin USB
-       5239  USB 2.0 Controller
-       5243  M1541 PCI to AGP Controller
-       5246  AGP8X Controller
-       5247  PCI to AGP Controller
-       5249  M5249 HTT to PCI Bridge
-       5251  M5251 P1394 OHCI 1.0 Controller
-       5253  M5253 P1394 OHCI 1.1 Controller
-       5261  M5261 Ethernet Controller
-       5263  M5263 Ethernet Controller
-       5281  ALi M5281 Serial ATA / RAID Host Controller
-       5287  ULi 5287 SATA
-       5289  ULi 5289 SATA
-       5450  Lucent Technologies Soft Modem AMR
-       5451  M5451 PCI AC-Link Controller Audio Device
-               1014 0506  ThinkPad R30
-               1014 053e  ThinkPad R40e (2684-HVG) builtin Audio
-               103c 0024  Pavilion ze4400 builtin Audio
-               10b9 5451  HP Compaq nc4010 (DY885AA#ABN)
-       5453  M5453 PCI AC-Link Controller Modem Device
-       5455  M5455 PCI AC-Link Controller Audio Device
-       5457  M5457 AC'97 Modem Controller
-               1014 0535  ThinkPad R40e (2684-HVG) builtin modem
-               103c 0024  Pavilion ze4400 builtin Modem Device
-# Same but more usefull for driver's lookup
-       5459  SmartLink SmartPCI561 56K Modem
-# SmartLink PCI SoftModem
-       545a  SmartLink SmartPCI563 56K Modem
-       5471  M5471 Memory Stick Controller
-       5473  M5473 SD-MMC Controller
-       7101  M7101 Power Management Controller [PMU]
-               1014 0510  ThinkPad R30
-               1014 053c  ThinkPad R40e (2684-HVG) Power Management Controller
-               103c 0024  Pavilion ze4400
-10ba  Mitsubishi Electric Corp.
-       0301  AccelGraphics AccelECLIPSE
-       0304  AccelGALAXY A2100 [OEM Evans & Sutherland]
-       0308  Tornado 3000 [OEM Evans & Sutherland]
-       1002  VG500 [VolumePro Volume Rendering Accelerator]
-10bb  Dapha Electronics Corporation
-10bc  Advanced Logic Research
-10bd  Surecom Technology
-       0e34  NE-34
-10be  Tseng Labs International Co.
-10bf  Most Inc
-10c0  Boca Research Inc.
-10c1  ICM Co., Ltd.
-10c2  Auspex Systems Inc.
-10c3  Samsung Semiconductors, Inc.
-       1100  Smartether100 SC1100 LAN Adapter (i82557B)
-10c4  Award Software International Inc.
-10c5  Xerox Corporation
-10c6  Rambus Inc.
-10c7  Media Vision
-10c8  Neomagic Corporation
-       0001  NM2070 [MagicGraph 128]
-       0002  NM2090 [MagicGraph 128V]
-       0003  NM2093 [MagicGraph 128ZV]
-       0004  NM2160 [MagicGraph 128XD]
-               1014 00ba  MagicGraph 128XD
-               1025 1007  MagicGraph 128XD
-               1028 0074  MagicGraph 128XD
-               1028 0075  MagicGraph 128XD
-               1028 007d  MagicGraph 128XD
-               1028 007e  MagicGraph 128XD
-               1033 802f  MagicGraph 128XD
-               104d 801b  MagicGraph 128XD
-               104d 802f  MagicGraph 128XD
-               104d 830b  MagicGraph 128XD
-               10ba 0e00  MagicGraph 128XD
-               10c8 0004  MagicGraph 128XD
-               10cf 1029  MagicGraph 128XD
-               10f7 8308  MagicGraph 128XD
-               10f7 8309  MagicGraph 128XD
-               10f7 830b  MagicGraph 128XD
-               10f7 830d  MagicGraph 128XD
-               10f7 8312  MagicGraph 128XD
-       0005  NM2200 [MagicGraph 256AV]
-               1014 00dd  ThinkPad 570
-               1028 0088  Latitude CPi A
-       0006  NM2360 [MagicMedia 256ZX]
-       0016  NM2380 [MagicMedia 256XL+]
-               10c8 0016  MagicMedia 256XL+
-       0025  NM2230 [MagicGraph 256AV+]
-       0083  NM2093 [MagicGraph 128ZV+]
-       8005  NM2200 [MagicMedia 256AV Audio]
-               0e11 b0d1  MagicMedia 256AV Audio Device on Discovery
-               0e11 b126  MagicMedia 256AV Audio Device on Durango
-               1014 00dd  MagicMedia 256AV Audio Device on BlackTip Thinkpad
-               1025 1003  MagicMedia 256AV Audio Device on TravelMate 720
-               1028 0088  Latitude CPi A
-               1028 008f  MagicMedia 256AV Audio Device on Colorado Inspiron
-               103c 0007  MagicMedia 256AV Audio Device on Voyager II
-               103c 0008  MagicMedia 256AV Audio Device on Voyager III
-               103c 000d  MagicMedia 256AV Audio Device on Omnibook 900
-               10c8 8005  MagicMedia 256AV Audio Device on FireAnt
-               110a 8005  MagicMedia 256AV Audio Device
-               14c0 0004  MagicMedia 256AV Audio Device
-       8006  NM2360 [MagicMedia 256ZX Audio]
-       8016  NM2380 [MagicMedia 256XL+ Audio]
-10c9  Dataexpert Corporation
-10ca  Fujitsu Microelectr., Inc.
-10cb  Omron Corporation
-# nee Mentor ARC Inc
-10cc  Mai Logic Incorporated
-       0660  Articia S Host Bridge
-       0661  Articia S PCI Bridge
-10cd  Advanced System Products, Inc
-       1100  ASC1100
-       1200  ASC1200 [(abp940) Fast SCSI-II]
-       1300  ABP940-U / ABP960-U
-               10cd 1310  ASC1300 SCSI Adapter
-       2300  ABP940-UW
-       2500  ABP940-U2W
-10ce  Radius
-# nee Citicorp TTI
-10cf  Fujitsu Limited.
-       2001  mb86605
-10d1  FuturePlus Systems Corp.
-10d2  Molex Incorporated
-10d3  Jabil Circuit Inc
-10d4  Hualon Microelectronics
-10d5  Autologic Inc.
-10d6  Cetia
-10d7  BCM Advanced Research
-10d8  Advanced Peripherals Labs
-10d9  Macronix, Inc. [MXIC]
-       0431  MX98715
-       0512  MX98713
-       0531  MX987x5
-               1186 1200  DFE-540TX ProFAST 10/100 Adapter
-       8625  MX86250
-       8888  MX86200
-10da  Compaq IPG-Austin
-       0508  TC4048 Token Ring 4/16
-       3390  Tl3c3x9
-10db  Rohm LSI Systems, Inc.
-10dc  CERN/ECP/EDU
-       0001  STAR/RD24 SCI-PCI (PMC)
-       0002  TAR/RD24 SCI-PCI (PMC)
-       0021  HIPPI destination
-       0022  HIPPI source
-       10dc  ATT2C15-3 FPGA
-10dd  Evans & Sutherland
-10de  nVidia Corporation
-       0008  NV1 [EDGE 3D]
-       0009  NV1 [EDGE 3D]
-       0010  NV2 [Mutara V08]
-       0020  NV4 [RIVA TNT]
-               1043 0200  V3400 TNT
-               1048 0c18  Erazor II SGRAM
-               1048 0c1b  Erazor II
-               1092 0550  Viper V550
-               1092 0552  Viper V550
-               1092 4804  Viper V550
-               1092 4808  Viper V550
-               1092 4810  Viper V550
-               1092 4812  Viper V550
-               1092 4815  Viper V550
-               1092 4820  Viper V550 with TV out
-               1092 4822  Viper V550
-               1092 4904  Viper V550
-               1092 4914  Viper V550
-               1092 8225  Viper V550
-               10b4 273d  Velocity 4400
-               10b4 273e  Velocity 4400
-               10b4 2740  Velocity 4400
-               10de 0020  Riva TNT
-               1102 1015  Graphics Blaster CT6710
-               1102 1016  Graphics Blaster RIVA TNT
-       0028  NV5 [RIVA TNT2/TNT2 Pro]
-               1043 0200  AGP-V3800 SGRAM
-               1043 0201  AGP-V3800 SDRAM
-               1043 0205  PCI-V3800
-               1043 4000  AGP-V3800PRO
-               1048 0c21  Synergy II
-               1048 0c31  Erazor III
-               107d 2134  WinFast 3D S320 II + TV-Out
-               1092 4804  Viper V770
-               1092 4a00  Viper V770
-               1092 4a02  Viper V770 Ultra
-               1092 5a00  RIVA TNT2/TNT2 Pro
-               1092 6a02  Viper V770 Ultra
-               1092 7a02  Viper V770 Ultra
-               10de 0005  RIVA TNT2 Pro
-               10de 000f  Compaq NVIDIA TNT2 Pro
-               1102 1020  3D Blaster RIVA TNT2
-               1102 1026  3D Blaster RIVA TNT2 Digital
-               14af 5810  Maxi Gamer Xentor
-       0029  NV5 [RIVA TNT2 Ultra]
-               1043 0200  AGP-V3800 Deluxe
-               1043 0201  AGP-V3800 Ultra SDRAM
-               1043 0205  PCI-V3800 Ultra
-               1102 1021  3D Blaster RIVA TNT2 Ultra
-               1102 1029  3D Blaster RIVA TNT2 Ultra
-               1102 102f  3D Blaster RIVA TNT2 Ultra
-               14af 5820  Maxi Gamer Xentor 32
-       002a  NV5 [Riva TnT2]
-       002b  NV5 [Riva TnT2]
-       002c  NV6 [Vanta/Vanta LT]
-               1043 0200  AGP-V3800 Combat SDRAM
-               1043 0201  AGP-V3800 Combat
-               1092 6820  Viper V730
-               1102 1031  CT6938 VANTA 8MB
-               1102 1034  CT6894 VANTA 16MB
-               14af 5008  Maxi Gamer Phoenix 2
-       002d  NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
-               1043 0200  AGP-V3800M
-               1043 0201  AGP-V3800M
-               1048 0c3a  Erazor III LT
-               10de 001e  M64 AGP4x
-               1102 1023  CT6892 RIVA TNT2 Value
-               1102 1024  CT6932 RIVA TNT2 Value 32Mb
-               1102 102c  CT6931 RIVA TNT2 Value [Jumper]
-               1462 8808  MSI-8808
-               1554 1041  Pixelview RIVA TNT2 M64
-               1569 002d  Palit Microsystems Daytona TNT2 M64
-       002e  NV6 [Vanta]
-       002f  NV6 [Vanta]
-       0034  MCP04 SMBus
-       0035  MCP04 IDE
-       0036  MCP04 Serial ATA Controller
-       0037  MCP04 Ethernet Controller
-       0038  MCP04 Ethernet Controller
-       003a  MCP04 AC'97 Audio Controller
-       003b  MCP04 USB Controller
-       003c  MCP04 USB Controller
-       003d  MCP04 PCI Bridge
-       003e  MCP04 Serial ATA Controller
-       0040  nv40 [GeForce 6800 Ultra]
-       0041  NV40 [GeForce 6800]
-       0042  NV40.2
-       0043  NV40.3
-       0045  NV40 [GeForce 6800 GT]
-       0049  NV40GL
-       004e  NV40GL [Quadro FX 4000]
-       0051  CK804 ISA Bridge
-       0052  CK804 SMBus
-       0053  CK804 IDE
-       0054  CK804 Serial ATA Controller
-       0055  CK804 Serial ATA Controller
-       0056  CK804 Ethernet Controller
-       0057  CK804 Ethernet Controller
-       0059  CK804 AC'97 Audio Controller
-       005a  CK804 USB Controller
-       005b  CK804 USB Controller
-       005c  CK804 PCI Bridge
-       005d  CK804 PCIE Bridge
-       005e  CK804 Memory Controller
-       0060  nForce2 ISA Bridge
-               1043 80ad  A7N8X Mainboard
-       0064  nForce2 SMBus (MCP)
-       0065  nForce2 IDE
-       0066  nForce2 Ethernet Controller
-               1043 80a7  A7N8X Mainboard onboard nForce2 Ethernet
-       0067  nForce2 USB Controller
-               1043 0c11  A7N8X Mainboard
-       0068  nForce2 USB Controller
-               1043 0c11  A7N8X Mainboard
-       006a  nForce2 AC97 Audio Controler (MCP)
-       006b  nForce Audio Processing Unit
-               10de 006b  nForce2 MCP Audio Processing Unit
-       006c  nForce2 External PCI Bridge
-       006d  nForce2 PCI Bridge
-       006e  nForce2 FireWire (IEEE 1394) Controller
-       0084  MCP2A SMBus
-       0085  MCP2A IDE
-       0086  MCP2A Ethernet Controller
-       0087  MCP2A USB Controller
-       0088  MCP2A USB Controller
-       008a  MCP2S AC'97 Audio Controller
-       008b  MCP2A PCI Bridge
-       008c  MCP2A Ethernet Controller
-       008e  nForce2 Serial ATA Controller
-       00a0  NV5 [Aladdin TNT2]
-               14af 5810  Maxi Gamer Xentor
-       00c0  NV41.0
-       00c1  NV41.1
-       00c2  NV41.2
-       00c8  NV41.8
-       00ce  NV41GL
-       00d0  nForce3 LPC Bridge
-       00d1  nForce3 Host Bridge
-       00d2  nForce3 AGP Bridge
-       00d3  CK804 Memory Controller
-       00d4  nForce3 SMBus
-       00d5  nForce3 IDE
-       00d6  nForce3 Ethernet
-       00d7  nForce3 USB 1.1
-       00d8  nForce3 USB 2.0
-       00da  nForce3 Audio
-       00dd  nForce3 PCI Bridge
-       00df  CK8S Ethernet Controller
-       00e0  nForce3 250Gb LPC Bridge
-       00e1  nForce3 250Gb Host Bridge
-       00e2  nForce3 250Gb AGP Host to PCI Bridge
-       00e3  CK8S Serial ATA Controller (v2.5)
-       00e4  nForce 250Gb PCI System Management
-       00e5  CK8S Parallel ATA Controller (v2.5)
-       00e6  CK8S Ethernet Controller
-       00e7  CK8S USB Controller
-       00e8  nForce3 EHCI USB 2.0 Controller
-       00ea  nForce3 250Gb AC'97 Audio Controller
-       00ed  nForce3 250Gb PCI-to-PCI Bridge
-       00ee  CK8S Serial ATA Controller (v2.5)
-       00f0  NV40 [GeForce 6800/GeForce 6800 Ultra]
-       00f1  NV43 [GeForce 6600/GeForce 6600 GT]
-       00f2  NV43 [GeForce 6600 GT]
-       00f8  NV45GL [Quadro FX 3400]
-       00f9  NV40 [GeForce 6800 Ultra/GeForce 6800 GT]
-               1682 2120  GEFORCE 6800 GT PCI-E
-       00fa  NV36 [GeForce PCX 5750]
-       00fb  NV35 [GeForce PCX 5900]
-       00fc  NV37GL [Quadro FX 330/GeForce PCX 5300]
-       00fd  NV37GL [Quadro FX 330]
-       00fe  NV38GL [Quadro FX 1300]
-       00ff  NV18 [GeForce PCX 4300]
-       0100  NV10 [GeForce 256 SDR]
-               1043 0200  AGP-V6600 SGRAM
-               1043 0201  AGP-V6600 SDRAM
-               1043 4008  AGP-V6600 SGRAM
-               1043 4009  AGP-V6600 SDRAM
-               1102 102d  CT6941 GeForce 256
-               14af 5022  3D Prophet SE
-       0101  NV10DDR [GeForce 256 DDR]
-               1043 0202  AGP-V6800 DDR
-               1043 400a  AGP-V6800 DDR SGRAM
-               1043 400b  AGP-V6800 DDR SDRAM
-               107d 2822  WinFast GeForce 256
-               1102 102e  CT6971 GeForce 256 DDR
-               14af 5021  3D Prophet DDR-DVI
-       0103  NV10GL [Quadro]
-       0110  NV11 [GeForce2 MX/MX 400]
-               1043 4015  AGP-V7100 Pro
-               1043 4031  V7100 Pro with TV output
-               10de 0091  Dell OEM GeForce 2 MX 400
-               1462 8817  MSI GeForce2 MX400 Pro32S [MS-8817]
-               14af 7102  3D Prophet II MX
-               14af 7103  3D Prophet II MX Dual-Display
-       0111  NV11DDR [GeForce2 MX 100 DDR/200 DDR]
-       0112  NV11 [GeForce2 Go]
-       0113  NV11GL [Quadro2 MXR/EX]
-       0140  NV43 [MSI NX6600GT-TD128E]
-       014f  NV43 [GeForce 6200]
-       0150  NV15 [GeForce2 GTS/Pro]
-               1043 4016  V7700 AGP Video Card
-               107d 2840  WinFast GeForce2 GTS with TV output
-               107d 2842  WinFast GeForce 2 Pro
-               1462 8831  Creative GeForce2 Pro
-       0151  NV15DDR [GeForce2 Ti]
-               1043 405f  V7700Ti
-               1462 5506  Creative 3D Blaster Geforce2 Titanium
-       0152  NV15BR [GeForce2 Ultra, Bladerunner]
-               1048 0c56  GLADIAC Ultra
-       0153  NV15GL [Quadro2 Pro]
-       0170  NV17 [GeForce4 MX 460]
-       0171  NV17 [GeForce4 MX 440]
-               10b0 0002  Gainward Pro/600 TV
-               1462 8661  G4MX440-VTP
-               1462 8730  MX440SES-T (MS-8873)
-               147b 8f00  Abit Siluro GeForce4MX440
-       0172  NV17 [GeForce4 MX 420]
-       0173  NV17 [GeForce4 MX 440-SE]
-       0174  NV17 [GeForce4 440 Go]
-       0175  NV17 [GeForce4 420 Go]
-       0176  NV17 [GeForce4 420 Go 32M]
-               4c53 1090  Cx9 / Vx9 mainboard
-       0177  NV17 [GeForce4 460 Go]
-       0178  NV17GL [Quadro4 550 XGL]
-       0179  NV17 [GeForce4 440 Go 64M]
-               10de 0179  GeForce4 MX (Mac)
-       017a  NV17GL [Quadro4 200/400 NVS]
-       017b  NV17GL [Quadro4 550 XGL]
-       017c  NV17GL [Quadro4 550 GoGL]
-       017d  NV17 [GeForce4 410 Go 16M]
-       0181  NV18 [GeForce4 MX 440 AGP 8x]
-               1043 806f  V9180 Magic
-               1462 8880  MS-StarForce GeForce4 MX 440 with AGP8X
-               1462 8900  MS-8890 GeForce 4 MX440 AGP8X
-               1462 9350  MSI Geforce4 MX T8X with AGP8X
-               147b 8f0d  Siluro GF4 MX-8X
-       0182  NV18 [GeForce4 MX 440SE AGP 8x]
-       0183  NV18 [GeForce4 MX 420 AGP 8x]
-       0185  NV18 [GeForce4 MX 4000 AGP 8x]
-       0186  NV18M [GeForce4 448 Go]
-       0187  NV18M [GeForce4 488 Go]
-       0188  NV18GL [Quadro4 580 XGL]
-       018a  NV18GL [Quadro4 NVS AGP 8x]
-       018b  NV18GL [Quadro4 380 XGL]
-       018d  NV18M [GeForce4 448 Go]
-       01a0  NVCrush11 [GeForce2 MX Integrated Graphics]
-       01a4  nForce CPU bridge
-       01ab  nForce 420 Memory Controller (DDR)
-       01ac  nForce 220/420 Memory Controller
-       01ad  nForce 220/420 Memory Controller
-       01b0  nForce Audio
-       01b1  nForce Audio
-       01b2  nForce ISA Bridge
-       01b4  nForce PCI System Management
-       01b7  nForce AGP to PCI Bridge
-       01b8  nForce PCI-to-PCI bridge
-       01bc  nForce IDE
-       01c1  nForce AC'97 Modem Controller
-       01c2  nForce USB Controller
-       01c3  nForce Ethernet Controller
-       01e0  nForce2 AGP (different version?)
-       01e8  nForce2 AGP
-       01ea  nForce2 Memory Controller 0
-       01eb  nForce2 Memory Controller 1
-       01ec  nForce2 Memory Controller 2
-       01ed  nForce2 Memory Controller 3
-       01ee  nForce2 Memory Controller 4
-       01ef  nForce2 Memory Controller 5
-       01f0  NV18 [GeForce4 MX - nForce GPU]
-       0200  NV20 [GeForce3]
-               1043 402f  AGP-V8200 DDR
-       0201  NV20 [GeForce3 Ti 200]
-       0202  NV20 [GeForce3 Ti 500]
-               1043 405b  V8200 T5
-               1545 002f  Xtasy 6964
-       0203  NV20DCC [Quadro DCC]
-       0240  C51 PCI Express Bridge
-       0241  C51 PCI Express Bridge
-       0242  C51 PCI Express Bridge
-       0243  C51 PCI Express Bridge
-       0244  C51 PCI Express Bridge
-       0245  C51 PCI Express Bridge
-       0246  C51 PCI Express Bridge
-       0247  C51 PCI Express Bridge
-       0248  C51 PCI Express Bridge
-       0249  C51 PCI Express Bridge
-       024a  C51 PCI Express Bridge
-       024b  C51 PCI Express Bridge
-       024c  C51 PCI Express Bridge
-       024d  C51 PCI Express Bridge
-       024e  C51 PCI Express Bridge
-       024f  C51 PCI Express Bridge
-       0250  NV25 [GeForce4 Ti 4600]
-       0251  NV25 [GeForce4 Ti 4400]
-               1043 8023  v8440 GeForce 4 Ti4400
-       0252  NV25 [GeForce4 Ti]
-       0253  NV25 [GeForce4 Ti 4200]
-               107d 2896  WinFast A250 LE TD (Dual VGA/TV-out/DVI)
-               147b 8f09  Siluro (Dual VGA/TV-out/DVI)
-       0258  NV25GL [Quadro4 900 XGL]
-       0259  NV25GL [Quadro4 750 XGL]
-       025b  NV25GL [Quadro4 700 XGL]
-       0260  MCP51 LPC Bridge
-       0261  MCP51 LPC Bridge
-       0262  MCP51 LPC Bridge
-       0263  MCP51 LPC Bridge
-       0264  MCP51 SMBus
-       0265  MCP51 IDE
-       0266  MCP51 Serial ATA Controller
-       0267  MCP51 Serial ATA Controller
-       0268  MCP51 Ethernet Controller
-       0269  MCP51 Ethernet Controller
-       026a  MCP51 MCI
-       026b  MCP51 AC97 Audio Controller
-       026c  MCP51 High Definition Audio
-       026d  MCP51 USB Controller
-       026e  MCP51 USB Controller
-       026f  MCP51 PCI Bridge
-       0270  MCP51 Host Bridge
-       0271  MCP51 PMU
-       0272  MCP51 Memory Controller 0
-       027e  C51 Memory Controller 2
-       027f  C51 Memory Controller 3
-       0280  NV28 [GeForce4 Ti 4800]
-       0281  NV28 [GeForce4 Ti 4200 AGP 8x]
-       0282  NV28 [GeForce4 Ti 4800 SE]
-       0286  NV28 [GeForce4 Ti 4200 Go AGP 8x]
-       0288  NV28GL [Quadro4 980 XGL]
-       0289  NV28GL [Quadro4 780 XGL]
-       028c  NV28GLM [Quadro4 700 GoGL]
-       02f0  C51 Host Bridge
-       02f1  C51 Host Bridge
-       02f2  C51 Host Bridge
-       02f3  C51 Host Bridge
-       02f4  C51 Host Bridge
-       02f5  C51 Host Bridge
-       02f6  C51 Host Bridge
-       02f7  C51 Host Bridge
-       02f8  C51 Memory Controller 5
-       02f9  C51 Memory Controller 4
-       02fa  C51 Memory Controller 0
-       02fb  C51 PCI Express Bridge
-       02fc  C51 PCI Express Bridge
-       02fd  C51 PCI Express Bridge
-       02fe  C51 Memory Controller 1
-       02ff  C51 Host Bridge
-       0300  NV30 [GeForce FX]
-       0301  NV30 [GeForce FX 5800 Ultra]
-       0302  NV30 [GeForce FX 5800]
-       0308  NV30GL [Quadro FX 2000]
-       0309  NV30GL [Quadro FX 1000]
-       0311  NV31 [GeForce FX 5600 Ultra]
-       0312  NV31 [GeForce FX 5600]
-       0313  NV31
-       0314  NV31 [GeForce FX 5600XT]
-               1043 814a  V9560XT/TD
-       0316  NV31
-       0317  NV31
-       031a  NV31M [GeForce FX Go 5600]
-       031b  NV31M [GeForce FX Go5650]
-       031c  NVIDIA Quadro FX 700 Go
-       031d  NV31
-       031e  NV31
-       031f  NV31
-       0320  NV34 [GeForce FX 5200]
-       0321  NV34 [GeForce FX 5200 Ultra]
-       0322  NV34 [GeForce FX 5200]
-               1462 9171  MS-8917 (FX5200-T128)
-       0323  NV34 [GeForce FX 5200LE]
-       0324  NV34M [GeForce FX Go 5200]
-               1071 8160  MIM2000
-       0325  NV34M [GeForce FX Go5250]
-       0326  NV34 [GeForce FX 5500]
-       0327  NV34 [GeForce FX 5100]
-       0328  NV34M [GeForce FX Go 5200]
-       0329  NV34M [GeForce FX Go5200]
-       032a  NV34GL [Quadro NVS 280 PCI]
-       032b  NV34GL [Quadro FX 500/600 PCI]
-       032c  NV34GLM [GeForce FX Go 5300]
-       032d  NV34 [GeForce FX Go5100]
-       032f  NV34
-       0330  NV35 [GeForce FX 5900 Ultra]
-       0331  NV35 [GeForce FX 5900]
-               1043 8145  V9950GE
-       0332  NV35 [GeForce FX 5900XT]
-       0333  NV38 [GeForce FX 5950 Ultra]
-       0334  NV35 [GeForce FX 5900ZT]
-       0338  NV35GL [Quadro FX 3000]
-       033f  NV35GL [Quadro FX 700]
-       0341  NV36.1 [GeForce FX 5700 Ultra]
-       0342  NV36.2 [GeForce FX 5700]
-       0343  NV36 [GeForce FX 5700LE]
-       0344  NV36.4 [GeForce FX 5700VE]
-       0345  NV36.5
-       0347  NV36 [GeForce FX Go5700]
-       0348  NV36 [GeForce FX Go5700]
-       0349  NV36
-       034b  NV36
-       034c  NV36 [Quadro FX Go1000]
-       034e  NV36GL [Quadro FX 1100]
-       034f  NV36GL
-10df  Emulex Corporation
-       1ae5  LP6000 Fibre Channel Host Adapter
-       1ae6  LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
-       1ae7  LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:2-3)
-       f005  LP1150e Fibre Channel Host Adapter
-       f085  LP850 Fibre Channel Host Adapter
-       f095  LP952 Fibre Channel Host Adapter
-       f098  LP982 Fibre Channel Host Adapter
-       f0a5  LP1050 Fibre Channel Host Adapter
-       f0d5  LP1150 Fibre Channel Host Adapter
-       f100  LP11000e Fibre Channel Host Adapter
-       f700  LP7000 Fibre Channel Host Adapter
-       f701  LP 7000EFibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
-       f800  LP8000 Fibre Channel Host Adapter
-       f801  LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
-       f900  LP9000 Fibre Channel Host Adapter
-       f901  LP 9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
-       f980  LP9802 Fibre Channel Host Adapter
-       f981  LP 9802 Fibre Channel Host Adapter Alternate ID
-       f982  LP 9802 Fibre Channel Host Adapter Alternate ID
-       fa00  LP10000 Fibre Channel Host Adapter
-       fa01  LP101 Fibre Channel Host Adapter
-       fd00  LP11000 Fibre Channel Host Adapter
-10e0  Integrated Micro Solutions Inc.
-       5026  IMS5026/27/28
-       5027  IMS5027
-       5028  IMS5028
-       8849  IMS8849
-       8853  IMS8853
-       9128  IMS9128 [Twin turbo 128]
-10e1  Tekram Technology Co.,Ltd.
-       0391  TRM-S1040
-               10e1 0391  DC-315U SCSI-3 Host Adapter
-       690c  DC-690c
-       dc29  DC-290
-10e2  Aptix Corporation
-10e3  Tundra Semiconductor Corp.
-       0000  CA91C042 [Universe]
-       0860  CA91C860 [QSpan]
-       0862  CA91C862A [QSpan-II]
-       8260  CA91L8200B [Dual PCI PowerSpan II]
-       8261  CA91L8260B [Single PCI PowerSpan II]
-10e4  Tandem Computers
-10e5  Micro Industries Corporation
-10e6  Gainbery Computer Products Inc.
-10e7  Vadem
-10e8  Applied Micro Circuits Corp.
-       1072  INES GPIB-PCI (AMCC5920 based)
-       2011  Q-Motion Video Capture/Edit board
-       4750  S5930 [Matchmaker]
-       5920  S5920
-       8043  LANai4.x [Myrinet LANai interface chip]
-       8062  S5933_PARASTATION
-       807d  S5933 [Matchmaker]
-       8088  Kongsberg Spacetec Format Synchronizer
-       8089  Kongsberg Spacetec Serial Output Board
-       809c  S5933_HEPC3
-       80d7  PCI-9112
-       80d9  PCI-9118
-       80da  PCI-9812
-       811a  PCI-IEEE1355-DS-DE Interface
-       814c  Fastcom ESCC-PCI (Commtech, Inc.)
-       8170  S5933 [Matchmaker] (Chipset Development Tool)
-# sold with Roper Scientifc(Photometrics) CoolSnap HQ camera
-       81e6  Multimedia video controller
-       8291  Fastcom 232/8-PCI (Commtech, Inc.)
-       82c4  Fastcom 422/4-PCI (Commtech, Inc.)
-       82c5  Fastcom 422/2-PCI (Commtech, Inc.)
-       82c6  Fastcom IG422/1-PCI (Commtech, Inc.)
-       82c7  Fastcom IG232/2-PCI (Commtech, Inc.)
-       82ca  Fastcom 232/4-PCI (Commtech, Inc.)
-       82db  AJA HDNTV HD SDI Framestore
-       82e2  Fastcom DIO24H-PCI (Commtech, Inc.)
-       8851  S5933 on Innes Corp FM Radio Capture card
-10e9  Alps Electric Co., Ltd.
-10ea  Intergraphics Systems
-       1680  IGA-1680
-       1682  IGA-1682
-       1683  IGA-1683
-       2000  CyberPro 2000
-       2010  CyberPro 2000A
-       5000  CyberPro 5000
-       5050  CyberPro 5050
-       5202  CyberPro 5202
-# CyberPro5202 Audio Function
-       5252  CyberPro5252
-10eb  Artists Graphics
-       0101  3GA
-       8111  Twist3 Frame Grabber
-10ec  Realtek Semiconductor Co., Ltd.
-       8029  RTL-8029(AS)
-               10b8 2011  EZ-Card (SMC1208)
-               10ec 8029  RTL-8029(AS)
-               1113 1208  EN1208
-               1186 0300  DE-528
-               1259 2400  AT-2400
-       8129  RTL-8129
-               10ec 8129  RT8129 Fast Ethernet Adapter
-       8138  RT8139 (B/C) Cardbus Fast Ethernet Adapter
-               10ec 8138  RT8139 (B/C) Fast Ethernet Adapter
-       8139  RTL-8139/8139C/8139C+
-               0357 000a  TTP-Monitoring Card V2.0
-               1025 005a  TravelMate 290
-               1025 8920  ALN-325
-               1025 8921  ALN-325
-               1071 8160  MIM2000
-               10bd 0320  EP-320X-R
-               10ec 8139  RT8139
-               1113 ec01  FNC-0107TX
-               1186 1300  DFE-538TX
-               1186 1320  SN5200
-               1186 8139  DRN-32TX
-               11f6 8139  FN22-3(A) LinxPRO Ethernet Adapter
-               1259 2500  AT-2500TX
-               1259 2503  AT-2500TX/ACPI
-               1429 d010  ND010
-               1432 9130  EN-9130TX
-               1436 8139  RT8139
-               1458 e000  GA-7VM400M/7VT600 Motherboard
-               146c 1439  FE-1439TX
-               1489 6001  GF100TXRII
-               1489 6002  GF100TXRA
-               149c 139a  LFE-8139ATX
-               149c 8139  LFE-8139TX
-               14cb 0200  LNR-100 Family 10/100 Base-TX Ethernet
-               1799 5000  F5D5000 PCI Card/Desktop Network PCI Card
-               2646 0001  EtheRx
-               8e2e 7000  KF-230TX
-               8e2e 7100  KF-230TX/2
-               a0a0 0007  ALN-325C
-       8169  RTL-8169 Gigabit Ethernet
-               1259 c107  CG-LAPCIGT
-               1371 434e  ProG-2000L
-               1458 e000  GA-K8VT800 Pro Motherboard
-               1462 702c  K8T NEO 2 motherboard
-       8180  RTL8180L 802.11b MAC
-       8197  SmartLAN56 56K Modem
-10ed  Ascii Corporation
-       7310  V7310
-10ee  Xilinx Corporation
-       3fc0  RME Digi96
-       3fc1  RME Digi96/8
-       3fc2  RME Digi96/8 Pro
-       3fc3  RME Digi96/8 Pad
-       3fc4  RME Digi9652 (Hammerfall)
-       3fc5  RME Hammerfall DSP
-       3fc6  RME Hammerfall DSP MADI
-       8381  Ellips Santos Frame Grabber
-10ef  Racore Computer Products, Inc.
-       8154  M815x Token Ring Adapter
-10f0  Peritek Corporation
-10f1  Tyan Computer
-10f2  Achme Computer, Inc.
-10f3  Alaris, Inc.
-10f4  S-MOS Systems, Inc.
-10f5  NKK Corporation
-       a001  NDR4000 [NR4600 Bridge]
-10f6  Creative Electronic Systems SA
-10f7  Matsushita Electric Industrial Co., Ltd.
-10f8  Altos India Ltd
-10f9  PC Direct
-10fa  Truevision
-       000c  TARGA 1000
-10fb  Thesys Gesellschaft für Mikroelektronik mbH
-       186f  TH 6255
-10fc  I-O Data Device, Inc.
-# What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
-       0003  Cardbus IDE Controller
-       0005  Cardbus SCSI CBSC II
-10fd  Soyo Computer, Inc
-10fe  Fast Multimedia AG
-10ff  NCube
-1100  Jazz Multimedia
-1101  Initio Corporation
-       1060  INI-A100U2W
-       9100  INI-9100/9100W
-       9400  INI-940
-       9401  INI-950
-       9500  360P
-       9502  Initio INI-9100UW Ultra Wide SCSI Controller INIC-950P chip
-1102  Creative Labs
-       0002  SB Live! EMU10k1
-               1102 0020  CT4850 SBLive! Value
-               1102 0021  CT4620 SBLive!
-               1102 002f  SBLive! mainboard implementation
-               1102 4001  E-mu APS
-               1102 8022  CT4780 SBLive! Value
-               1102 8023  CT4790 SoundBlaster PCI512
-               1102 8024  CT4760 SBLive!
-               1102 8025  SBLive! Mainboard Implementation
-               1102 8026  CT4830 SBLive! Value
-               1102 8027  CT4832 SBLive! Value
-               1102 8028  CT4760 SBLive! OEM version
-               1102 8031  CT4831 SBLive! Value
-               1102 8040  CT4760 SBLive!
-               1102 8051  CT4850 SBLive! Value
-               1102 8061  SBLive! Player 5.1
-               1102 8064  SB Live! 5.1 Model SB0100
-               1102 8065  SBLive! 5.1 Digital Model SB0220
-               1102 8067  SBLive! 5.1 eMicro 28028
-       0004  SB Audigy
-               1102 0051  SB0090 Audigy Player
-               1102 0053  SB0090 Audigy Player/OEM
-               1102 0058  SB0090 Audigy Player/OEM
-               1102 1007  SB0240 Audigy 2 Platinum 6.1
-               1102 2002  SB Audigy 2 ZS (SB0350)
-       0006  [SB Live! Value] EMU10k1X
-       0007  SB Audigy LS
-               1102 1001  SB0310 Audigy LS
-               1102 1002  SB0312 Audigy LS
-               1102 1006  SB0410 SBLive! 24-bit
-       0008  SB0400 Audigy2 Value
-       4001  SB Audigy FireWire Port
-               1102 0010  SB Audigy FireWire Port
-       7002  SB Live! MIDI/Game Port
-               1102 0020  Gameport Joystick
-       7003  SB Audigy MIDI/Game port
-               1102 0040  SB Audigy MIDI/Game Port
-       7004  [SB Live! Value] Input device controller
-       7005  SB Audigy LS MIDI/Game port
-               1102 1001  SB0310 Audigy LS MIDI/Game port
-               1102 1002  SB0312 Audigy LS MIDI/Game port
-       8064  SB0100 [SBLive! 5.1 OEM]
-       8938  Ectiva EV1938
-               1033 80e5  SlimTower-Jim (NEC)
-               1071 7150  Mitac 7150
-               110a 5938  Siemens Scenic Mobile 510PIII
-               13bd 100c  Ceres-C (Sharp, Intel BX)
-               13bd 100d  Sharp, Intel Banister
-               13bd 100e  TwinHead P09S/P09S3 (Sharp)
-               13bd f6f1  Marlin (Sharp)
-               14ff 0e70  P88TE (TWINHEAD INTERNATIONAL Corp)
-               14ff c401  Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
-               156d b400  G400 - Geo (AlphaTop (Taiwan))
-               156d b550  G560  (AlphaTop (Taiwan))
-               156d b560  G560  (AlphaTop (Taiwan))
-               156d b700  G700/U700  (AlphaTop (Taiwan))
-               156d b795  G795  (AlphaTop (Taiwan))
-               156d b797  G797  (AlphaTop (Taiwan))
-1103  Triones Technologies, Inc.
-       0003  HPT343
-       0004  HPT366/368/370/370A/372/372N
-               1103 0001  HPT370A
-               1103 0003  HPT343 / HPT345 / HPT363 UDMA33
-               1103 0004  HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
-               1103 0005  HPT370 UDMA100
-               1103 0006  HPT302
-               1103 0007  HPT371 UDMA133
-               1103 0008  HPT374 UDMA/ATA133 RAID Controller
-       0005  HPT372A/372N
-       0006  HPT302
-       0007  HPT371/371N
-       0008  HPT374
-       0009  HPT372N
-1104  RasterOps Corp.
-1105  Sigma Designs, Inc.
-       1105  REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
-       8300  REALmagic Hollywood Plus DVD Decoder
-       8400  EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
-       8401  EM8401 REALmagic DVD/MPEG-2 A/V Decoder
-       8470  EM8470 REALmagic DVD/MPEG-4 A/V Decoder
-       8471  EM8471 REALmagic DVD/MPEG-4 A/V Decoder
-       8475  EM8475 REALmagic DVD/MPEG-4 A/V Decoder
-       8476  EM8476 REALmagic DVD/MPEG-4 A/V Decoder
-       8485  EM8485 REALmagic DVD/MPEG-4 A/V Decoder
-       8486  EM8486 REALmagic DVD/MPEG-4 A/V Decoder
-1106  VIA Technologies, Inc.
-       0102  Embedded VIA Ethernet Controller
-       0130  VT6305 1394.A Controller
-       0305  VT8363/8365 [KT133/KM133]
-               1043 8033  A7V Mainboard
-               1043 803e  A7V-E Mainboard
-               1043 8042  A7V133/A7V133-C Mainboard
-               147b a401  KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
-       0391  VT8371 [KX133]
-       0501  VT8501 [Apollo MVP4]
-       0505  VT82C505
-# Shares chip with :0576. The VT82C576M has :1571 instead of :0561.
-       0561  VT82C576MV
-       0571  VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
-               1019 0985  P6VXA Motherboard
-               1019 0a81  L7VTA v1.0 Motherboard (KT400-8235)
-               1043 8052  VT8233A Bus Master ATA100/66/33 IDE
-               1043 808c  A7V8X motherboard
-               1043 80a1  A7V8X-X motherboard rev. 1.01
-               1043 80ed  A7V600 motherboard
-               1106 0571  VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
-               1179 0001  Magnia Z310
-               1297 f641  FX41 motherboard
-               1458 5002  GA-7VAX Mainboard
-               1462 7020  K8T NEO 2 motherboard
-               147b 1407  KV8-MAX3 motherboard
-               1849 0571  K7VT2 motherboard
-       0576  VT82C576 3V [Apollo Master]
-       0585  VT82C585VP [Apollo VP1/VPX]
-       0586  VT82C586/A/B PCI-to-ISA [Apollo VP]
-               1106 0000  MVP3 ISA Bridge
-       0595  VT82C595 [Apollo VP2]
-       0596  VT82C596 ISA [Mobile South]
-               1106 0000  VT82C596/A/B PCI to ISA Bridge
-               1458 0596  VT82C596/A/B PCI to ISA Bridge
-       0597  VT82C597 [Apollo VP3]
-       0598  VT82C598 [Apollo MVP3]
-       0601  VT8601 [Apollo ProMedia]
-       0605  VT8605 [ProSavage PM133]
-               1043 802c  CUV4X mainboard
-       0680  VT82C680 [Apollo P6]
-       0686  VT82C686 [Apollo Super South]
-               1019 0985  P6VXA Motherboard
-               1043 802c  CUV4X mainboard
-               1043 8033  A7V Mainboard
-               1043 803e  A7V-E Mainboard
-               1043 8040  A7M266 Mainboard
-               1043 8042  A7V133/A7V133-C Mainboard
-               1106 0000  VT82C686/A PCI to ISA Bridge
-               1106 0686  VT82C686/A PCI to ISA Bridge
-               1179 0001  Magnia Z310
-               147b a702  KG7-Lite Mainboard
-       0691  VT82C693A/694x [Apollo PRO133x]
-               1019 0985  P6VXA Motherboard
-               1179 0001  Magnia Z310
-               1458 0691  VT82C691 Apollo Pro System Controller
-       0693  VT82C693 [Apollo Pro Plus]
-       0698  VT82C693A [Apollo Pro133 AGP]
-       0926  VT82C926 [Amazon]
-       1000  VT82C570MV
-       1106  VT82C570MV
-       1571  VT82C576M/VT82C586
-       1595  VT82C595/97 [Apollo VP2/97]
-       3022  CLE266
-# This is *not* USB 2.0 as the existing entry suggests
-       3038  VT82xxxxx UHCI USB 1.1 Controller
-               0925 1234  USB Controller
-               1019 0985  P6VXA Motherboard
-               1019 0a81  L7VTA v1.0 Motherboard (KT400-8235)
-               1043 808c  VT6202 USB2.0 4 port controller
-               1043 80a1  A7V8X-X motherboard
-               1043 80ed  A7V600 motherboard
-               1179 0001  Magnia Z310
-               1458 5004  GA-7VAX Mainboard
-               1462 7020  K8T NEO 2 motherboard
-               147b 1407  KV8-MAX3 motherboard
-               182d 201d  CN-029 USB2.0 4 port PCI Card
-       3040  VT82C586B ACPI
-       3043  VT86C100A [Rhine]
-               10bd 0000  VT86C100A Fast Ethernet Adapter
-               1106 0100  VT86C100A Fast Ethernet Adapter
-               1186 1400  DFE-530TX rev A
-       3044  IEEE 1394 Host Controller
-               1025 005a  TravelMate 290
-               1458 1000  GA-7VT600-1394 Motherboard
-               1462 702d  K8T NEO 2 motherboard
-       3050  VT82C596 Power Management
-       3051  VT82C596 Power Management
-       3053  VT6105M [Rhine-III]
-       3057  VT82C686 [Apollo Super ACPI]
-               1019 0985  P6VXA Motherboard
-               1043 8033  A7V Mainboard
-               1043 803e  A7V-E Mainboard
-               1043 8040  A7M266 Mainboard
-               1043 8042  A7V133/A7V133-C Mainboard
-               1179 0001  Magnia Z310
-       3058  VT82C686 AC97 Audio Controller
-               0e11 0097  SoundMax Digital Integrated Audio
-               0e11 b194  Soundmax integrated digital audio
-               1019 0985  P6VXA Motherboard
-               1043 1106  A7V133/A7V133-C Mainboard
-               1106 4511  Onboard Audio on EP7KXA
-               1458 7600  Onboard Audio
-               1462 3091  MS-6309 Onboard Audio
-               1462 3300  MS-6330 Onboard Audio
-               15dd 7609  Onboard Audio
-       3059  VT8233/A/8235/8237 AC97 Audio Controller
-               1019 0a81  L7VTA v1.0 Motherboard (KT400-8235)
-               1043 8095  A7V8X Motherboard (Realtek ALC650 codec)
-               1043 80a1  A7V8X-X Motherboard
-               1043 80b0  A7V600/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
-               1106 3059  L7VMM2 Motherboard
-               1106 4161  K7VT2 motherboard
-               1297 c160  FX41 motherboard (Realtek ALC650 codec)
-               1458 a002  GA-7VAX Onboard Audio (Realtek ALC650)
-               1462 0080  K8T NEO 2 motherboard
-               1462 3800  KT266 onboard audio
-               147b 1407  KV8-MAX3 motherboard
-       3065  VT6102 [Rhine-II]
-               1043 80a1  A7V8X-X Motherboard
-               1106 0102  VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
-               1186 1400  DFE-530TX rev A
-               1186 1401  DFE-530TX rev B
-               13b9 1421  LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
-# This hosts more than just the Intel 537 codec, it also hosts PCtel (SIL33) and SmartLink (SIL34) codecs
-       3068  AC'97 Modem Controller
-               1462 309e  MS-6309 Saturn Motherboard
-       3074  VT8233 PCI to ISA Bridge
-               1043 8052  VT8233A
-       3091  VT8633 [Apollo Pro266]
-       3099  VT8366/A/7 [Apollo KT266/A/333]
-               1043 8064  A7V266-E Mainboard
-               1043 807f  A7V333 Mainboard
-               1849 3099  K7VT2 motherboard
-       3101  VT8653 Host Bridge
-       3102  VT8662 Host Bridge
-       3103  VT8615 Host Bridge
-       3104  USB 2.0
-               1019 0a81  L7VTA v1.0 Motherboard (KT400-8235)
-               1043 808c  A7V8X motherboard
-               1043 80a1  A7V8X-X motherboard rev 1.01
-               1043 80ed  A7V600 motherboard
-               1297 f641  FX41 motherboard
-               1458 5004  GA-7VAX Mainboard
-               1462 7020  K8T NEO 2 motherboard
-               147b 1407  KV8-MAX3 motherboard
-               182d 201d  CN-029 USB 2.0 4 port PCI Card
-       3106  VT6105 [Rhine-III]
-               1186 1403  DFE-530TX rev C
-       3108  S3 Unichrome Pro VGA Adapter
-       3109  VT8233C PCI to ISA Bridge
-       3112  VT8361 [KLE133] Host Bridge
-       3116  VT8375 [KM266/KL266] Host Bridge
-               1297 f641  FX41 motherboard
-       3118  S3 Unichrome Pro VGA Adapter
-       3119  VT6120/VT6121/VT6122 Gigabit Ethernet Adapter
-# found on EPIA M6000/9000 mainboard
-       3122  VT8623 [Apollo CLE266] integrated CastleRock graphics
-# found on EPIA M6000/9000 mainboard
-       3123  VT8623 [Apollo CLE266]
-       3128  VT8753 [P4X266 AGP]
-       3133  VT3133 Host Bridge
-       3147  VT8233A ISA Bridge
-       3148  P4M266 Host Bridge
-       3149  VIA VT6420 SATA RAID Controller
-               1043 80ed  A7V600/K8V Deluxe motherboard
-               1458 b003  GA-7VM400AM(F) Motherboard
-               1462 7020  K8T Neo 2 Motherboard
-               147b 1407  KV8-MAX3 motherboard
-       3156  P/KN266 Host Bridge
-# on ASUS P4P800
-       3164  VT6410 ATA133 RAID controller
-       3168  VT8374 P4X400 Host Controller/AGP Bridge
-       3177  VT8235 ISA Bridge
-               1019 0a81  L7VTA v1.0 Motherboard (KT400-8235)
-               1043 808c  A7V8X motherboard
-               1043 80a1  A7V8X-X motherboard
-               1297 f641  FX41 motherboard
-               1458 5001  GA-7VAX Mainboard
-               1849 3177  K7VT2 motherboard
-       3178  ProSavageDDR P4N333 Host Bridge
-       3188  VT8385 [K8T800 AGP] Host Bridge
-               1043 80a3  K8V Deluxe motherboard
-               147b 1407  KV8-MAX3 motherboard
-       3189  VT8377 [KT400/KT600 AGP] Host Bridge
-               1043 807f  A7V8X motherboard
-               1458 5000  GA-7VAX Mainboard
-       3204  K8M800
-       3205  VT8378 [KM400/A] Chipset Host Bridge
-               1458 5000  GA-7VM400M Motherboard
-       3218  K8T800M Host Bridge
-       3227  VT8237 ISA bridge [KT600/K8T800 South]
-               1043 80ed  A7V600 motherboard
-               1106 3227  DFI KT600-AL Motherboard
-               1458 5001  GA-7VT600 Motherboard
-               147b 1407  KV8-MAX3 motherboard
-       3249  VT6421 IDE RAID Controller
-       4149  VIA VT6420 (ATA133) Controller
-       5030  VT82C596 ACPI [Apollo PRO]
-       6100  VT85C100A [Rhine II]
-       7204  K8M800
-# S3 Graphics UniChromeâ„¢ 2D/3D Graphics with motion compensation
-       7205  VT8378 [S3 UniChrome] Integrated Video
-               1458 d000  Gigabyte GA-7VM400(A)M(F) Motherboard
-       8231  VT8231 [PCI-to-ISA Bridge]
-       8235  VT8235 ACPI
-       8305  VT8363/8365 [KT133/KM133 AGP]
-       8391  VT8371 [KX133 AGP]
-       8501  VT8501 [Apollo MVP4 AGP]
-       8596  VT82C596 [Apollo PRO AGP]
-       8597  VT82C597 [Apollo VP3 AGP]
-       8598  VT82C598/694x [Apollo MVP3/Pro133x AGP]
-               1019 0985  P6VXA Motherboard
-       8601  VT8601 [Apollo ProMedia AGP]
-       8605  VT8605 [PM133 AGP]
-       8691  VT82C691 [Apollo Pro]
-       8693  VT82C693 [Apollo Pro Plus] PCI Bridge
-       b091  VT8633 [Apollo Pro266 AGP]
-       b099  VT8366/A/7 [Apollo KT266/A/333 AGP]
-       b101  VT8653 AGP Bridge
-       b102  VT8362 AGP Bridge
-       b103  VT8615 AGP Bridge
-       b112  VT8361 [KLE133] AGP Bridge
-       b168  VT8235 PCI Bridge
-       b188  VT8237 PCI bridge [K8T800 South]
-               147b 1407  KV8-MAX3 motherboard
-       b198  VT8237 PCI Bridge
-# 32-Bit PCI bus master Ethernet MAC with standard MII interface
-       d104  VT8237 Integrated Fast Ethernet Controller
-1107  Stratus Computers
-       0576  VIA VT82C570MV [Apollo] (Wrong vendor ID!)
-1108  Proteon, Inc.
-       0100  p1690plus_AA
-       0101  p1690plus_AB
-       0105  P1690Plus
-       0108  P1690Plus
-       0138  P1690Plus
-       0139  P1690Plus
-       013c  P1690Plus
-       013d  P1690Plus
-1109  Cogent Data Technologies, Inc.
-       1400  EM110TX [EX110TX]
-110a  Siemens Nixdorf AG
-       0002  Pirahna 2-port
-       0005  Tulip controller, power management, switch extender
-       0006  FSC PINC (I/O-APIC)
-       0015  FSC Multiprocessor Interrupt Controller
-       001d  FSC Copernicus Management Controller
-       007b  FSC Remote Service Controller, mailbox device
-       007c  FSC Remote Service Controller, shared memory device
-       007d  FSC Remote Service Controller, SMIC device
-# Superfastcom-PCI (Commtech, Inc.) or DSCC4 WAN Adapter
-       2102  DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels
-       2104  Eicon Diva 2.02 compatible passive ISDN card
-       3142  SIMATIC NET CP 5613A1 (Profibus Adapter)
-       4021  SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
-       4029  SIMATIC NET CP 5613A2 (Profibus Adapter)
-       4942  FPGA I-Bus Tracer for MBD
-       6120  SZB6120
-110b  Chromatic Research Inc.
-       0001  Mpact Media Processor
-       0004  Mpact 2
-110c  Mini-Max Technology, Inc.
-110d  Znyx Advanced Systems
-110e  CPU Technology
-110f  Ross Technology
-1110  Powerhouse Systems
-       6037  Firepower Powerized SMP I/O ASIC
-       6073  Firepower Powerized SMP I/O ASIC
-1111  Santa Cruz Operation
-# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom
-1112  Osicom Technologies Inc
-       2200  FDDI Adapter
-       2300  Fast Ethernet Adapter
-       2340  4 Port Fast Ethernet Adapter
-       2400  ATM Adapter
-1113  Accton Technology Corporation
-       1211  SMC2-1211TX
-               103c 1207  EN-1207D Fast Ethernet Adapter
-               1113 1211  EN-1207D Fast Ethernet Adapter
-       1216  EN-1216 Ethernet Adapter
-               1113 2242  EN2242 10/100 Ethernet Mini-PCI Card
-               111a 1020  SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
-       1217  EN-1217 Ethernet Adapter
-       5105  10Mbps Network card
-       9211  EN-1207D Fast Ethernet Adapter
-               1113 9211  EN-1207D Fast Ethernet Adapter
-       9511  21x4x DEC-Tulip compatible Fast Ethernet
-       d301  CPWNA100 (Philips wireless PCMCIA)
-       ec02  SMC 1244TX v3
-1114  Atmel Corporation
-       0506  802.11b Wireless Network Adaptor (at76c506)
-1115  3D Labs
-1116  Data Translation
-       0022  DT3001
-       0023  DT3002
-       0024  DT3003
-       0025  DT3004
-       0026  DT3005
-       0027  DT3001-PGL
-       0028  DT3003-PGL
-1117  Datacube, Inc
-       9500  Max-1C SVGA card
-       9501  Max-1C image processing
-1118  Berg Electronics
-1119  ICP Vortex Computersysteme GmbH
-       0000  GDT 6000/6020/6050
-       0001  GDT 6000B/6010
-       0002  GDT 6110/6510
-       0003  GDT 6120/6520
-       0004  GDT 6530
-       0005  GDT 6550
-       0006  GDT 6117/6517
-       0007  GDT 6127/6527
-       0008  GDT 6537
-       0009  GDT 6557/6557-ECC
-       000a  GDT 6115/6515
-       000b  GDT 6125/6525
-       000c  GDT 6535
-       000d  GDT 6555
-       0010  GDT 6115/6515
-       0011  GDT 6125/6525
-       0012  GDT 6535
-       0013  GDT 6555/6555-ECC
-       0100  GDT 6117RP/6517RP
-       0101  GDT 6127RP/6527RP
-       0102  GDT 6537RP
-       0103  GDT 6557RP
-       0104  GDT 6111RP/6511RP
-       0105  GDT 6121RP/6521RP
-       0110  GDT 6117RD/6517RD
-       0111  GDT 6127RD/6527RD
-       0112  GDT 6537RD
-       0113  GDT 6557RD
-       0114  GDT 6111RD/6511RD
-       0115  GDT 6121RD/6521RD
-       0118  GDT 6118RD/6518RD/6618RD
-       0119  GDT 6128RD/6528RD/6628RD
-       011a  GDT 6538RD/6638RD
-       011b  GDT 6558RD/6658RD
-       0120  GDT 6117RP2/6517RP2
-       0121  GDT 6127RP2/6527RP2
-       0122  GDT 6537RP2
-       0123  GDT 6557RP2
-       0124  GDT 6111RP2/6511RP2
-       0125  GDT 6121RP2/6521RP2
-       0136  GDT 6113RS/6513RS
-       0137  GDT 6123RS/6523RS
-       0138  GDT 6118RS/6518RS/6618RS
-       0139  GDT 6128RS/6528RS/6628RS
-       013a  GDT 6538RS/6638RS
-       013b  GDT 6558RS/6658RS
-       013c  GDT 6533RS/6633RS
-       013d  GDT 6543RS/6643RS
-       013e  GDT 6553RS/6653RS
-       013f  GDT 6563RS/6663RS
-       0166  GDT 7113RN/7513RN/7613RN
-       0167  GDT 7123RN/7523RN/7623RN
-       0168  GDT 7118RN/7518RN/7518RN
-       0169  GDT 7128RN/7528RN/7628RN
-       016a  GDT 7538RN/7638RN
-       016b  GDT 7558RN/7658RN
-       016c  GDT 7533RN/7633RN
-       016d  GDT 7543RN/7643RN
-       016e  GDT 7553RN/7653RN
-       016f  GDT 7563RN/7663RN
-       01d6  GDT 4x13RZ
-       01d7  GDT 4x23RZ
-       01f6  GDT 8x13RZ
-       01f7  GDT 8x23RZ
-       01fc  GDT 8x33RZ
-       01fd  GDT 8x43RZ
-       01fe  GDT 8x53RZ
-       01ff  GDT 8x63RZ
-       0210  GDT 6519RD/6619RD
-       0211  GDT 6529RD/6629RD
-       0260  GDT 7519RN/7619RN
-       0261  GDT 7529RN/7629RN
-       02ff  GDT MAXRP
-       0300  GDT NEWRX
-111a  Efficient Networks, Inc
-       0000  155P-MF1 (FPGA)
-       0002  155P-MF1 (ASIC)
-       0003  ENI-25P ATM
-               111a 0000  ENI-25p Miniport ATM Adapter
-       0005  SpeedStream (LANAI)
-               111a 0001  ENI-3010 ATM
-               111a 0009  ENI-3060 ADSL (VPI=0)
-               111a 0101  ENI-3010 ATM
-               111a 0109  ENI-3060CO ADSL (VPI=0)
-               111a 0809  ENI-3060 ADSL (VPI=0 or 8)
-               111a 0909  ENI-3060CO ADSL (VPI=0 or 8)
-               111a 0a09  ENI-3060 ADSL (VPI=<0..15>)
-       0007  SpeedStream ADSL
-               111a 1001  ENI-3061 ADSL [ASIC]
-       1203  SpeedStream 1023 Wireless PCI Adapter
-111b  Teledyne Electronic Systems
-111c  Tricord Systems Inc.
-       0001  Powerbis Bridge
-111d  Integrated Device Technology, Inc.
-       0001  IDT77201/77211 155Mbps ATM SAR Controller [NICStAR]
-       0003  IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller
-       0004  IDT77V252 155Mbps ATM MICRO ABR SAR Controller
-       0005  IDT77V222 155Mbps ATM MICRO ABR SAR Controller
-111e  Eldec
-111f  Precision Digital Images
-       4a47  Precision MX Video engine interface
-       5243  Frame capture bus interface
-1120  EMC Corporation
-1121  Zilog
-1122  Multi-tech Systems, Inc.
-1123  Excellent Design, Inc.
-1124  Leutron Vision AG
-1125  Eurocore
-1126  Vigra
-1127  FORE Systems Inc
-       0200  ForeRunner PCA-200 ATM
-       0210  PCA-200PC
-       0250  ATM
-       0300  ForeRunner PCA-200EPC ATM
-       0310  ATM
-       0400  ForeRunnerHE ATM Adapter
-               1127 0400  ForeRunnerHE ATM
-1129  Firmworks
-112a  Hermes Electronics Company, Ltd.
-112b  Linotype - Hell AG
-112c  Zenith Data Systems
-112d  Ravicad
-112e  Infomedia Microelectronics Inc.
-112f  Imaging Technology Inc
-       0000  MVC IC-PCI
-       0001  MVC IM-PCI Video frame grabber/processor
-1130  Computervision
-1131  Philips Semiconductors
-       1561  USB 1.1 Host Controller
-       1562  USB 2.0 Host Controller
-       3400  SmartPCI56(UCB1500) 56K Modem
-       5400  TriMedia TM1000/1100
-       5402  TriMedia TM-1300
-               1244 0f00  Fritz!Card DSL
-       7130  SAA7130 Video Broadcast Decoder
-               5168 0138  LiveView FlyVideo 2000
-       7133  SAA713X Audio+video broadcast decoder
-               5168 0138  LifeView FlyVideo 3000
-               5168 0212  LifeView FlyTV Platinum mini
-               5168 0502  LifeView FlyDVB-T Duo CardBus
-# PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl)
-       7134  SAA7134
-               1043 4842  TV-FM Card 7134
-       7135  SAA7135 Audio+video broadcast decoder
-       7145  SAA7145
-       7146  SAA7146
-               110a 0000  Fujitsu/Siemens DVB-C card rev1.5
-               110a ffff  Fujitsu/Siemens DVB-C card rev1.5
-               1131 4f56  KNC1 DVB-S Budget
-               1131 4f61  Fujitsu-Siemens Activy DVB-S Budget
-               114b 2003  DVRaptor Video Edit/Capture Card
-               11bd 0006  DV500 Overlay
-               11bd 000a  DV500 Overlay
-               11bd 000f  DV500 Overlay
-               13c2 0000  Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
-               13c2 0001  Technotrend/Hauppauge DVB card rev1.3 or rev1.6
-               13c2 0002  Technotrend/Hauppauge DVB card rev2.1
-               13c2 0003  Technotrend/Hauppauge DVB card rev2.1
-               13c2 0004  Technotrend/Hauppauge DVB card rev2.1
-               13c2 0006  Technotrend/Hauppauge DVB card rev1.3 or rev1.6
-               13c2 0008  Technotrend/Hauppauge DVB-T
-               13c2 000a  Octal/Technotrend DVB-C for iTV
-               13c2 1003  Technotrend-Budget / Hauppauge WinTV-NOVA-S DVB card
-               13c2 1004  Technotrend-Budget / Hauppauge WinTV-NOVA-C DVB card
-               13c2 1005  Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
-               13c2 100c  Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
-               13c2 100f  Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
-               13c2 1011  Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
-               13c2 1013  SATELCO Multimedia DVB
-               13c2 1102  Technotrend/Hauppauge DVB card rev2.1
-1132  Mitel Corp.
-# This is the new official company name. See disclaimer on www.eicon.com for details!
-1133  Eicon Networks Corporation
-       7901  EiconCard S90
-       7902  EiconCard S90
-       7911  EiconCard S91
-       7912  EiconCard S91
-       7941  EiconCard S94
-       7942  EiconCard S94
-       7943  EiconCard S94
-       7944  EiconCard S94
-       b921  EiconCard P92
-       b922  EiconCard P92
-       b923  EiconCard P92
-       e001  Diva Pro 2.0 S/T
-       e002  Diva 2.0 S/T PCI
-       e003  Diva Pro 2.0 U
-       e004  Diva 2.0 U PCI
-       e005  Diva 2.01 S/T PCI
-       e006  Diva CT S/T PCI
-       e007  Diva CT U PCI
-       e008  Diva CT Lite S/T PCI
-       e009  Diva CT Lite U PCI
-       e00a  Diva ISDN+V.90 PCI
-       e00b  Diva 2.02 PCI S/T
-       e00c  Diva 2.02 PCI U
-       e00d  Diva ISDN Pro 3.0 PCI
-       e00e  Diva ISDN+CT S/T PCI Rev 2
-       e010  Diva Server BRI-2M PCI
-               110a 0021  Fujitsu Siemens ISDN S0
-               8001 0014  Diva Server BRI-2M PCI Cornet NQ
-       e011  Diva Server BRI S/T Rev 2
-       e012  Diva Server 4BRI-8M PCI
-               8001 0014  Diva Server 4BRI-8M PCI Cornet NQ
-       e013  Diva Server 4BRI Rev 2
-               1133 1300  Diva Server V-4BRI-8
-               1133 e013  Diva Server 4BRI-8M 2.0 PCI
-               8001 0014  Diva Server 4BRI-8M 2.0 PCI Cornet NQ
-       e014  Diva Server PRI-30M PCI
-               0008 0100  Diva Server PRI-30M PCI
-               8001 0014  Diva Server PRI-30M PCI Cornet NQ
-       e015  DIVA Server PRI Rev 2
-               1133 e015  Diva Server PRI 2.0 PCI
-               8001 0014  Diva Server PRI 2.0 PCI Cornet NQ
-       e016  Diva Server Voice 4BRI PCI
-               8001 0014  Diva Server PRI Cornet NQ
-       e017  Diva Server Voice 4BRI Rev 2
-               1133 e017  Diva Server Voice 4BRI-8M 2.0 PCI
-               8001 0014  Diva Server Voice 4BRI-8M 2.0 PCI Cornet NQ
-       e018  Diva Server BRI-2M 2.0 PCI
-               1133 1800  Diva Server V-BRI-2
-               1133 e018  Diva Server BRI-2M 2.0 PCI
-               8001 0014  Diva Server BRI-2M 2.0 PCI Cornet NQ
-       e019  Diva Server Voice PRI Rev 2
-               1133 e019  Diva Server Voice PRI 2.0 PCI
-               8001 0014  Diva Server Voice PRI 2.0 PCI Cornet NQ
-       e01a  Diva Server 2FX
-       e01b  Diva Server Voice BRI-2M 2.0 PCI
-               1133 e01b  Diva Server Voice BRI-2M 2.0 PCI
-               8001 0014  Diva Server Voice BRI-2M 2.0 PCI Cornet NQ
-       e01c  Diva Server PRI Rev 3
-               1133 1c01  Diva Server PRI/E1/T1-8
-               1133 1c02  Diva Server PRI/T1-24
-               1133 1c03  Diva Server PRI/E1-30
-               1133 1c04  Diva Server PRI/E1/T1
-               1133 1c05  Diva Server V-PRI/T1-24
-               1133 1c06  Diva Server V-PRI/E1-30
-               1133 1c07  Diva Server PRI/E1/T1-8 Cornet NQ
-               1133 1c08  Diva Server PRI/T1-24 Cornet NQ
-               1133 1c09  Diva Server PRI/E1-30 Cornet NQ
-               1133 1c0a  Diva Server PRI/E1/T1 Cornet NQ
-               1133 1c0b  Diva Server V-PRI/T1-24 Cornet NQ
-               1133 1c0c  Diva Server V-PRI/E1-30 Cornet NQ
-       e01e  Diva Server 2PRI
-               1133 1e00  Diva Server V-2PRI/E1-60
-               1133 1e01  Diva Server V-2PRI/T1-48
-               1133 1e02  Diva Server 2PRI/E1-60
-               1133 1e03  Diva Server 2PRI/T1-48
-       e020  Diva Server 4PRI
-               1133 2000  Diva Server V-4PRI/E1-120
-               1133 2001  Diva Server V-4PRI/T1-96
-               1133 2002  Diva Server 4PRI/E1-120
-               1133 2003  Diva Server 4PRI/T1-96
-       e024  Diva Server Analog-4P
-               1133 2400  Diva Server V-Analog-4P
-               1133 e024  Diva Server Analog-4P
-       e028  Diva Server Analog-8P
-               1133 2800  Diva Server V-Analog-8P
-               1133 e028  Diva Server Analog-8P
-1134  Mercury Computer Systems
-       0001  Raceway Bridge
-       0002  Dual PCI to RapidIO Bridge
-1135  Fuji Xerox Co Ltd
-       0001  Printer controller
-1136  Momentum Data Systems
-1137  Cisco Systems Inc
-1138  Ziatech Corporation
-       8905  8905 [STD 32 Bridge]
-1139  Dynamic Pictures, Inc
-       0001  VGA Compatable 3D Graphics
-113a  FWB Inc
-113b  Network Computing Devices
-113c  Cyclone Microsystems, Inc.
-       0000  PCI-9060 i960 Bridge
-       0001  PCI-SDK [PCI i960 Evaluation Platform]
-       0911  PCI-911 [i960Jx-based Intelligent I/O Controller]
-       0912  PCI-912 [i960CF-based Intelligent I/O Controller]
-       0913  PCI-913
-       0914  PCI-914 [I/O Controller w/ secondary PCI bus]
-113d  Leading Edge Products Inc
-113e  Sanyo Electric Co - Computer Engineering Dept
-113f  Equinox Systems, Inc.
-       0808  SST-64P Adapter
-       1010  SST-128P Adapter
-       80c0  SST-16P DB Adapter
-       80c4  SST-16P RJ Adapter
-       80c8  SST-16P Adapter
-       8888  SST-4P Adapter
-       9090  SST-8P Adapter
-1140  Intervoice Inc
-1141  Crest Microsystem Inc
-1142  Alliance Semiconductor Corporation
-       3210  AP6410
-       6422  ProVideo 6422
-       6424  ProVideo 6424
-       6425  ProMotion AT25
-       643d  ProMotion AT3D
-1143  NetPower, Inc
-1144  Cincinnati Milacron
-       0001  Noservo controller
-1145  Workbit Corporation
-       8007  NinjaSCSI-32 Workbit
-       f007  NinjaSCSI-32 KME
-       f010  NinjaSCSI-32 Workbit
-       f012  NinjaSCSI-32 Logitec
-       f013  NinjaSCSI-32 Logitec
-       f015  NinjaSCSI-32 Melco
-1146  Force Computers
-1147  Interface Corp
-# Formerly (Schneider & Koch)
-1148  SysKonnect
-       4000  FDDI Adapter
-               0e11 b03b  Netelligent 100 FDDI DAS Fibre SC
-               0e11 b03c  Netelligent 100 FDDI SAS Fibre SC
-               0e11 b03d  Netelligent 100 FDDI DAS UTP
-               0e11 b03e  Netelligent 100 FDDI SAS UTP
-               0e11 b03f  Netelligent 100 FDDI SAS Fibre MIC
-               1148 5521  FDDI SK-5521 (SK-NET FDDI-UP)
-               1148 5522  FDDI SK-5522 (SK-NET FDDI-UP DAS)
-               1148 5541  FDDI SK-5541 (SK-NET FDDI-FP)
-               1148 5543  FDDI SK-5543 (SK-NET FDDI-LP)
-               1148 5544  FDDI SK-5544 (SK-NET FDDI-LP DAS)
-               1148 5821  FDDI SK-5821 (SK-NET FDDI-UP64)
-               1148 5822  FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
-               1148 5841  FDDI SK-5841 (SK-NET FDDI-FP64)
-               1148 5843  FDDI SK-5843 (SK-NET FDDI-LP64)
-               1148 5844  FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
-       4200  Token Ring adapter
-       4300  SK-98xx Gigabit Ethernet Server Adapter
-               1148 9821  SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
-               1148 9822  SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
-               1148 9841  SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
-               1148 9842  SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
-               1148 9843  SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
-               1148 9844  SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
-               1148 9861  SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
-               1148 9862  SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
-               1148 9871  SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
-               1148 9872  SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
-               1259 2970  AT-2970SX Gigabit Ethernet Adapter
-               1259 2971  AT-2970LX Gigabit Ethernet Adapter
-               1259 2972  AT-2970TX Gigabit Ethernet Adapter
-               1259 2973  AT-2971SX Gigabit Ethernet Adapter
-               1259 2974  AT-2971T Gigabit Ethernet Adapter
-               1259 2975  AT-2970SX/2SC Gigabit Ethernet Adapter
-               1259 2976  AT-2970LX/2SC Gigabit Ethernet Adapter
-               1259 2977  AT-2970TX/2TX Gigabit Ethernet Adapter
-       4320  SK-98xx V2.0 Gigabit Ethernet Adapter
-               1148 0121  Marvell RDK-8001 Adapter
-               1148 0221  Marvell RDK-8002 Adapter
-               1148 0321  Marvell RDK-8003 Adapter
-               1148 0421  Marvell RDK-8004 Adapter
-               1148 0621  Marvell RDK-8006 Adapter
-               1148 0721  Marvell RDK-8007 Adapter
-               1148 0821  Marvell RDK-8008 Adapter
-               1148 0921  Marvell RDK-8009 Adapter
-               1148 1121  Marvell RDK-8011 Adapter
-               1148 1221  Marvell RDK-8012 Adapter
-               1148 3221  SK-9521 V2.0 10/100/1000Base-T Adapter
-               1148 5021  SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
-               1148 5041  SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
-               1148 5043  SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-               1148 5051  SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-               1148 5061  SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-               1148 5071  SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
-               1148 9521  SK-9521 10/100/1000Base-T Adapter
-       4400  SK-9Dxx Gigabit Ethernet Adapter
-       4500  SK-9Mxx Gigabit Ethernet Adapter
-       9000  SK-9Sxx Gigabit Ethernet Server Adapter PCI-X
-       9843  [Fujitsu] Gigabit Ethernet
-       9e00  SK-9Exx 10/100/1000Base-T Adapter
-               1148 2100  SK-9E21 Server Adapter
-               1148 21d0  SK-9E21D 10/100/1000Base-T Adapter
-               1148 2200  SK-9E22 Server Adapter
-               1148 8100  SK-9E81 Server Adapter
-               1148 8200  SK-9E82 Server Adapter
-               1148 9100  SK-9E91 Server Adapter
-               1148 9200  SK-9E92 Server Adapter
-1149  Win System Corporation
-114a  VMIC
-       5579  VMIPCI-5579 (Reflective Memory Card)
-       5587  VMIPCI-5587 (Reflective Memory Card)
-       6504  VMIC PCI 7755 FPGA
-       7587  VMIVME-7587
-114b  Canopus Co., Ltd
-114c  Annabooks
-114d  IC Corporation
-114e  Nikon Systems Inc
-114f  Digi International
-       0002  AccelePort EPC
-       0003  RightSwitch SE-6
-       0004  AccelePort Xem
-       0005  AccelePort Xr
-       0006  AccelePort Xr,C/X
-       0009  AccelePort Xr/J
-       000a  AccelePort EPC/J
-       000c  DataFirePRIme T1 (1-port)
-       000d  SyncPort 2-Port (x.25/FR)
-       0011  AccelePort 8r EIA-232 (IBM)
-       0012  AccelePort 8r EIA-422
-       0013  AccelePort Xr
-       0014  AccelePort 8r EIA-422
-       0015  AccelePort Xem
-       0016  AccelePort EPC/X
-       0017  AccelePort C/X
-       001a  DataFirePRIme E1 (1-port)
-       001b  AccelePort C/X (IBM)
-       001d  DataFire RAS T1/E1/PRI
-               114f 0050  DataFire RAS E1 Adapter
-               114f 0051  DataFire RAS Dual E1 Adapter
-               114f 0052  DataFire RAS T1 Adapter
-               114f 0053  DataFire RAS Dual T1 Adapter
-       0023  AccelePort RAS
-       0024  DataFire RAS B4 ST/U
-               114f 0030  DataFire RAS BRI U Adapter
-               114f 0031  DataFire RAS BRI S/T Adapter
-       0026  AccelePort 4r 920
-       0027  AccelePort Xr 920
-       0028  ClassicBoard 4
-       0029  ClassicBoard 8
-       0034  AccelePort 2r 920
-       0035  DataFire DSP T1/E1/PRI cPCI
-       0040  AccelePort Xp
-       0042  AccelePort 2p
-       0043  AccelePort 4p
-       0044  AccelePort 8p
-       0045  AccelePort 16p
-       004e  AccelePort 32p
-       0070  Datafire Micro V IOM2 (Europe)
-       0071  Datafire Micro V (Europe)
-       0072  Datafire Micro V IOM2 (North America)
-       0073  Datafire Micro V (North America)
-       00b0  Digi Neo 4
-       00b1  Digi Neo 8
-       00c8  Digi Neo 2 DB9
-       00c9  Digi Neo 2 DB9 PRI
-       00ca  Digi Neo 2 RJ45
-       00cb  Digi Neo 2 RJ45 PRI
-       00d0  ClassicBoard 4 422
-       00d1  ClassicBoard 8 422
-       6001  Avanstar
-1150  Thinking Machines Corp
-1151  JAE Electronics Inc.
-1152  Megatek
-1153  Land Win Electronic Corp
-1154  Melco Inc
-1155  Pine Technology Ltd
-1156  Periscope Engineering
-1157  Avsys Corporation
-1158  Voarx R & D Inc
-       3011  Tokenet/vg 1001/10m anylan
-       9050  Lanfleet/Truevalue
-       9051  Lanfleet/Truevalue
-1159  Mutech Corp
-       0001  MV-1000
-115a  Harlequin Ltd
-115b  Parallax Graphics
-115c  Photron Ltd.
-115d  Xircom
-       0003  Cardbus Ethernet 10/100
-               1014 0181  10/100 EtherJet Cardbus Adapter
-               1014 1181  10/100 EtherJet Cardbus Adapter
-               1014 8181  10/100 EtherJet Cardbus Adapter
-               1014 9181  10/100 EtherJet Cardbus Adapter
-               115d 0181  Cardbus Ethernet 10/100
-               115d 1181  Cardbus Ethernet 10/100
-               1179 0181  Cardbus Ethernet 10/100
-               8086 8181  EtherExpress PRO/100 Mobile CardBus 32 Adapter
-               8086 9181  EtherExpress PRO/100 Mobile CardBus 32 Adapter
-       0005  Cardbus Ethernet 10/100
-               1014 0182  10/100 EtherJet Cardbus Adapter
-               1014 1182  10/100 EtherJet Cardbus Adapter
-               115d 0182  Cardbus Ethernet 10/100
-               115d 1182  Cardbus Ethernet 10/100
-       0007  Cardbus Ethernet 10/100
-               1014 0182  10/100 EtherJet Cardbus Adapter
-               1014 1182  10/100 EtherJet Cardbus Adapter
-               115d 0182  Cardbus Ethernet 10/100
-               115d 1182  Cardbus Ethernet 10/100
-       000b  Cardbus Ethernet 10/100
-               1014 0183  10/100 EtherJet Cardbus Adapter
-               115d 0183  Cardbus Ethernet 10/100
-       000c  Mini-PCI V.90 56k Modem
-       000f  Cardbus Ethernet 10/100
-               1014 0183  10/100 EtherJet Cardbus Adapter
-               115d 0183  Cardbus Ethernet 10/100
-       00d4  Mini-PCI K56Flex Modem
-       0101  Cardbus 56k modem
-               115d 1081  Cardbus 56k Modem
-       0103  Cardbus Ethernet + 56k Modem
-               1014 9181  Cardbus 56k Modem
-               1115 1181  Cardbus Ethernet 100 + 56k Modem
-               115d 1181  CBEM56G-100 Ethernet + 56k Modem
-               8086 9181  PRO/100 LAN + Modem56 CardBus
-115e  Peer Protocols Inc
-115f  Maxtor Corporation
-1160  Megasoft Inc
-1161  PFU Limited
-1162  OA Laboratory Co Ltd
-1163  Rendition
-       0001  Verite 1000
-       2000  Verite V2000/V2100/V2200
-               1092 2000  Stealth II S220
-1164  Advanced Peripherals Technologies
-1165  Imagraph Corporation
-       0001  Motion TPEG Recorder/Player with audio
-1166  ServerWorks
-       0000  CMIC-LE
-       0005  CNB20-LE Host Bridge
-       0006  CNB20HE Host Bridge
-       0007  CNB20-LE Host Bridge
-       0008  CNB20HE Host Bridge
-       0009  CNB20LE Host Bridge
-       0010  CIOB30
-       0011  CMIC-HE
-       0012  CMIC-WS Host Bridge (GC-LE chipset)
-       0013  CNB20-HE Host Bridge
-       0014  CMIC-LE Host Bridge (GC-LE chipset)
-       0015  CMIC-GC Host Bridge
-       0016  CMIC-GC Host Bridge
-       0017  GCNB-LE Host Bridge
-       0101  CIOB-X2 PCI-X I/O Bridge
-       0110  CIOB-E I/O Bridge with Gigabit Ethernet
-       0200  OSB4 South Bridge
-       0201  CSB5 South Bridge
-               4c53 1080  CT8 mainboard
-       0203  CSB6 South Bridge
-       0211  OSB4 IDE Controller
-       0212  CSB5 IDE Controller
-               4c53 1080  CT8 mainboard
-       0213  CSB6 RAID/IDE Controller
-       0217  CSB6 IDE Controller
-       0220  OSB4/CSB5 OHCI USB Controller
-               4c53 1080  CT8 mainboard
-       0221  CSB6 OHCI USB Controller
-       0225  CSB5 LPC bridge
-# cancelled
-               4c53 1080  CT8 mainboard
-       0227  GCLE-2 Host Bridge
-       0230  CSB5 LPC bridge
-               4c53 1080  CT8 mainboard
-       0240  K2 SATA
-       0241  K2 SATA
-       0242  K2 SATA
-1167  Mutoh Industries Inc
-1168  Thine Electronics Inc
-1169  Centre for Development of Advanced Computing
-116a  Polaris Communications
-       6100  Bus/Tag Channel
-       6800  Escon Channel
-       7100  Bus/Tag Channel
-       7800  Escon Channel
-116b  Connectware Inc
-116c  Intelligent Resources Integrated Systems
-116d  Martin-Marietta
-116e  Electronics for Imaging
-116f  Workstation Technology
-1170  Inventec Corporation
-1171  Loughborough Sound Images Plc
-1172  Altera Corporation
-1173  Adobe Systems, Inc
-1174  Bridgeport Machines
-1175  Mitron Computer Inc.
-1176  SBE Incorporated
-1177  Silicon Engineering
-1178  Alfa, Inc.
-       afa1  Fast Ethernet Adapter
-1179  Toshiba America Info Systems
-       0103  EX-IDE Type-B
-       0404  DVD Decoder card
-       0406  Tecra Video Capture device
-       0407  DVD Decoder card (Version 2)
-       0601  CPU to PCI bridge
-       0603  ToPIC95 PCI to CardBus Bridge for Notebooks
-       060a  ToPIC95
-       060f  ToPIC97
-       0617  ToPIC100 PCI to Cardbus Bridge with ZV Support
-       0618  CPU to PCI and PCI to ISA bridge
-# Claimed to be Lucent DSP1645 [Mars], but that's apparently incorrect. Does anyone know the correct ID?
-       0701  FIR Port
-       0804  TC6371AF SmartMedia Controller
-       0805  SD TypA Controller
-       0d01  FIR Port Type-DO
-               1179 0001  FIR Port Type-DO
-117a  A-Trend Technology
-117b  L G Electronics, Inc.
-117c  Atto Technology
-117d  Becton & Dickinson
-117e  T/R Systems
-117f  Integrated Circuit Systems
-1180  Ricoh Co Ltd
-       0465  RL5c465
-       0466  RL5c466
-       0475  RL5c475
-               144d c006  vpr Matrix 170B4 CardBus bridge
-       0476  RL5c476 II
-               1014 0185  ThinkPad A/T/X Series
-               104d 80df  Vaio PCG-FX403
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               14ef 0220  PCD-RP-220S
-       0477  RL5c477
-       0478  RL5c478
-               1014 0184  ThinkPad A30p (2653-64G)
-       0522  R5C522 IEEE 1394 Controller
-               1014 01cf  ThinkPad A30p (2653-64G)
-       0551  R5C551 IEEE 1394 Controller
-               144d c006  vpr Matrix 170B4
-       0552  R5C552 IEEE 1394 Controller
-               1014 0511  ThinkPad A/T/X Series
-       0576  R5C576 SD Bus Host Adapter
-       0592  R5C592 Memory Stick Bus Host Adapter
-1181  Telmatics International
-1183  Fujikura Ltd
-1184  Forks Inc
-1185  Dataworld International Ltd
-1186  D-Link System Inc
-       0100  DC21041
-       1002  DL10050 Sundance Ethernet
-               1186 1002  DFE-550TX
-               1186 1012  DFE-580TX
-       1025  AirPlus Xtreme G DWL-G650 Adapter
-       1026  AirXpert DWL-AG650 Wireless Cardbus Adapter
-       1043  AirXpert DWL-AG650 Wireless Cardbus Adapter
-       1300  RTL8139 Ethernet
-               1186 1300  DFE-538TX 10/100 Ethernet Adapter
-               1186 1301  DFE-530TX+ 10/100 Ethernet Adapter
-       1340  DFE-690TXD CardBus PC Card
-       1541  DFE-680TXD CardBus PC Card
-       1561  DRP-32TXD Cardbus PC Card
-       2027  AirPlus Xtreme G DWL-G520 Adapter
-       3203  AirPlus Xtreme G DWL-G520 Adapter
-       3300  DWL-510 2.4GHz Wireless PCI Adapter
-       3a03  AirPro DWL-A650 Wireless Cardbus Adapter(rev.B)
-       3a04  AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
-       3a05  AirPro DWL-AB520 Multimode Wireless PCI Adapter
-       3a07  AirXpert DWL-AG650 Wireless Cardbus Adapter
-       3a08  AirXpert DWL-AG520 Wireless PCI Adapter
-       3a10  AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
-       3a11  AirXpert DWL-AG520 Wireless PCI Adapter(rev.B)
-       3a12  AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
-       3a13  AirPlus DWL-G520 Wireless PCI Adapter(rev.B)
-       3a14  AirPremier DWL-AG530 Wireless PCI Adapter
-       3a63  AirXpert DWL-AG660 Wireless Cardbus Adapter
-       3b05  DWL-G650+ CardBus PC Card
-       4000  DL2000-based Gigabit Ethernet
-       4300  DGE-528T Gigabit Ethernet Adapter
-       4c00  Gigabit Ethernet Adapter
-               1186 4c00  DGE-530T Gigabit Ethernet Adapter
-       8400  D-Link DWL-650+ CardBus PC Card
-1187  Advanced Technology Laboratories, Inc.
-1188  Shima Seiki Manufacturing Ltd.
-1189  Matsushita Electronics Co Ltd
-118a  Hilevel Technology
-118b  Hypertec Pty Limited
-118c  Corollary, Inc
-       0014  PCIB [C-bus II to PCI bus host bridge chip]
-       1117  Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
-118d  BitFlow Inc
-       0001  Raptor-PCI framegrabber
-       0012  Model 12 Road Runner Frame Grabber
-       0014  Model 14 Road Runner Frame Grabber
-       0024  Model 24 Road Runner Frame Grabber
-       0044  Model 44 Road Runner Frame Grabber
-       0112  Model 12 Road Runner Frame Grabber
-       0114  Model 14 Road Runner Frame Grabber
-       0124  Model 24 Road Runner Frame Grabber
-       0144  Model 44 Road Runner Frame Grabber
-       0212  Model 12 Road Runner Frame Grabber
-       0214  Model 14 Road Runner Frame Grabber
-       0224  Model 24 Road Runner Frame Grabber
-       0244  Model 44 Road Runner Frame Grabber
-       0312  Model 12 Road Runner Frame Grabber
-       0314  Model 14 Road Runner Frame Grabber
-       0324  Model 24 Road Runner Frame Grabber
-       0344  Model 44 Road Runner Frame Grabber
-118e  Hermstedt GmbH
-118f  Green Logic
-1190  Tripace
-       c731  TP-910/920/940 PCI Ultra(Wide) SCSI Adapter
-1191  Artop Electronic Corp
-       0003  SCSI Cache Host Adapter
-       0004  ATP8400
-       0005  ATP850UF
-       0006  ATP860 NO-BIOS
-       0007  ATP860
-       0008  ATP865 NO-ROM
-       0009  ATP865
-       8002  AEC6710 SCSI-2 Host Adapter
-       8010  AEC6712UW SCSI
-       8020  AEC6712U SCSI
-       8030  AEC6712S SCSI
-       8040  AEC6712D SCSI
-       8050  AEC6712SUW SCSI
-       8060  AEC6712 SCSI
-       8080  AEC67160 SCSI
-       8081  AEC67160S SCSI
-       808a  AEC67162 2-ch. LVD SCSI
-1192  Densan Company Ltd
-1193  Zeitnet Inc.
-       0001  1221
-       0002  1225
-1194  Toucan Technology
-1195  Ratoc System Inc
-1196  Hytec Electronics Ltd
-1197  Gage Applied Sciences, Inc.
-       010c  CompuScope 82G 8bit 2GS/s Analog Input Card
-1198  Lambda Systems Inc
-1199  Attachmate Corporation
-119a  Mind Share, Inc.
-119b  Omega Micro Inc.
-       1221  82C092G
-119c  Information Technology Inst.
-119d  Bug, Inc. Sapporo Japan
-119e  Fujitsu Microelectronics Ltd.
-       0001  FireStream 155
-       0003  FireStream 50
-119f  Bull HN Information Systems
-11a0  Convex Computer Corporation
-11a1  Hamamatsu Photonics K.K.
-11a2  Sierra Research and Technology
-11a3  Deuretzbacher GmbH & Co. Eng. KG
-11a4  Barco Graphics NV
-11a5  Microunity Systems Eng. Inc
-11a6  Pure Data Ltd.
-11a7  Power Computing Corp.
-11a8  Systech Corp.
-11a9  InnoSys Inc.
-       4240  AMCC S933Q Intelligent Serial Card
-11aa  Actel
-# Formerly Galileo Technology, Inc.
-11ab  Marvell Technology Group Ltd.
-       0146  GT-64010/64010A System Controller
-       138f  W8300 802.11 Adapter (rev 07)
-       1fa6  Marvell W8300 802.11 Adapter
-       1fa7  88W8310 and 88W8000G [Libertas] 802.11g client chipset
-       4320  Gigabit Ethernet Controller
-               1019 0f38  Marvell 88E8001 Gigabit Ethernet Controller (ECS)
-               1019 8001  Marvell 88E8001 Gigabit Ethernet Controller (ECS)
-               1043 173c  Marvell 88E8001 Gigabit Ethernet Controller (Asus)
-               1043 811a  Marvell 88E8001 Gigabit Ethernet Controller (Asus)
-               105b 0c19  Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
-               10b8 b452  SMC EZ Card 1000 (SMC9452TXV.2)
-               11ab 0121  Marvell RDK-8001
-               11ab 0321  Marvell RDK-8003
-               11ab 1021  Marvell RDK-8010
-               11ab 5021  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
-               11ab 9521  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
-               1458 e000  Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
-               147b 1406  Marvell 88E8001 Gigabit Ethernet Controller (Abit)
-               15d4 0047  Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
-               1695 9025  Marvell 88E8001 Gigabit Ethernet Controller (Epox)
-               17f2 1c03  Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
-               270f 2803  Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
-       4350  Fast Ethernet Controller
-               1179 0001  Marvell 88E8035 Fast Ethernet Controller (Toshiba)
-               11ab 3521  Marvell RDK-8035
-               1854 000d  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 000e  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 000f  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0011  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0012  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0016  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0017  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0018  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0019  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 001c  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 001e  Marvell 88E8035 Fast Ethernet Controller (LGE)
-               1854 0020  Marvell 88E8035 Fast Ethernet Controller (LGE)
-       4351  Fast Ethernet Controller
-               107b 4009  Marvell 88E8036 Fast Ethernet Controller (Wistron)
-               10f7 8338  Marvell 88E8036 Fast Ethernet Controller (Panasonic)
-               1179 0001  Marvell 88E8036 Fast Ethernet Controller (Toshiba)
-               1179 ff00  Marvell 88E8036 Fast Ethernet Controller (Compal)
-               1179 ff10  Marvell 88E8036 Fast Ethernet Controller (Inventec)
-               11ab 3621  Marvell RDK-8036
-               13d1 ac12  Abocom EFE3K - 10/100 Ethernet Expresscard
-               161f 203d  Marvell 88E8036 Fast Ethernet Controller (Arima)
-               1854 000d  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 000e  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 000f  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0011  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0012  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0016  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0017  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0018  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0019  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 001c  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 001e  Marvell 88E8036 Fast Ethernet Controller (LGE)
-               1854 0020  Marvell 88E8036 Fast Ethernet Controller (LGE)
-       4360  Gigabit Ethernet Controller
-               1043 8134  Marvell 88E8052 Gigabit Ethernet Controller (Asus)
-               107b 4009  Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
-               11ab 5221  Marvell RDK-8052
-               1458 e000  Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
-               1462 052c  Marvell 88E8052 Gigabit Ethernet Controller (MSI)
-               1849 8052  Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
-               1940 e000  Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
-               a0a0 0509  Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
-       4361  Gigabit Ethernet Controller
-               107b 3015  Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
-               11ab 5021  Marvell 88E8050 Gigabit Ethernet Controller (Intel)
-               8086 3063  D925XCVLK mainboard
-       4362  Gigabit Ethernet Controller
-               103c 2a0d  Marvell 88E8053 Gigabit Ethernet Controller (Asus)
-               1043 8142  Marvell 88E8053 Gigabit Ethernet Controller (Asus)
-               109f 3197  Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
-               10f7 8338  Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
-               10fd a430  Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
-               1179 0001  Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
-               1179 ff00  Marvell 88E8053 Gigabit Ethernet Controller (Compal)
-               1179 ff10  Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
-               11ab 5321  Marvell RDK-8053
-               1297 c240  Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
-               1297 c241  Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
-               1297 c242  Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
-               1297 c243  Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
-               1297 c244  Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
-               13d1 ac11  Abocom EGE5K - Giga Ethernet Expresscard
-               1458 e000  Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
-               1462 058c  Marvell 88E8053 Gigabit Ethernet Controller (MSI)
-               14c0 0012  Marvell 88E8053 Gigabit Ethernet Controller (Compal)
-               1558 04a0  Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
-               15bd 1003  Marvell 88E8053 Gigabit Ethernet Controller (DFI)
-               161f 203c  Marvell 88E8053 Gigabit Ethernet Controller (Arima)
-               161f 203d  Marvell 88E8053 Gigabit Ethernet Controller (Arima)
-               1695 9029  Marvell 88E8053 Gigabit Ethernet Controller (Epox)
-               17f2 2c08  Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
-               17ff 0585  Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
-               1849 8053  Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
-               1854 000b  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 000c  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 0010  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 0013  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 0014  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 0015  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 001a  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 001b  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 001d  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 001f  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 0021  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1854 0022  Marvell 88E8053 Gigabit Ethernet Controller (LGE)
-               1940 e000  Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
-               270f 2801  Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
-               a0a0 0506  Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
-       4611  GT-64115 System Controller
-       4620  GT-64120/64120A/64121A System Controller
-       4801  GT-48001
-       5005  Belkin F5D5005 Gigabit Desktop Network PCI Card
-       5040  MV88SX5040 4-port SATA I PCI-X Controller
-       5041  MV88SX5041 4-port SATA I PCI-X Controller
-       5080  MV88SX5080 8-port SATA I PCI-X Controller
-       5081  MV88SX5081 8-port SATA I PCI-X Controller
-       6041  MV88SX6041 4-port SATA II PCI-X Controller
-       6081  MV88SX6081 8-port SATA II PCI-X Controller
-       6460  MV64360/64361/64362 System Controller
-       f003  GT-64010 Primary Image Piranha Image Generator
-11ac  Canon Information Systems Research Aust.
-11ad  Lite-On Communications Inc
-       0002  LNE100TX
-               11ad 0002  LNE100TX
-               11ad 0003  LNE100TX
-               11ad f003  LNE100TX
-               11ad ffff  LNE100TX
-               1385 f004  FA310TX
-       c115  LNE100TX [Linksys EtherFast 10/100]
-               11ad c001  LNE100TX [ver 2.0]
-11ae  Aztech System Ltd
-11af  Avid Technology Inc.
-       0001  [Cinema]
-11b0  V3 Semiconductor Inc.
-       0002  V300PSC
-       0292  V292PBC [Am29030/40 Bridge]
-       0960  V96xPBC
-       c960  V96DPC
-11b1  Apricot Computers
-11b2  Eastman Kodak
-11b3  Barr Systems Inc.
-11b4  Leitch Technology International
-11b5  Radstone Technology Plc
-11b6  United Video Corp
-11b7  Motorola
-11b8  XPoint Technologies, Inc
-       0001  Quad PeerMaster
-11b9  Pathlight Technology Inc.
-       c0ed  SSA Controller
-11ba  Videotron Corp
-11bb  Pyramid Technology
-11bc  Network Peripherals Inc
-       0001  NP-PCI
-11bd  Pinnacle Systems Inc.
-11be  International Microcircuits Inc
-11bf  Astrodesign, Inc.
-11c0  Hewlett Packard
-11c1  Agere Systems (former Lucent Microelectronics)
-       0440  56k WinModem
-               1033 8015  LT WinModem 56k Data+Fax+Voice+Dsvd
-               1033 8047  LT WinModem 56k Data+Fax+Voice+Dsvd
-               1033 804f  LT WinModem 56k Data+Fax+Voice+Dsvd
-               10cf 102c  LB LT Modem V.90 56k
-               10cf 104a  BIBLO LT Modem 56k
-               10cf 105f  LB2 LT Modem V.90 56k
-               1179 0001  Internal V.90 Modem
-               11c1 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
-               122d 4101  MDP7800-U Modem
-               122d 4102  MDP7800SP-U Modem
-               13e0 0040  LT WinModem 56k Data+Fax+Voice+Dsvd
-               13e0 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
-               13e0 0441  LT WinModem 56k Data+Fax+Voice+Dsvd
-               13e0 0450  LT WinModem 56k Data+Fax+Voice+Dsvd
-               13e0 f100  LT WinModem 56k Data+Fax+Voice+Dsvd
-               13e0 f101  LT WinModem 56k Data+Fax+Voice+Dsvd
-               144d 2101  LT56PV Modem
-               149f 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
-       0441  56k WinModem
-               1033 804d  LT WinModem 56k Data+Fax
-               1033 8065  LT WinModem 56k Data+Fax
-               1092 0440  Supra 56i
-               1179 0001  Internal V.90 Modem
-               11c1 0440  LT WinModem 56k Data+Fax
-               11c1 0441  LT WinModem 56k Data+Fax
-               122d 4100  MDP7800-U Modem
-               13e0 0040  LT WinModem 56k Data+Fax
-               13e0 0100  LT WinModem 56k Data+Fax
-               13e0 0410  LT WinModem 56k Data+Fax
-               13e0 0420  TelePath Internet 56k WinModem
-               13e0 0440  LT WinModem 56k Data+Fax
-               13e0 0443  LT WinModem 56k Data+Fax
-               13e0 f102  LT WinModem 56k Data+Fax
-               1416 9804  CommWave 56k Modem
-               141d 0440  LT WinModem 56k Data+Fax
-               144f 0441  Lucent 56k V.90 DF Modem
-               144f 0449  Lucent 56k V.90 DF Modem
-               144f 110d  Lucent Win Modem
-               1468 0441  Presario 56k V.90 DF Modem
-               1668 0440  Lucent Win Modem
-       0442  56k WinModem
-               11c1 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               11c1 0442  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               13e0 0412  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               13e0 0442  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               13fc 2471  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               144d 2104  LT56PT Modem
-               144f 1104  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               149f 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               1668 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-       0443  LT WinModem
-       0444  LT WinModem
-       0445  LT WinModem
-               8086 2203  PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
-               8086 2204  PRO/100+ MiniPCI on Armada E500
-       0446  LT WinModem
-       0447  LT WinModem
-       0448  WinModem 56k
-               1014 0131  Lucent Win Modem
-               1033 8066  LT WinModem 56k Data+Fax+Voice+Dsvd
-               13e0 0030  56k Voice Modem
-               13e0 0040  LT WinModem 56k Data+Fax+Voice+Dsvd
-# Actiontech eth+modem card as used by Dell &c.
-               1668 2400  LT WinModem 56k (MiniPCI Ethernet+Modem)
-       0449  WinModem 56k
-               0e11 b14d  56k V.90 Modem
-               13e0 0020  LT WinModem 56k Data+Fax
-               13e0 0041  TelePath Internet 56k WinModem
-               1436 0440  Lucent Win Modem
-               144f 0449  Lucent 56k V.90 DFi Modem
-               1468 0410  IBM ThinkPad T23 (2647-4MG)
-               1468 0440  Lucent Win Modem
-               1468 0449  Presario 56k V.90 DFi Modem
-       044a  F-1156IV WinModem (V90, 56KFlex)
-               10cf 1072  LB Global LT Modem
-               13e0 0012  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               13e0 0042  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-               144f 1005  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
-       044b  LT WinModem
-       044c  LT WinModem
-       044d  LT WinModem
-       044e  LT WinModem
-       044f  V90 WildWire Modem
-       0450  LT WinModem
-               1033 80a8  Versa Note Vxi
-               144f 4005  Magnia SG20
-       0451  LT WinModem
-       0452  LT WinModem
-       0453  LT WinModem
-       0454  LT WinModem
-       0455  LT WinModem
-       0456  LT WinModem
-       0457  LT WinModem
-       0458  LT WinModem
-       0459  LT WinModem
-       045a  LT WinModem
-       045c  LT WinModem
-       0461  V90 WildWire Modem
-       0462  V90 WildWire Modem
-       0480  Venus Modem (V90, 56KFlex)
-       048c  V.92 56K WinModem
-# InPorte Home Internal 56k Modem/fax/answering machine/SMS Features
-       048f  V.92 56k WinModem
-       5801  USB
-       5802  USS-312 USB Controller
-# 4 port PCI USB Controller made by Agere (formely Lucent)
-       5803  USS-344S USB Controller
-       5811  FW323
-               8086 524c  D865PERL mainboard
-               dead 0800  FireWire Host Bus Adapter
-       ab10  WL60010 Wireless LAN MAC
-       ab11  WL60040 Multimode Wireles LAN MAC
-               11c1 ab12  WaveLAN 11abg Cardbus card (Model 1102)
-               11c1 ab13  WaveLAN 11abg MiniPCI card (Model 0512)
-               11c1 ab15  WaveLAN 11abg Cardbus card (Model 1106)
-               11c1 ab16  WaveLAN 11abg MiniPCI card (Model 0516)
-       ab20  ORiNOCO PCI Adapter
-       ab21  Agere Wireless PCI Adapter
-       ab30  Hermes2 Mini-PCI WaveLAN a/b/g
-               14cd 2012  Hermes2 Mini-PCI WaveLAN a/b/g
-11c2  Sand Microelectronics
-11c3  NEC Corporation
-11c4  Document Technologies, Inc
-11c5  Shiva Corporation
-11c6  Dainippon Screen Mfg. Co. Ltd
-11c7  D.C.M. Data Systems
-11c8  Dolphin Interconnect Solutions AS
-       0658  PSB32 SCI-Adapter D31x
-       d665  PSB64 SCI-Adapter D32x
-       d667  PSB66 SCI-Adapter D33x
-11c9  Magma
-       0010  16-line serial port w/- DMA
-       0011  4-line serial port w/- DMA
-11ca  LSI Systems, Inc
-11cb  Specialix Research Ltd.
-       2000  PCI_9050
-               11cb 0200  SX
-               11cb b008  I/O8+
-       4000  SUPI_1
-       8000  T225
-11cc  Michels & Kleberhoff Computer GmbH
-11cd  HAL Computer Systems, Inc.
-11ce  Netaccess
-11cf  Pioneer Electronic Corporation
-11d0  Lockheed Martin Federal Systems-Manassas
-11d1  Auravision
-       01f7  VxP524
-11d2  Intercom Inc.
-11d3  Trancell Systems Inc
-11d4  Analog Devices
-       1535  Blackfin BF535 processor
-       1805  SM56 PCI modem
-       1889  AD1889 sound chip
-11d5  Ikon Corporation
-       0115  10115
-       0117  10117
-11d6  Tekelec Telecom
-11d7  Trenton Technology, Inc.
-11d8  Image Technologies Development
-11d9  TEC Corporation
-11da  Novell
-11db  Sega Enterprises Ltd
-11dc  Questra Corporation
-11dd  Crosfield Electronics Limited
-11de  Zoran Corporation
-       6057  ZR36057PQC Video cutting chipset
-               1031 7efe  DC10 Plus
-               1031 fc00  MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
-               13ca 4231  JPEG/TV Card
-       6120  ZR36120
-               1328 f001  Cinemaster C DVD Decoder
-11df  New Wave PDG
-11e0  Cray Communications A/S
-11e1  GEC Plessey Semi Inc.
-11e2  Samsung Information Systems America
-11e3  Quicklogic Corporation
-       5030  PC Watchdog
-11e4  Second Wave Inc
-11e5  IIX Consulting
-11e6  Mitsui-Zosen System Research
-11e7  Toshiba America, Elec. Company
-11e8  Digital Processing Systems Inc.
-11e9  Highwater Designs Ltd.
-11ea  Elsag Bailey
-11eb  Formation Inc.
-11ec  Coreco Inc
-11ed  Mediamatics
-11ee  Dome Imaging Systems Inc
-11ef  Nicolet Technologies B.V.
-11f0  Compu-Shack
-       4231  FDDI
-       4232  FASTline UTP Quattro
-       4233  FASTline FO
-       4234  FASTline UTP
-       4235  FASTline-II UTP
-       4236  FASTline-II FO
-       4731  GIGAline
-11f1  Symbios Logic Inc
-11f2  Picture Tel Japan K.K.
-11f3  Keithley Metrabyte
-11f4  Kinetic Systems Corporation
-       2915  CAMAC controller
-11f5  Computing Devices International
-11f6  Compex
-       0112  ENet100VG4
-       0113  FreedomLine 100
-       1401  ReadyLink 2000
-       2011  RL100-ATX 10/100
-               11f6 2011  RL100-ATX
-       2201  ReadyLink 100TX (Winbond W89C840)
-               11f6 2011  ReadyLink 100TX
-       9881  RL100TX Fast Ethernet
-11f7  Scientific Atlanta
-11f8  PMC-Sierra Inc.
-       7375  PM7375 [LASAR-155 ATM SAR]
-11f9  I-Cube Inc
-11fa  Kasan Electronics Company, Ltd.
-11fb  Datel Inc
-11fc  Silicon Magic
-11fd  High Street Consultants
-11fe  Comtrol Corporation
-       0001  RocketPort 32 port w/external I/F
-       0002  RocketPort 8 port w/external I/F
-       0003  RocketPort 16 port w/external I/F
-       0004  RocketPort 4 port w/quad cable
-       0005  RocketPort 8 port w/octa cable
-       0006  RocketPort 8 port w/RJ11 connectors
-       0007  RocketPort 4 port w/RJ11 connectors
-       0008  RocketPort 8 port w/ DB78 SNI (Siemens) connector
-       0009  RocketPort 16 port w/ DB78 SNI (Siemens) connector
-       000a  RocketPort Plus 4 port
-       000b  RocketPort Plus 8 port
-       000c  RocketModem 6 port
-       000d  RocketModem 4-port
-       000e  RocketPort Plus 2 port RS232
-       000f  RocketPort Plus 2 port RS422
-       0801  RocketPort UPCI 32 port w/external I/F
-       0802  RocketPort UPCI 8 port w/external I/F
-       0803  RocketPort UPCI 16 port w/external I/F
-       0805  RocketPort UPCI 8 port w/octa cable
-       080c  RocketModem III 8 port
-       080d  RocketModem III 4 port
-       0903  RocketPort Compact PCI 16 port w/external I/F
-       8015  RocketPort 4-port UART 16954
-11ff  Scion Corporation
-       0003  AG-5
-1200  CSS Corporation
-1201  Vista Controls Corp
-1202  Network General Corp.
-       4300  Gigabit Ethernet Adapter
-               1202 9841  SK-9841 LX
-               1202 9842  SK-9841 LX dual link
-               1202 9843  SK-9843 SX
-               1202 9844  SK-9843 SX dual link
-1203  Bayer Corporation, Agfa Division
-1204  Lattice Semiconductor Corporation
-1205  Array Corporation
-1206  Amdahl Corporation
-1208  Parsytec GmbH
-       4853  HS-Link Device
-1209  SCI Systems Inc
-120a  Synaptel
-120b  Adaptive Solutions
-120c  Technical Corp.
-120d  Compression Labs, Inc.
-120e  Cyclades Corporation
-       0100  Cyclom-Y below first megabyte
-       0101  Cyclom-Y above first megabyte
-       0102  Cyclom-4Y below first megabyte
-       0103  Cyclom-4Y above first megabyte
-       0104  Cyclom-8Y below first megabyte
-       0105  Cyclom-8Y above first megabyte
-       0200  Cyclades-Z below first megabyte
-       0201  Cyclades-Z above first megabyte
-       0300  PC300/RSV or /X21 (2 ports)
-       0301  PC300/RSV or /X21 (1 port)
-       0310  PC300/TE (2 ports)
-       0311  PC300/TE (1 port)
-       0320  PC300/TE-M (2 ports)
-       0321  PC300/TE-M (1 port)
-       0400  PC400
-120f  Essential Communications
-       0001  Roadrunner serial HIPPI
-1210  Hyperparallel Technologies
-1211  Braintech Inc
-1212  Kingston Technology Corp.
-1213  Applied Intelligent Systems, Inc.
-1214  Performance Technologies, Inc.
-1215  Interware Co., Ltd
-1216  Purup Prepress A/S
-1217  O2 Micro, Inc.
-       6729  OZ6729
-       673a  OZ6730
-       6832  OZ6832/6833 CardBus Controller
-       6836  OZ6836/6860 CardBus Controller
-       6872  OZ6812 CardBus Controller
-       6925  OZ6922 CardBus Controller
-       6933  OZ6933/711E1 CardBus/SmartCardBus Controller
-               1025 1016  Travelmate 612 TX
-       6972  OZ601/6912/711E0 CardBus/SmartCardBus Controller
-               1014 020c  ThinkPad R30
-               1179 0001  Magnia Z310
-       7110  OZ711Mx 4-in-1 MemoryCardBus Accelerator
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-       7112  OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
-       7113  OZ711EC1 SmartCardBus Controller
-       7114  OZ711M1/MC1 4-in-1 MemoryCardBus Controller
-       7134  OZ711MP1/MS1 MemoryCardBus Controller
-       71e2  OZ711E2 SmartCardBus Controller
-       7212  OZ711M2 4-in-1 MemoryCardBus Controller
-       7213  OZ6933E CardBus Controller
-       7223  OZ711M3/MC3 4-in-1 MemoryCardBus Controller
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-       7233  OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
-1218  Hybricon Corp.
-1219  First Virtual Corporation
-121a  3Dfx Interactive, Inc.
-       0001  Voodoo
-       0002  Voodoo 2
-       0003  Voodoo Banshee
-               1092 0003  Monster Fusion
-               1092 4000  Monster Fusion
-               1092 4002  Monster Fusion
-               1092 4801  Monster Fusion AGP
-               1092 4803  Monster Fusion AGP
-               1092 8030  Monster Fusion
-               1092 8035  Monster Fusion AGP
-               10b0 0001  Dragon 4000
-               1102 1018  3D Blaster Banshee VE
-               121a 0001  Voodoo Banshee AGP
-               121a 0003  Voodoo Banshee AGP SGRAM
-               121a 0004  Voodoo Banshee
-               139c 0016  Raven
-               139c 0017  Raven
-               14af 0002  Maxi Gamer Phoenix
-       0004  Voodoo Banshee [Velocity 100]
-       0005  Voodoo 3
-               121a 0004  Voodoo3 AGP
-               121a 0030  Voodoo3 AGP
-               121a 0031  Voodoo3 AGP
-               121a 0034  Voodoo3 AGP
-               121a 0036  Voodoo3 2000 PCI
-               121a 0037  Voodoo3 AGP
-               121a 0038  Voodoo3 AGP
-               121a 003a  Voodoo3 AGP
-               121a 0044  Voodoo3
-               121a 004b  Velocity 100
-               121a 004c  Velocity 200
-               121a 004d  Voodoo3 AGP
-               121a 004e  Voodoo3 AGP
-               121a 0051  Voodoo3 AGP
-               121a 0052  Voodoo3 AGP
-               121a 0060  Voodoo3 3500 TV (NTSC)
-               121a 0061  Voodoo3 3500 TV (PAL)
-               121a 0062  Voodoo3 3500 TV (SECAM)
-       0009  Voodoo 4 / Voodoo 5
-               121a 0003  Voodoo5 PCI 5500
-               121a 0009  Voodoo5 AGP 5500/6000
-       0057  Voodoo 3/3000 [Avenger]
-121b  Advanced Telecommunications Modules
-121c  Nippon Texaco., Ltd
-121d  Lippert Automationstechnik GmbH
-121e  CSPI
-121f  Arcus Technology, Inc.
-1220  Ariel Corporation
-       1220  AMCC 5933 TMS320C80 DSP/Imaging board
-1221  Contec Co., Ltd
-1222  Ancor Communications, Inc.
-1223  Artesyn Communication Products
-       0003  PM/Link
-       0004  PM/T1
-       0005  PM/E1
-       0008  PM/SLS
-       0009  BajaSpan Resource Target
-       000a  BajaSpan Section 0
-       000b  BajaSpan Section 1
-       000c  BajaSpan Section 2
-       000d  BajaSpan Section 3
-       000e  PM/PPC
-1224  Interactive Images
-1225  Power I/O, Inc.
-1227  Tech-Source
-       0006  Raptor GFX 8P
-1228  Norsk Elektro Optikk A/S
-1229  Data Kinesis Inc.
-122a  Integrated Telecom
-122b  LG Industrial Systems Co., Ltd
-122c  Sican GmbH
-122d  Aztech System Ltd
-       1206  368DSP
-       1400  Trident PCI288-Q3DII (NX)
-       50dc  3328 Audio
-               122d 0001  3328 Audio
-       80da  3328 Audio
-               122d 0001  3328 Audio
-122e  Xyratex
-122f  Andrew Corporation
-1230  Fishcamp Engineering
-1231  Woodward McCoach, Inc.
-1232  GPT Limited
-1233  Bus-Tech, Inc.
-1234  Technical Corp.
-1235  Risq Modular Systems, Inc.
-1236  Sigma Designs Corporation
-       0000  RealMagic64/GX
-       6401  REALmagic 64/GX (SD 6425)
-1237  Alta Technology Corporation
-1238  Adtran
-1239  3DO Company
-123a  Visicom Laboratories, Inc.
-123b  Seeq Technology, Inc.
-123c  Century Systems, Inc.
-123d  Engineering Design Team, Inc.
-       0000  EasyConnect 8/32
-       0002  EasyConnect 8/64
-       0003  EasyIO
-123e  Simutech, Inc.
-123f  C-Cube Microsystems
-       00e4  MPEG
-       8120  E4?
-               11bd 0006  DV500 E4
-               11bd 000a  DV500 E4
-               11bd 000f  DV500 E4
-       8888  Cinemaster C 3.0 DVD Decoder
-               1002 0001  Cinemaster C 3.0 DVD Decoder
-               1002 0002  Cinemaster C 3.0 DVD Decoder
-               1328 0001  Cinemaster C 3.0 DVD Decoder
-1240  Marathon Technologies Corp.
-1241  DSC Communications
-# Formerly Jaycor Networks, Inc.
-1242  JNI Corporation
-       1560  JNIC-1560 PCI-X Fibre Channel Controller
-               1242 6562  FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
-               1242 656a  FCX-6562 PCI-X Fibre Channel Adapter
-       4643  FCI-1063 Fibre Channel Adapter
-       6562  FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
-       656a  FCX-6562 PCI-X Fibre Channel Adapter
-1243  Delphax
-1244  AVM Audiovisuelles MKTG & Computer System GmbH
-       0700  B1 ISDN
-       0800  C4 ISDN
-       0a00  A1 ISDN [Fritz]
-               1244 0a00  FRITZ!Card ISDN Controller
-       0e00  Fritz!PCI v2.0 ISDN
-       1100  C2 ISDN
-       1200  T1 ISDN
-       2700  Fritz!Card DSL SL
-       2900  Fritz!Card DSL v2.0
-1245  A.P.D., S.A.
-1246  Dipix Technologies, Inc.
-1247  Xylon Research, Inc.
-1248  Central Data Corporation
-1249  Samsung Electronics Co., Ltd.
-124a  AEG Electrocom GmbH
-124b  SBS/Greenspring Modular I/O
-       0040  PCI-40A or cPCI-200 Quad IndustryPack carrier
-               124b 9080  PCI9080 Bridge
-124c  Solitron Technologies, Inc.
-124d  Stallion Technologies, Inc.
-       0000  EasyConnection 8/32
-       0002  EasyConnection 8/64
-       0003  EasyIO
-       0004  EasyConnection/RA
-124e  Cylink
-124f  Infortrend Technology, Inc.
-       0041  IFT-2000 Series RAID Controller
-1250  Hitachi Microcomputer System Ltd
-1251  VLSI Solutions Oy
-1253  Guzik Technical Enterprises
-1254  Linear Systems Ltd.
-1255  Optibase Ltd
-       1110  MPEG Forge
-       1210  MPEG Fusion
-       2110  VideoPlex
-       2120  VideoPlex CC
-       2130  VideoQuest
-1256  Perceptive Solutions, Inc.
-       4201  PCI-2220I
-       4401  PCI-2240I
-       5201  PCI-2000
-1257  Vertex Networks, Inc.
-1258  Gilbarco, Inc.
-1259  Allied Telesyn International
-       2560  AT-2560 Fast Ethernet Adapter (i82557B)
-       a117  RTL81xx Fast Ethernet
-       a120  21x4x DEC-Tulip compatible 10/100 Ethernet
-125a  ABB Power Systems
-125b  Asix Electronics Corporation
-       1400  ALFA GFC2204 Fast Ethernet
-125c  Aurora Technologies, Inc.
-       0101  Saturn 4520P
-       0640  Aries 16000P
-125d  ESS Technology
-       0000  ES336H Fax Modem (Early Model)
-       1948  Solo?
-       1968  ES1968 Maestro 2
-               1028 0085  ES1968 Maestro-2 PCI
-               1033 8051  ES1968 Maestro-2 Audiodrive
-       1969  ES1969 Solo-1 Audiodrive
-               1014 0166  ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
-               125d 8888  Solo-1 Audio Adapter
-               153b 111b  Terratec 128i PCI
-       1978  ES1978 Maestro 2E
-               0e11 b112  Armada M700/E500
-               1033 803c  ES1978 Maestro-2E Audiodrive
-               1033 8058  ES1978 Maestro-2E Audiodrive
-               1092 4000  Monster Sound MX400
-               1179 0001  ES1978 Maestro-2E Audiodrive
-       1988  ES1988 Allegro-1
-               1092 4100  Sonic Impact S100
-               125d 1988  ESS Allegro-1 Audiodrive
-       1989  ESS Modem
-               125d 1989  ESS Modem
-       1998  ES1983S Maestro-3i PCI Audio Accelerator
-               1028 00b1  Latitude C600
-               1028 00e6  ES1983S Maestro-3i (Dell Inspiron 8100)
-       1999  ES1983S Maestro-3i PCI Modem Accelerator
-       199a  ES1983S Maestro-3i PCI Audio Accelerator
-       199b  ES1983S Maestro-3i PCI Modem Accelerator
-       2808  ES336H Fax Modem (Later Model)
-       2838  ES2838/2839 SuperLink Modem
-       2898  ES2898 Modem
-               125d 0424  ES56-PI Data Fax Modem
-               125d 0425  ES56T-PI Data Fax Modem
-               125d 0426  ES56V-PI Data Fax Modem
-               125d 0427  VW-PI Data Fax Modem
-               125d 0428  ES56ST-PI Data Fax Modem
-               125d 0429  ES56SV-PI Data Fax Modem
-               147a c001  ES56-PI Data Fax Modem
-               14fe 0428  ES56-PI Data Fax Modem
-               14fe 0429  ES56-PI Data Fax Modem
-125e  Specialvideo Engineering SRL
-125f  Concurrent Technologies, Inc.
-1260  Intersil Corporation
-       3872  Prism 2.5 Wavelan chipset
-               1468 0202  LAN-Express IEEE 802.11b Wireless LAN
-       3873  Prism 2.5 Wavelan chipset
-               1186 3501  DWL-520 Wireless PCI Adapter
-               1186 3700  DWL-520 Wireless PCI Adapter, Rev E1
-               1385 4105  MA311 802.11b wireless adapter
-               1668 0414  HWP01170-01 802.11b PCI Wireless Adapter
-               16a5 1601  AIR.mate PC-400 PCI Wireless LAN Adapter
-               1737 3874  WMP11 Wireless 802.11b PCI Adapter
-               8086 2513  Wireless 802.11b MiniPCI Adapter
-       3886  ISL3886 [Prism Javelin/Prism Xbow]
-               17cf 0037  Z-Com XG-901 and clones Wireless Adapter
-       3890  Intersil ISL3890 [Prism GT/Prism Duette]
-               10b8 2802  SMC2802W Wireless PCI Adapter
-               10b8 2835  SMC2835W Wireless Cardbus Adapter
-               10b8 a835  SMC2835W V2 Wireless Cardbus Adapter
-               1113 ee03  SMC2802W V2 Wireless PCI Adapter
-               1113 ee08  SMC2835W V3 EU Wireless Cardbus Adapter
-               1186 3202  DWL-G650 A1 Wireless Adapter
-               1259 c104  CG-WLCB54GT Wireless Adapter
-               1385 4800  WG511 Wireless Adapter
-               16a5 1605  ALLNET ALL0271 Wireless PCI Adapter
-               17cf 0014  Z-Com XG-600 and clones Wireless Adapter
-               17cf 0020  Z-Com XG-900 and clones Wireless Adapter
-       8130  HMP8130 NTSC/PAL Video Decoder
-       8131  HMP8131 NTSC/PAL Video Decoder
-1261  Matsushita-Kotobuki Electronics Industries, Ltd.
-1262  ES Computer Company, Ltd.
-1263  Sonic Solutions
-1264  Aval Nagasaki Corporation
-1265  Casio Computer Co., Ltd.
-1266  Microdyne Corporation
-       0001  NE10/100 Adapter (i82557B)
-       1910  NE2000Plus (RT8029) Ethernet Adapter
-               1266 1910  NE2000Plus Ethernet Adapter
-1267  S. A. Telecommunications
-       5352  PCR2101
-       5a4b  Telsat Turbo
-1268  Tektronix
-1269  Thomson-CSF/TTM
-126a  Lexmark International, Inc.
-126b  Adax, Inc.
-126c  Northern Telecom
-       1211  10/100BaseTX [RTL81xx]
-       126c  802.11b Wireless Ethernet Adapter
-126d  Splash Technology, Inc.
-126e  Sumitomo Metal Industries, Ltd.
-126f  Silicon Motion, Inc.
-       0501  SM501 VoyagerGX
-       0710  SM710 LynxEM
-       0712  SM712 LynxEM+
-       0720  SM720 Lynx3DM
-       0730  SM731 Cougar3DR
-       0810  SM810 LynxE
-       0811  SM811 LynxE
-       0820  SM820 Lynx3D
-       0910  SM910
-1270  Olympus Optical Co., Ltd.
-1271  GW Instruments
-1272  Telematics International
-1273  Hughes Network Systems
-       0002  DirecPC
-1274  Ensoniq
-       1171  ES1373 [AudioPCI] (also Creative Labs CT5803)
-       1371  ES1371 [AudioPCI-97]
-               0e11 0024  AudioPCI on Motherboard Compaq Deskpro
-               0e11 b1a7  ES1371, ES1373 AudioPCI
-               1033 80ac  ES1371, ES1373 AudioPCI
-               1042 1854  Tazer
-               107b 8054  Tabor2
-               1274 1371  Creative Sound Blaster AudioPCI64V, AudioPCI128
-               1462 6470  ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
-               1462 6560  ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
-               1462 6630  ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
-               1462 6631  ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
-               1462 6632  ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
-               1462 6633  ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
-               1462 6820  ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
-               1462 6822  ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
-               1462 6830  ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
-               1462 6880  ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
-               1462 6900  ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
-               1462 6910  ES1371, ES1373 AudioPCI On Motherboard MS-6191
-               1462 6930  ES1371, ES1373 AudioPCI On Motherboard MS-6193
-               1462 6990  ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
-               1462 6991  ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
-               14a4 2077  ES1371, ES1373 AudioPCI On Motherboard KR639
-               14a4 2105  ES1371, ES1373 AudioPCI On Motherboard MR800
-               14a4 2107  ES1371, ES1373 AudioPCI On Motherboard MR801
-               14a4 2172  ES1371, ES1373 AudioPCI On Motherboard DR739
-               1509 9902  ES1371, ES1373 AudioPCI On Motherboard KW11
-               1509 9903  ES1371, ES1373 AudioPCI On Motherboard KW31
-               1509 9904  ES1371, ES1373 AudioPCI On Motherboard KA11
-               1509 9905  ES1371, ES1373 AudioPCI On Motherboard KC13
-               152d 8801  ES1371, ES1373 AudioPCI On Motherboard CP810E
-               152d 8802  ES1371, ES1373 AudioPCI On Motherboard CP810
-               152d 8803  ES1371, ES1373 AudioPCI On Motherboard P3810E
-               152d 8804  ES1371, ES1373 AudioPCI On Motherboard P3810-S
-               152d 8805  ES1371, ES1373 AudioPCI On Motherboard P3820-S
-               270f 2001  ES1371, ES1373 AudioPCI On Motherboard 6CTR
-               270f 2200  ES1371, ES1373 AudioPCI On Motherboard 6WTX
-               270f 3000  ES1371, ES1373 AudioPCI On Motherboard 6WSV
-               270f 3100  ES1371, ES1373 AudioPCI On Motherboard 6WIV2
-               270f 3102  ES1371, ES1373 AudioPCI On Motherboard 6WIV
-               270f 7060  ES1371, ES1373 AudioPCI On Motherboard 6ASA2
-               8086 4249  ES1371, ES1373 AudioPCI On Motherboard BI440ZX
-               8086 424c  ES1371, ES1373 AudioPCI On Motherboard BL440ZX
-               8086 425a  ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
-               8086 4341  ES1371, ES1373 AudioPCI On Motherboard Cayman
-               8086 4343  ES1371, ES1373 AudioPCI On Motherboard Cape Cod
-               8086 4649  ES1371, ES1373 AudioPCI On Motherboard Fire Island
-               8086 464a  ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
-               8086 4d4f  ES1371, ES1373 AudioPCI On Motherboard Montreal
-               8086 4f43  ES1371, ES1373 AudioPCI On Motherboard OC440LX
-               8086 5243  ES1371, ES1373 AudioPCI On Motherboard RC440BX
-               8086 5352  ES1371, ES1373 AudioPCI On Motherboard SunRiver
-               8086 5643  ES1371, ES1373 AudioPCI On Motherboard Vancouver
-               8086 5753  ES1371, ES1373 AudioPCI On Motherboard WS440BX
-       5000  ES1370 [AudioPCI]
-       5880  5880 AudioPCI
-               1274 2000  Creative Sound Blaster AudioPCI128
-               1274 2003  Creative SoundBlaster AudioPCI 128
-               1274 5880  Creative Sound Blaster AudioPCI128
-               1274 8001  Sound Blaster 16PCI 4.1ch
-               1458 a000  5880 AudioPCI On Motherboard 6OXET
-               1462 6880  5880 AudioPCI On Motherboard MS-6188 1.00
-               270f 2001  5880 AudioPCI On Motherboard 6CTR
-               270f 2200  5880 AudioPCI On Motherboard 6WTX
-               270f 7040  5880 AudioPCI On Motherboard 6ATA4
-1275  Network Appliance Corporation
-1276  Switched Network Technologies, Inc.
-1277  Comstream
-1278  Transtech Parallel Systems Ltd.
-       0701  TPE3/TM3 PowerPC Node
-       0710  TPE5 PowerPC PCI board
-1279  Transmeta Corporation
-       0295  Northbridge
-       0395  LongRun Northbridge
-       0396  SDRAM controller
-       0397  BIOS scratchpad
-127a  Rockwell International
-       1002  HCF 56k Data/Fax Modem
-               1092 094c  SupraExpress 56i PRO [Diamond SUP2380]
-               122d 4002  HPG / MDP3858-U
-               122d 4005  MDP3858-E
-               122d 4007  MDP3858-A/-NZ
-               122d 4012  MDP3858-SA
-               122d 4017  MDP3858-W
-               122d 4018  MDP3858-W
-               127a 1002  Rockwell 56K D/F HCF Modem
-       1003  HCF 56k Data/Fax Modem
-               0e11 b0bc  229-DF Zephyr
-               0e11 b114  229-DF Cheetah
-               1033 802b  229-DF
-               13df 1003  PCI56RX Modem
-               13e0 0117  IBM
-               13e0 0147  IBM F-1156IV+/R3 Spain V.90 Modem
-               13e0 0197  IBM
-               13e0 01c7  IBM F-1156IV+/R3 WW V.90 Modem
-               13e0 01f7  IBM
-               1436 1003  IBM
-               1436 1103  IBM 5614PM3G V.90 Modem
-               1436 1602  Compaq 229-DF Ducati
-       1004  HCF 56k Data/Fax/Voice Modem
-               1048 1500  MicroLink 56k Modem
-               10cf 1059  Fujitsu 229-DFRT
-       1005  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-               1005 127a  AOpen FM56-P
-               1033 8029  229-DFSV
-               1033 8054  Modem
-               10cf 103c  Fujitsu
-               10cf 1055  Fujitsu 229-DFSV
-               10cf 1056  Fujitsu 229-DFSV
-               122d 4003  MDP3858SP-U
-               122d 4006  Packard Bell MDP3858V-E
-               122d 4008  MDP3858SP-A/SP-NZ
-               122d 4009  MDP3858SP-E
-               122d 4010  MDP3858V-U
-               122d 4011  MDP3858SP-SA
-               122d 4013  MDP3858V-A/V-NZ
-               122d 4015  MDP3858SP-W
-               122d 4016  MDP3858V-W
-               122d 4019  MDP3858V-SA
-               13df 1005  PCI56RVP Modem
-               13e0 0187  IBM
-               13e0 01a7  IBM
-               13e0 01b7  IBM DF-1156IV+/R3 Spain V.90 Modem
-               13e0 01d7  IBM DF-1156IV+/R3 WW V.90 Modem
-               1436 1005  IBM
-               1436 1105  IBM
-               1437 1105  IBM 5614PS3G V.90 Modem
-       1022  HCF 56k Modem
-               1436 1303  M3-5614PM3G V.90 Modem
-       1023  HCF 56k Data/Fax Modem
-               122d 4020  Packard Bell MDP3858-WE
-               122d 4023  MDP3858-UE
-               13e0 0247  IBM F-1156IV+/R6 Spain V.90 Modem
-               13e0 0297  IBM
-               13e0 02c7  IBM F-1156IV+/R6 WW V.90 Modem
-               1436 1203  IBM
-               1436 1303  IBM
-       1024  HCF 56k Data/Fax/Voice Modem
-       1025  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-               10cf 106a  Fujitsu 235-DFSV
-               122d 4021  Packard Bell MDP3858V-WE
-               122d 4022  MDP3858SP-WE
-               122d 4024  MDP3858V-UE
-               122d 4025  MDP3858SP-UE
-       1026  HCF 56k PCI Speakerphone Modem
-       1032  HCF 56k Modem
-       1033  HCF 56k Modem
-       1034  HCF 56k Modem
-       1035  HCF 56k PCI Speakerphone Modem
-       1036  HCF 56k Modem
-       1085  HCF 56k Volcano PCI Modem
-       2005  HCF 56k Data/Fax Modem
-               104d 8044  229-DFSV
-               104d 8045  229-DFSV
-               104d 8055  PBE/Aztech 235W-DFSV
-               104d 8056  235-DFSV
-               104d 805a  Modem
-               104d 805f  Modem
-               104d 8074  Modem
-       2013  HSF 56k Data/Fax Modem
-               1179 0001  Modem
-               1179 ff00  Modem
-       2014  HSF 56k Data/Fax/Voice Modem
-               10cf 1057  Fujitsu Citicorp III
-               122d 4050  MSP3880-U
-               122d 4055  MSP3880-W
-       2015  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-               10cf 1063  Fujitsu
-               10cf 1064  Fujitsu
-               1468 2015  Fujitsu
-       2016  HSF 56k Data/Fax/Voice/Spkp Modem
-               122d 4051  MSP3880V-W
-               122d 4052  MSP3880SP-W
-               122d 4054  MSP3880V-U
-               122d 4056  MSP3880SP-U
-               122d 4057  MSP3880SP-A
-       4311  Riptide HSF 56k PCI Modem
-               127a 4311  Ring Modular? Riptide HSF RT HP Dom
-               13e0 0210  HP-GVC
-       4320  Riptide PCI Audio Controller
-               1235 4320  Riptide PCI Audio Controller
-       4321  Riptide HCF 56k PCI Modem
-               1235 4321  Hewlett Packard DF
-               1235 4324  Hewlett Packard DF
-               13e0 0210  Hewlett Packard DF
-               144d 2321  Riptide
-       4322  Riptide PCI Game Controller
-               1235 4322  Riptide PCI Game Controller
-       8234  RapidFire 616X ATM155 Adapter
-               108d 0022  RapidFire 616X ATM155 Adapter
-               108d 0027  RapidFire 616X ATM155 Adapter
-127b  Pixera Corporation
-127c  Crosspoint Solutions, Inc.
-127d  Vela Research
-127e  Winnov, L.P.
-127f  Fujifilm
-1280  Photoscript Group Ltd.
-1281  Yokogawa Electric Corporation
-1282  Davicom Semiconductor, Inc.
-       9009  Ethernet 100/10 MBit
-       9100  21x4x DEC-Tulip compatible 10/100 Ethernet
-       9102  21x4x DEC-Tulip compatible 10/100 Ethernet
-       9132  Ethernet 100/10 MBit
-1283  Integrated Technology Express, Inc.
-       673a  IT8330G
-       8212  IT/ITE8212 Dual channel ATA RAID controller (PCI version seems to be IT8212, embedded seems to be ITE8212)
-               1283 0001  IT/ITE8212 Dual channel ATA RAID controller
-       8330  IT8330G
-       8872  IT8874F PCI Dual Serial Port Controller
-       8888  IT8888F PCI to ISA Bridge with SMB
-       8889  IT8889F PCI to ISA Bridge
-       e886  IT8330G
-1284  Sahara Networks, Inc.
-1285  Platform Technologies, Inc.
-       0100  AGOGO sound chip (aka ESS Maestro 1)
-1286  Mazet GmbH
-1287  M-Pact, Inc.
-       001e  LS220D DVD Decoder
-       001f  LS220C DVD Decoder
-1288  Timestep Corporation
-1289  AVC Technology, Inc.
-128a  Asante Technologies, Inc.
-128b  Transwitch Corporation
-128c  Retix Corporation
-128d  G2 Networks, Inc.
-       0021  ATM155 Adapter
-128e  Hoontech Corporation/Samho Multi Tech Ltd.
-       0008  ST128 WSS/SB
-       0009  ST128 SAM9407
-       000a  ST128 Game Port
-       000b  ST128 MPU Port
-       000c  ST128 Ctrl Port
-128f  Tateno Dennou, Inc.
-1290  Sord Computer Corporation
-1291  NCS Computer Italia
-1292  Tritech Microelectronics Inc
-1293  Media Reality Technology
-1294  Rhetorex, Inc.
-1295  Imagenation Corporation
-1296  Kofax Image Products
-1297  Holco Enterprise Co, Ltd/Shuttle Computer
-1298  Spellcaster Telecommunications Inc.
-1299  Knowledge Technology Lab.
-129a  VMetro, inc.
-       0615  PBT-615 PCI-X Bus Analyzer
-129b  Image Access
-129c  Jaycor
-129d  Compcore Multimedia, Inc.
-129e  Victor Company of Japan, Ltd.
-129f  OEC Medical Systems, Inc.
-12a0  Allen-Bradley Company
-12a1  Simpact Associates, Inc.
-12a2  Newgen Systems Corporation
-12a3  Lucent Technologies
-       8105  T8105 H100 Digital Switch
-12a4  NTT Electronics Technology Company
-12a5  Vision Dynamics Ltd.
-12a6  Scalable Networks, Inc.
-12a7  AMO GmbH
-12a8  News Datacom
-12a9  Xiotech Corporation
-12aa  SDL Communications, Inc.
-12ab  Yuan Yuan Enterprise Co., Ltd.
-       0002  AU8830 [Vortex2] Based Sound Card With A3D Support
-       3000  MPG-200C PCI DVD Decoder Card
-12ac  Measurex Corporation
-12ad  Multidata GmbH
-12ae  Alteon Networks Inc.
-       0001  AceNIC Gigabit Ethernet
-               1014 0104  Gigabit Ethernet-SX PCI Adapter
-               12ae 0001  Gigabit Ethernet-SX (Universal)
-               1410 0104  Gigabit Ethernet-SX PCI Adapter
-       0002  AceNIC Gigabit Ethernet (Copper)
-               10a9 8002  Acenic Gigabit Ethernet
-               12ae 0002  Gigabit Ethernet-T (3C986-T)
-       00fa  Farallon PN9100-T Gigabit Ethernet
-12af  TDK USA Corp
-12b0  Jorge Scientific Corp
-12b1  GammaLink
-12b2  General Signal Networks
-12b3  Inter-Face Co Ltd
-12b4  FutureTel Inc
-12b5  Granite Systems Inc.
-12b6  Natural Microsystems
-12b7  Cognex Modular Vision Systems Div. - Acumen Inc.
-12b8  Korg
-12b9  3Com Corp, Modem Division (formerly US Robotics)
-       1006  WinModem
-               12b9 005c  USR 56k Internal Voice WinModem (Model 3472)
-               12b9 005e  USR 56k Internal WinModem (Models 662975)
-               12b9 0062  USR 56k Internal Voice WinModem (Model 662978)
-               12b9 0068  USR 56k Internal Voice WinModem (Model 5690)
-               12b9 007a  USR 56k Internal Voice WinModem (Model 662974)
-               12b9 007f  USR 56k Internal WinModem (Models 5698, 5699)
-               12b9 0080  USR 56k Internal WinModem (Models 2975, 3528)
-               12b9 0081  USR 56k Internal Voice WinModem (Models 2974, 3529)
-               12b9 0091  USR 56k Internal Voice WinModem (Model 2978)
-       1007  USR 56k Internal WinModem
-               12b9 00a3  USR 56k Internal WinModem (Model 3595)
-       1008  56K FaxModem Model 5610
-               12b9 00a2  USR 56k Internal FAX Modem (Model 2977)
-               12b9 00aa  USR 56k Internal Voice Modem (Model 2976)
-               12b9 00ab  USR 56k Internal Voice Modem (Model 5609)
-               12b9 00ac  USR 56k Internal Voice Modem (Model 3298)
-               12b9 00ad  USR 56k Internal FAX Modem (Model 5610)
-12ba  BittWare, Inc.
-12bb  Nippon Unisoft Corporation
-12bc  Array Microsystems
-12bd  Computerm Corp.
-12be  Anchor Chips Inc.
-       3041  AN3041Q CO-MEM
-       3042  AN3042Q CO-MEM Lite
-               12be 3042  Anchor Chips Lite Evaluation Board
-12bf  Fujifilm Microdevices
-12c0  Infimed
-12c1  GMM Research Corp
-12c2  Mentec Limited
-12c3  Holtek Microelectronics Inc
-       0058  PCI NE2K Ethernet
-       5598  PCI NE2K Ethernet
-12c4  Connect Tech Inc
-       0001  Blue HEAT/PCI 8 (RS232/CL/RJ11)
-       0002  Blue HEAT/PCI 4 (RS232)
-       0003  Blue HEAT/PCI 2 (RS232)
-       0004  Blue HEAT/PCI 8 (UNIV, RS485)
-       0005  Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485)
-       0006  Blue HEAT/PCI 4 (OPTO, RS485)
-       0007  Blue HEAT/PCI 2+2 (RS232/485)
-       0008  Blue HEAT/PCI 2 (OPTO, Tx, RS485)
-       0009  Blue HEAT/PCI 2+6 (RS232/485)
-       000a  Blue HEAT/PCI 8 (Tx, RS485)
-       000b  Blue HEAT/PCI 4 (Tx, RS485)
-       000c  Blue HEAT/PCI 2 (20 MHz, RS485)
-       000d  Blue HEAT/PCI 2 PTM
-       0100  NT960/PCI
-       0201  cPCI Titan - 2 Port
-       0202  cPCI Titan - 4 Port
-       0300  CTI PCI UART 2 (RS232)
-       0301  CTI PCI UART 4 (RS232)
-       0302  CTI PCI UART 8 (RS232)
-       0310  CTI PCI UART 1+1 (RS232/485)
-       0311  CTI PCI UART 2+2 (RS232/485)
-       0312  CTI PCI UART 4+4 (RS232/485)
-       0320  CTI PCI UART 2
-       0321  CTI PCI UART 4
-       0322  CTI PCI UART 8
-       0330  CTI PCI UART 2 (RS485)
-       0331  CTI PCI UART 4 (RS485)
-       0332  CTI PCI UART 8 (RS485)
-12c5  Picture Elements Incorporated
-       007e  Imaging/Scanning Subsystem Engine
-       007f  Imaging/Scanning Subsystem Engine
-       0081  PCIVST [Grayscale Thresholding Engine]
-       0085  Video Simulator/Sender
-       0086  THR2 Multi-scale Thresholder
-12c6  Mitani Corporation
-12c7  Dialogic Corp
-12c8  G Force Co, Ltd
-12c9  Gigi Operations
-12ca  Integrated Computing Engines
-12cb  Antex Electronics Corporation
-12cc  Pluto Technologies International
-12cd  Aims Lab
-12ce  Netspeed Inc.
-12cf  Prophet Systems, Inc.
-12d0  GDE Systems, Inc.
-12d1  PSITech
-12d2  NVidia / SGS Thomson (Joint Venture)
-       0008  NV1
-       0009  DAC64
-       0018  Riva128
-               1048 0c10  VICTORY Erazor
-               107b 8030  STB Velocity 128
-               1092 0350  Viper V330
-               1092 1092  Viper V330
-               10b4 1b1b  STB Velocity 128
-               10b4 1b1d  STB Velocity 128
-               10b4 1b1e  STB Velocity 128, PAL TV-Out
-               10b4 1b20  STB Velocity 128 Sapphire
-               10b4 1b21  STB Velocity 128
-               10b4 1b22  STB Velocity 128 AGP, NTSC TV-Out
-               10b4 1b23  STB Velocity 128 AGP, PAL TV-Out
-               10b4 1b27  STB Velocity 128 DVD
-               10b4 1b88  MVP Pro 128
-               10b4 222a  STB Velocity 128 AGP
-               10b4 2230  STB Velocity 128
-               10b4 2232  STB Velocity 128
-               10b4 2235  STB Velocity 128 AGP
-               2a15 54a3  3DVision-SAGP / 3DexPlorer 3000
-       0019  Riva128ZX
-       0020  TNT
-       0028  TNT2
-       0029  UTNT2
-       002c  VTNT2
-       00a0  ITNT2
-12d3  Vingmed Sound A/S
-12d4  Ulticom (Formerly DGM&S)
-       0200  T1 Card
-12d5  Equator Technologies Inc
-       0003  BSP16
-       1000  BSP15
-12d6  Analogic Corp
-12d7  Biotronic SRL
-12d8  Pericom Semiconductor
-12d9  Aculab PLC
-       0002  PCI Prosody
-       0004  cPCI Prosody
-       0005  Aculab E1/T1 PCI card
-12da  True Time Inc.
-12db  Annapolis Micro Systems, Inc
-12dc  Symicron Computer Communication Ltd.
-12dd  Management Graphics
-12de  Rainbow Technologies
-       0200  CryptoSwift CS200
-12df  SBS Technologies Inc
-12e0  Chase Research
-       0010  ST16C654 Quad UART
-       0020  ST16C654 Quad UART
-       0030  ST16C654 Quad UART
-12e1  Nintendo Co, Ltd
-12e2  Datum Inc. Bancomm-Timing Division
-12e3  Imation Corp - Medical Imaging Systems
-12e4  Brooktrout Technology Inc
-12e5  Apex Semiconductor Inc
-12e6  Cirel Systems
-12e7  Sunsgroup Corporation
-12e8  Crisc Corp
-12e9  GE Spacenet
-12ea  Zuken
-12eb  Aureal Semiconductor
-       0001  Vortex 1
-               104d 8036  AU8820 Vortex Digital Audio Processor
-               1092 2000  Sonic Impact A3D
-               1092 2100  Sonic Impact A3D
-               1092 2110  Sonic Impact A3D
-               1092 2200  Sonic Impact A3D
-               122d 1002  AU8820 Vortex Digital Audio Processor
-               12eb 0001  AU8820 Vortex Digital Audio Processor
-               5053 3355  Montego
-       0002  Vortex 2
-               104d 8049  AU8830 Vortex 3D Digital Audio Processor
-               104d 807b  AU8830 Vortex 3D Digital Audio Processor
-               1092 3000  Monster Sound II
-               1092 3001  Monster Sound II
-               1092 3002  Monster Sound II
-               1092 3003  Monster Sound II
-               1092 3004  Monster Sound II
-               12eb 0001  AU8830 Vortex 3D Digital Audio Processor
-               12eb 0002  AU8830 Vortex 3D Digital Audio Processor
-               12eb 0088  AU8830 Vortex 3D Digital Audio Processor
-               144d 3510  AU8830 Vortex 3D Digital Audio Processor
-               5053 3356  Montego II
-       0003  AU8810 Vortex Digital Audio Processor
-               104d 8049  AU8810 Vortex Digital Audio Processor
-               104d 8077  AU8810 Vortex Digital Audio Processor
-               109f 1000  AU8810 Vortex Digital Audio Processor
-               12eb 0003  AU8810 Vortex Digital Audio Processor
-               1462 6780  AU8810 Vortex Digital Audio Processor
-               14a4 2073  AU8810 Vortex Digital Audio Processor
-               14a4 2091  AU8810 Vortex Digital Audio Processor
-               14a4 2104  AU8810 Vortex Digital Audio Processor
-               14a4 2106  AU8810 Vortex Digital Audio Processor
-       8803  Vortex 56k Software Modem
-               12eb 8803  Vortex 56k Software Modem
-12ec  3A International, Inc.
-12ed  Optivision Inc.
-12ee  Orange Micro
-12ef  Vienna Systems
-12f0  Pentek
-12f1  Sorenson Vision Inc
-12f2  Gammagraphx, Inc.
-12f3  Radstone Technology
-12f4  Megatel
-12f5  Forks
-12f6  Dawson France
-12f7  Cognex
-12f8  Electronic Design GmbH
-       0002  VideoMaker
-12f9  Four Fold Ltd
-12fb  Spectrum Signal Processing
-12fc  Capital Equipment Corp
-12fd  I2S
-12fe  ESD Electronic System Design GmbH
-12ff  Lexicon
-1300  Harman International Industries Inc
-1302  Computer Sciences Corp
-1303  Innovative Integration
-1304  Juniper Networks
-1305  Netphone, Inc
-1306  Duet Technologies
-# Formerly ComputerBoards
-1307  Measurement Computing
-       0001  PCI-DAS1602/16
-       000b  PCI-DIO48H
-       000c  PCI-PDISO8
-       000d  PCI-PDISO16
-       000f  PCI-DAS1200
-       0010  PCI-DAS1602/12
-       0014  PCI-DIO24H
-       0015  PCI-DIO24H/CTR3
-       0016  PCI-DIO48H/CTR15
-       0017  PCI-DIO96H
-       0018  PCI-CTR05
-       0019  PCI-DAS1200/JR
-       001a  PCI-DAS1001
-       001b  PCI-DAS1002
-       001c  PCI-DAS1602JR/16
-       001d  PCI-DAS6402/16
-       001e  PCI-DAS6402/12
-       001f  PCI-DAS16/M1
-       0020  PCI-DDA02/12
-       0021  PCI-DDA04/12
-       0022  PCI-DDA08/12
-       0023  PCI-DDA02/16
-       0024  PCI-DDA04/16
-       0025  PCI-DDA08/16
-       0026  PCI-DAC04/12-HS
-       0027  PCI-DAC04/16-HS
-       0028  PCI-DIO24
-       0029  PCI-DAS08
-       002c  PCI-INT32
-       0033  PCI-DUAL-AC5
-       0034  PCI-DAS-TC
-       0035  PCI-DAS64/M1/16
-       0036  PCI-DAS64/M2/16
-       0037  PCI-DAS64/M3/16
-       004c  PCI-DAS1000
-       004d  PCI-QUAD04
-       0052  PCI-DAS4020/12
-       005e  PCI-DAS6025
-1308  Jato Technologies Inc.
-       0001  NetCelerator Adapter
-               1308 0001  NetCelerator Adapter
-1309  AB Semiconductor Ltd
-130a  Mitsubishi Electric Microcomputer
-130b  Colorgraphic Communications Corp
-130c  Ambex Technologies, Inc
-130d  Accelerix Inc
-130e  Yamatake-Honeywell Co. Ltd
-130f  Advanet Inc
-1310  Gespac
-1311  Videoserver, Inc
-1312  Acuity Imaging, Inc
-1313  Yaskawa Electric Co.
-1316  Teradyne Inc
-1317  Linksys
-       0981  21x4x DEC-Tulip compatible 10/100 Ethernet
-       0985  NC100 Network Everywhere Fast Ethernet 10/100
-       1985  21x4x DEC-Tulip compatible 10/100 Ethernet
-       2850  HSP MicroModem 56
-       8201  ADMtek ADM8211 802.11b Wireless Interface
-               10b8 2635  SMC2635W 802.11b (11Mbps) wireless lan pcmcia (cardbus) card
-               1317 8201  SMC2635W 802.11b (11mbps) wireless lan pcmcia (cardbus) card
-       8211  ADMtek ADM8211 802.11b Wireless Interface
-       9511  21x4x DEC-Tulip compatible 10/100 Ethernet
-1318  Packet Engines Inc.
-       0911  GNIC-II PCI Gigabit Ethernet [Hamachi]
-1319  Fortemedia, Inc
-       0801  Xwave QS3000A [FM801]
-       0802  Xwave QS3000A [FM801 game port]
-       1000  FM801 PCI Audio
-       1001  FM801 PCI Joystick
-131a  Finisar Corp.
-131c  Nippon Electro-Sensory Devices Corp
-131d  Sysmic, Inc.
-131e  Xinex Networks Inc
-131f  Siig Inc
-       1000  CyberSerial (1-port) 16550
-       1001  CyberSerial (1-port) 16650
-       1002  CyberSerial (1-port) 16850
-       1010  Duet 1S(16550)+1P
-       1011  Duet 1S(16650)+1P
-       1012  Duet 1S(16850)+1P
-       1020  CyberParallel (1-port)
-       1021  CyberParallel (2-port)
-       1030  CyberSerial (2-port) 16550
-       1031  CyberSerial (2-port) 16650
-       1032  CyberSerial (2-port) 16850
-       1034  Trio 2S(16550)+1P
-       1035  Trio 2S(16650)+1P
-       1036  Trio 2S(16850)+1P
-       1050  CyberSerial (4-port) 16550
-       1051  CyberSerial (4-port) 16650
-       1052  CyberSerial (4-port) 16850
-       2000  CyberSerial (1-port) 16550
-       2001  CyberSerial (1-port) 16650
-       2002  CyberSerial (1-port) 16850
-       2010  Duet 1S(16550)+1P
-       2011  Duet 1S(16650)+1P
-       2012  Duet 1S(16850)+1P
-       2020  CyberParallel (1-port)
-       2021  CyberParallel (2-port)
-       2030  CyberSerial (2-port) 16550
-               131f 2030  PCI Serial Card
-       2031  CyberSerial (2-port) 16650
-       2032  CyberSerial (2-port) 16850
-       2040  Trio 1S(16550)+2P
-       2041  Trio 1S(16650)+2P
-       2042  Trio 1S(16850)+2P
-       2050  CyberSerial (4-port) 16550
-       2051  CyberSerial (4-port) 16650
-       2052  CyberSerial (4-port) 16850
-       2060  Trio 2S(16550)+1P
-       2061  Trio 2S(16650)+1P
-       2062  Trio 2S(16850)+1P
-       2081  CyberSerial (8-port) ST16654
-1320  Crypto AG
-1321  Arcobel Graphics BV
-1322  MTT Co., Ltd
-1323  Dome Inc
-1324  Sphere Communications
-1325  Salix Technologies, Inc
-1326  Seachange international
-1327  Voss scientific
-1328  quadrant international
-1329  Productivity Enhancement
-132a  Microcom Inc.
-132b  Broadband Technologies
-132c  Micrel Inc
-132d  Integrated Silicon Solution, Inc.
-1330  MMC Networks
-1331  Radisys Corp.
-       0030  ENP-2611
-       8200  82600 Host Bridge
-       8201  82600 IDE
-       8202  82600 USB
-       8210  82600 PCI Bridge
-1332  Micro Memory
-       5415  MM-5415CN PCI Memory Module with Battery Backup
-       5425  MM-5425CN PCI 64/66 Memory Module with Battery Backup
-1334  Redcreek Communications, Inc
-1335  Videomail, Inc
-1337  Third Planet Publishing
-1338  BT Electronics
-133a  Vtel Corp
-133b  Softcom Microsystems
-133c  Holontech Corp
-133d  SS Technologies
-133e  Virtual Computer Corp
-133f  SCM Microsystems
-1340  Atalla Corp
-1341  Kyoto Microcomputer Co
-1342  Promax Systems Inc
-1343  Phylon Communications Inc
-1344  Crucial Technology
-1345  Arescom Inc
-1347  Odetics
-1349  Sumitomo Electric Industries, Ltd.
-134a  DTC Technology Corp.
-       0001  Domex 536
-       0002  Domex DMX3194UP SCSI Adapter
-134b  ARK Research Corp.
-134c  Chori Joho System Co. Ltd
-134d  PCTel Inc
-       2189  HSP56 MicroModem
-       2486  2304WT V.92 MDC Modem
-       7890  HSP MicroModem 56
-               134d 0001  PCT789 adapter
-       7891  HSP MicroModem 56
-               134d 0001  HSP MicroModem 56
-       7892  HSP MicroModem 56
-       7893  HSP MicroModem 56
-       7894  HSP MicroModem 56
-       7895  HSP MicroModem 56
-       7896  HSP MicroModem 56
-       7897  HSP MicroModem 56
-134e  CSTI
-134f  Algo System Co Ltd
-1350  Systec Co. Ltd
-1351  Sonix Inc
-1353  Thales Idatys
-       0002  Proserver
-       0003  PCI-FUT
-       0004  PCI-S0
-       0005  PCI-FUT-S0
-1354  Dwave System Inc
-1355  Kratos Analytical Ltd
-1356  The Logical Co
-1359  Prisa Networks
-135a  Brain Boxes
-135b  Giganet Inc
-135c  Quatech Inc
-       0010  QSC-100
-       0020  DSC-100
-       0030  DSC-200/300
-       0040  QSC-200/300
-       0050  ESC-100D
-       0060  ESC-100M
-       00f0  MPAC-100 Syncronous Serial Card (Zilog 85230)
-       0170  QSCLP-100
-       0180  DSCLP-100
-       0190  SSCLP-100
-       01a0  QSCLP-200/300
-       01b0  DSCLP-200/300
-       01c0  SSCLP-200/300
-135d  ABB Network Partner AB
-135e  Sealevel Systems Inc
-       5101  Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32)
-       7101  Single Port RS-232/422/485/530
-       7201  Dual Port RS-232/422/485 Interface
-       7202  Dual Port RS-232 Interface
-       7401  Four Port RS-232 Interface
-       7402  Four Port RS-422/485 Interface
-       7801  Eight Port RS-232 Interface
-       7804  Eight Port RS-232/422/485 Interface
-       8001  8001 Digital I/O Adapter
-135f  I-Data International A-S
-1360  Meinberg Funkuhren
-       0101  PCI32 DCF77 Radio Clock
-       0102  PCI509 DCF77 Radio Clock
-       0103  PCI510 DCF77 Radio Clock
-       0201  GPS167PCI GPS Receiver
-       0202  GPS168PCI GPS Receiver
-       0203  GPS169PCI GPS Receiver
-       0301  TCR510PCI IRIG Receiver
-1361  Soliton Systems K.K.
-1362  Fujifacom Corporation
-1363  Phoenix Technology Ltd
-1364  ATM Communications Inc
-1365  Hypercope GmbH
-1366  Teijin Seiki Co. Ltd
-1367  Hitachi Zosen Corporation
-1368  Skyware Corporation
-1369  Digigram
-136a  High Soft Tech
-136b  Kawasaki Steel Corporation
-       ff01  KL5A72002 Motion JPEG
-136c  Adtek System Science Co Ltd
-136d  Gigalabs Inc
-136f  Applied Magic Inc
-1370  ATL Products
-1371  CNet Technology Inc
-       434e  GigaCard Network Adapter
-               1371 434e  N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
-1373  Silicon Vision Inc
-1374  Silicom Ltd
-1375  Argosystems Inc
-1376  LMC
-1377  Electronic Equipment Production & Distribution GmbH
-1378  Telemann Co. Ltd
-1379  Asahi Kasei Microsystems Co Ltd
-137a  Mark of the Unicorn Inc
-       0001  PCI-324 Audiowire Interface
-137b  PPT Vision
-137c  Iwatsu Electric Co Ltd
-137d  Dynachip Corporation
-137e  Patriot Scientific Corporation
-137f  Japan Satellite Systems Inc
-1380  Sanritz Automation Co Ltd
-1381  Brains Co. Ltd
-1382  Marian - Electronic & Software
-       0001  ARC88 audio recording card
-       2008  Prodif 96 Pro sound system
-       2088  Marc 8 Midi sound system
-       20c8  Marc A sound system
-       4008  Marc 2 sound system
-       4010  Marc 2 Pro sound system
-       4048  Marc 4 MIDI sound system
-       4088  Marc 4 Digi sound system
-       4248  Marc X sound system
-1383  Controlnet Inc
-1384  Reality Simulation Systems Inc
-1385  Netgear
-# Note: This lists as Atheros Communications, Inc. AR5212 802.11abg NIC because of Madwifi
-       0013  WG311T
-       311a  GA511 Gigabit Ethernet
-       4100  802.11b Wireless Adapter (MA301)
-       4105  MA311 802.11b wireless adapter
-       4400  WAG511 802.11a/b/g Dual Band Wireless PC Card
-       4600  WAG511 802.11a/b/g Dual Band Wireless PC Card
-       4601  WAG511 802.11a/b/g Dual Band Wireless PC Card
-       4610  WAG511 802.11a/b/g Dual Band Wireless PC Card
-       4a00  WAG311 802.11a/g Wireless PCI Adapter
-       4c00  WG311v2 54 Mbps Wireless PCI Adapter
-       620a  GA620 Gigabit Ethernet
-       622a  GA622
-       630a  GA630 Gigabit Ethernet
-       f004  FA310TX
-1386  Video Domain Technologies
-1387  Systran Corp
-1388  Hitachi Information Technology Co Ltd
-1389  Applicom International
-       0001  PCI1500PFB [Intelligent fieldbus adaptor]
-138a  Fusion Micromedia Corp
-138b  Tokimec Inc
-138c  Silicon Reality
-138d  Future Techno Designs pte Ltd
-138e  Basler GmbH
-138f  Patapsco Designs Inc
-1390  Concept Development Inc
-1391  Development Concepts Inc
-1392  Medialight Inc
-1393  Moxa Technologies Co Ltd
-       1040  Smartio C104H/PCI
-       1141  Industrio CP-114
-       1680  Smartio C168H/PCI
-       2040  Intellio CP-204J
-       2180  Intellio C218 Turbo PCI
-       3200  Intellio C320 Turbo PCI
-1394  Level One Communications
-       0001  LXT1001 Gigabit Ethernet
-               1394 0001  NetCelerator Adapter
-1395  Ambicom Inc
-1396  Cipher Systems Inc
-1397  Cologne Chip Designs GmbH
-       2bd0  ISDN network controller [HFC-PCI]
-               1397 2bd0  ISDN Board
-               e4bf 1000  CI1-1-Harp
-1398  Clarion co. Ltd
-1399  Rios systems Co Ltd
-139a  Alacritech Inc
-       0001  Quad Port 10/100 Server Accelerator
-       0003  Single Port 10/100 Server Accelerator
-       0005  Single Port Gigabit Server Accelerator
-139b  Mediasonic Multimedia Systems Ltd
-139c  Quantum 3d Inc
-139d  EPL limited
-139e  Media4
-139f  Aethra s.r.l.
-13a0  Crystal Group Inc
-13a1  Kawasaki Heavy Industries Ltd
-13a2  Ositech Communications Inc
-13a3  Hifn Inc.
-       0005  7751 Security Processor
-       0006  6500 Public Key Processor
-       0007  7811 Security Processor
-       0012  7951 Security Processor
-       0014  78XX Security Processor
-       0016  8065 Security Processor
-       0017  8165 Security Processor
-       0018  8154 Security Processor
-       001d  7956 Security Processor
-       0020  7955 Security Processor
-13a4  Rascom Inc
-13a5  Audio Digital Imaging Inc
-13a6  Videonics Inc
-13a7  Teles AG
-13a8  Exar Corp.
-       0154  XR17C154 Quad UART
-       0158  XR17C158 Octal UART
-13a9  Siemens Medical Systems, Ultrasound Group
-13aa  Broadband Networks Inc
-13ab  Arcom Control Systems Ltd
-13ac  Motion Media Technology Ltd
-13ad  Nexus Inc
-13ae  ALD Technology Ltd
-13af  T.Sqware
-13b0  Maxspeed Corp
-13b1  Tamura corporation
-13b2  Techno Chips Co. Ltd
-13b3  Lanart Corporation
-13b4  Wellbean Co Inc
-13b5  ARM
-13b6  Dlog GmbH
-13b7  Logic Devices Inc
-13b8  Nokia Telecommunications oy
-13b9  Elecom Co Ltd
-13ba  Oxford Instruments
-13bb  Sanyo Technosound Co Ltd
-13bc  Bitran Corporation
-13bd  Sharp corporation
-13be  Miroku Jyoho Service Co. Ltd
-13bf  Sharewave Inc
-13c0  Microgate Corporation
-       0010  SyncLink Adapter v1
-       0020  SyncLink SCC Adapter
-       0030  SyncLink Multiport Adapter
-       0210  SyncLink Adapter v2
-13c1  3ware Inc
-       1000  3ware Inc 3ware 5xxx/6xxx-series PATA-RAID
-       1001  3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
-               13c1 1001  3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
-       1002  3ware Inc 3ware 9xxx-series SATA-RAID
-13c2  Technotrend Systemtechnik GmbH
-13c3  Janz Computer AG
-13c4  Phase Metrics
-13c5  Alphi Technology Corp
-13c6  Condor Engineering Inc
-       0520  CEI-520 A429 Card
-       0620  CEI-620 A429 Card
-       0820  CEI-820 A429 Card
-13c7  Blue Chip Technology Ltd
-13c8  Apptech Inc
-13c9  Eaton Corporation
-13ca  Iomega Corporation
-13cb  Yano Electric Co Ltd
-13cc  Metheus Corporation
-13cd  Compatible Systems Corporation
-13ce  Cocom A/S
-13cf  Studio Audio & Video Ltd
-13d0  Techsan Electronics Co Ltd
-       2103  B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card
-       2200  B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card
-13d1  Abocom Systems Inc
-       ab02  ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
-       ab03  21x4x DEC-Tulip compatible 10/100 Ethernet
-       ab06  RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
-       ab08  21x4x DEC-Tulip compatible 10/100 Ethernet
-13d2  Shark Multimedia Inc
-13d3  IMC Networks
-13d4  Graphics Microsystems Inc
-13d5  Media 100 Inc
-13d6  K.I. Technology Co Ltd
-13d7  Toshiba Engineering Corporation
-13d8  Phobos corporation
-13d9  Apex PC Solutions Inc
-13da  Intresource Systems pte Ltd
-13db  Janich & Klass Computertechnik GmbH
-13dc  Netboost Corporation
-13dd  Multimedia Bundle Inc
-13de  ABB Robotics Products AB
-13df  E-Tech Inc
-       0001  PCI56RVP Modem
-               13df 0001  PCI56RVP Modem
-13e0  GVC Corporation
-13e1  Silicom Multimedia Systems Inc
-13e2  Dynamics Research Corporation
-13e3  Nest Inc
-13e4  Calculex Inc
-13e5  Telesoft Design Ltd
-13e6  Argosy research Inc
-13e7  NAC Incorporated
-13e8  Chip Express Corporation
-13e9  Intraserver Technology Inc
-13ea  Dallas Semiconductor
-13eb  Hauppauge Computer Works Inc
-13ec  Zydacron Inc
-13ed  Raytheion E-Systems
-13ee  Hayes Microcomputer Products Inc
-13ef  Coppercom Inc
-13f0  Sundance Technology Inc
-       0201  ST201 Sundance Ethernet
-13f1  Oce' - Technologies B.V.
-13f2  Ford Microelectronics Inc
-13f3  Mcdata Corporation
-13f4  Troika Networks, Inc.
-       1401  Zentai Fibre Channel Adapter
-13f5  Kansai Electric Co. Ltd
-13f6  C-Media Electronics Inc
-       0011  CMI8738
-       0100  CM8338A
-               13f6 ffff  CMI8338/C3DX PCI Audio Device
-       0101  CM8338B
-               13f6 0101  CMI8338-031 PCI Audio Device
-       0111  CM8738
-               1019 0970  P6STP-FL motherboard
-               1043 8035  CUSI-FX motherboard
-               1043 8077  CMI8738 6-channel audio controller
-               1043 80e2  CMI8738 6ch-MX
-               13f6 0111  CMI8738/C3DX PCI Audio Device
-               1681 a000  Gamesurround MUSE XL
-       0211  CM8738
-13f7  Wildfire Communications
-13f8  Ad Lib Multimedia Inc
-13f9  NTT Advanced Technology Corp.
-13fa  Pentland Systems Ltd
-13fb  Aydin Corp
-13fc  Computer Peripherals International
-13fd  Micro Science Inc
-13fe  Advantech Co. Ltd
-       1240  PCI-1240 4-channel stepper motor controller card w.  Nova Electronics MCX314
-       1600  PCI-1612 4-port RS-232/422/485 PCI Communication Card
-       1752  PCI-1752
-       1754  PCI-1754
-       1756  PCI-1756
-13ff  Silicon Spice Inc
-1400  Artx Inc
-       1401  9432 TX
-1401  CR-Systems A/S
-1402  Meilhaus Electronic GmbH
-1403  Ascor Inc
-1404  Fundamental Software Inc
-1405  Excalibur Systems Inc
-1406  Oce' Printing Systems GmbH
-1407  Lava Computer mfg Inc
-       0100  Lava Dual Serial
-       0101  Lava Quatro A
-       0102  Lava Quatro B
-       0110  Lava DSerial-PCI Port A
-       0111  Lava DSerial-PCI Port B
-       0120  Quattro-PCI A
-       0121  Quattro-PCI B
-       0180  Lava Octo A
-       0181  Lava Octo B
-       0200  Lava Port Plus
-       0201  Lava Quad A
-       0202  Lava Quad B
-       0220  Lava Quattro PCI Ports A/B
-       0221  Lava Quattro PCI Ports C/D
-       0500  Lava Single Serial
-       0600  Lava Port 650
-       8000  Lava Parallel
-       8001  Dual parallel port controller A
-       8002  Lava Dual Parallel port A
-       8003  Lava Dual Parallel port B
-       8800  BOCA Research IOPPAR
-1408  Aloka Co. Ltd
-1409  Timedia Technology Co Ltd
-       7168  PCI2S550 (Dual 16550 UART)
-140a  DSP Research Inc
-140b  Ramix Inc
-140c  Elmic Systems Inc
-140d  Matsushita Electric Works Ltd
-140e  Goepel Electronic GmbH
-140f  Salient Systems Corp
-1410  Midas lab Inc
-1411  Ikos Systems Inc
-# formerly IC Ensemble Inc.
-1412  VIA Technologies Inc.
-       1712  ICE1712 [Envy24] PCI Multi-Channel I/O Controller
-               1412 1712  Hoontech ST Audio DSP 24
-               1412 d630  M-Audio Delta 1010
-               1412 d631  M-Audio Delta DiO
-               1412 d632  M-Audio Delta 66
-               1412 d633  M-Audio Delta 44
-               1412 d634  M-Audio Delta Audiophile
-               1412 d635  M-Audio Delta TDIF
-               1412 d637  M-Audio Delta RBUS
-               1412 d638  M-Audio Delta 410
-               1412 d63b  M-Audio Delta 1010LT
-               1412 d63c  Digigram VX442
-               1416 1712  Hoontech ST Audio DSP 24 Media 7.1
-               153b 1115  EWS88 MT
-               153b 1125  EWS88 MT (Master)
-               153b 112b  EWS88 D
-               153b 112c  EWS88 D (Master)
-               153b 1130  EWX 24/96
-               153b 1138  DMX 6fire 24/96
-               153b 1151  PHASE88
-               16ce 1040  Edirol DA-2496
-       1724  VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
-               1412 1724  AMP Ltd AUDIO2000
-               1412 3630  M-Audio Revolution 7.1
-               153b 1145  Aureon 7.1 Space
-               153b 1147  Aureon 5.1 Sky
-               153b 1153  Aureon 7.1 Universe
-               270f f641  ZNF3-150
-               270f f645  ZNF3-250
-1413  Addonics
-1414  Microsoft Corporation
-1415  Oxford Semiconductor Ltd
-       8403  VScom 011H-EP1 1 port parallel adaptor
-       9501  OX16PCI954 (Quad 16950 UART) function 0
-               131f 2050  CyberPro (4-port)
-# Model IO1085, Part No: JJ-P46012
-               131f 2051  CyberSerial 4S Plus
-               15ed 2000  MCCR Serial p0-3 of 8
-               15ed 2001  MCCR Serial p0-3 of 16
-       950a  EXSYS EX-41092 Dual 16950 Serial adapter
-       950b  OXCB950 Cardbus 16950 UART
-       9510  OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
-       9511  OX16PCI954 (Quad 16950 UART) function 1
-               15ed 2000  MCCR Serial p4-7 of 8
-               15ed 2001  MCCR Serial p4-15 of 16
-       9521  OX16PCI952 (Dual 16950 UART)
-1416  Multiwave Innovation pte Ltd
-1417  Convergenet Technologies Inc
-1418  Kyushu electronics systems Inc
-1419  Excel Switching Corp
-141a  Apache Micro Peripherals Inc
-141b  Zoom Telephonics Inc
-141d  Digitan Systems Inc
-141e  Fanuc Ltd
-141f  Visiontech Ltd
-1420  Psion Dacom plc
-       8002  Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part)
-       8003  Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part)
-1421  Ads Technologies Inc
-1422  Ygrec Systems Co Ltd
-1423  Custom Technology Corp.
-1424  Videoserver Connections
-1425  Chelsio Communications Inc
-1426  Storage Technology Corp.
-1427  Better On-Line Solutions
-1428  Edec Co Ltd
-1429  Unex Technology Corp.
-142a  Kingmax Technology Inc
-142b  Radiolan
-142c  Minton Optic Industry Co Ltd
-142d  Pix stream Inc
-142e  Vitec Multimedia
-       4020  VM2-2 [Video Maker 2] MPEG1/2 Encoder
-142f  Radicom Research Inc
-1430  ITT Aerospace/Communications Division
-1431  Gilat Satellite Networks
-1432  Edimax Computer Co.
-       9130  RTL81xx Fast Ethernet
-1433  Eltec Elektronik GmbH
-1435  Real Time Devices US Inc.
-1436  CIS Technology Inc
-1437  Nissin Inc Co
-1438  Atmel-dream
-1439  Outsource Engineering & Mfg. Inc
-143a  Stargate Solutions Inc
-143b  Canon Research Center, America
-143c  Amlogic Inc
-143d  Tamarack Microelectronics Inc
-143e  Jones Futurex Inc
-143f  Lightwell Co Ltd - Zax Division
-1440  ALGOL Corp.
-1441  AGIE Ltd
-1442  Phoenix Contact GmbH & Co.
-1443  Unibrain S.A.
-1444  TRW
-1445  Logical DO Ltd
-1446  Graphin Co Ltd
-1447  AIM GmBH
-1448  Alesis Studio Electronics
-1449  TUT Systems Inc
-144a  Adlink Technology
-       7296  PCI-7296
-       7432  PCI-7432
-       7433  PCI-7433
-       7434  PCI-7434
-       7841  PCI-7841
-       8133  PCI-8133
-       8164  PCI-8164
-       8554  PCI-8554
-       9111  PCI-9111
-       9113  PCI-9113
-       9114  PCI-9114
-144b  Loronix Information Systems Inc
-144c  Catalina Research Inc
-144d  Samsung Electronics Co Ltd
-144e  OLITEC
-144f  Askey Computer Corp.
-1450  Octave Communications Ind.
-1451  SP3D Chip Design GmBH
-1453  MYCOM Inc
-1454  Altiga Networks
-1455  Logic Plus Plus Inc
-1456  Advanced Hardware Architectures
-1457  Nuera Communications Inc
-1458  Giga-byte Technology
-       0c11  K8NS Pro Mainboard
-1459  DOOIN Electronics
-145a  Escalate Networks Inc
-145b  PRAIM SRL
-145c  Cryptek
-145d  Gallant Computer Inc
-145e  Aashima Technology B.V.
-145f  Baldor Electric Company
-       0001  NextMove PCI
-1460  DYNARC INC
-1461  Avermedia Technologies Inc
-1462  Micro-Star International Co., Ltd.
-# MSI CB54G Wireless PC Card that seems to use the Broadcom 4306 Chipset
-       6819  Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G]
-       6825  PCI Card wireless 11g [PC54G]
-       8725  NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter
-# MSI G4Ti4800, 128MB DDR SDRAM, TV-Out, DVI-I
-       9000  NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter
-       9110  GeFORCE FX5200
-       9119  NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter
-       9591  nVidia Corporation NV36 [GeForce FX 5700LE]
-1463  Fast Corporation
-1464  Interactive Circuits & Systems Ltd
-1465  GN NETTEST Telecom DIV.
-1466  Designpro Inc.
-1467  DIGICOM SPA
-1468  AMBIT Microsystem Corp.
-1469  Cleveland Motion Controls
-146a  IFR
-146b  Parascan Technologies Ltd
-146c  Ruby Tech Corp.
-       1430  FE-1430TX Fast Ethernet PCI Adapter
-146d  Tachyon, INC.
-146e  Williams Electronics Games, Inc.
-146f  Multi Dimensional Consulting Inc
-1470  Bay Networks
-1471  Integrated Telecom Express Inc
-1472  DAIKIN Industries, Ltd
-1473  ZAPEX Technologies Inc
-1474  Doug Carson & Associates
-1475  PICAZO Communications
-1476  MORTARA Instrument Inc
-1477  Net Insight
-1478  DIATREND Corporation
-1479  TORAY Industries Inc
-147a  FORMOSA Industrial Computing
-147b  ABIT Computer Corp.
-147c  AWARE, Inc.
-147d  Interworks Computer Products
-147e  Matsushita Graphic Communication Systems, Inc.
-147f  NIHON UNISYS, Ltd.
-1480  SCII Telecom
-1481  BIOPAC Systems Inc
-1482  ISYTEC - Integrierte Systemtechnik GmBH
-1483  LABWAY Corporation
-1484  Logic Corporation
-1485  ERMA - Electronic GmBH
-1486  L3 Communications Telemetry & Instrumentation
-1487  MARQUETTE Medical Systems
-1488  KONTRON Electronik GmBH
-1489  KYE Systems Corporation
-148a  OPTO
-148b  INNOMEDIALOGIC Inc.
-148c  C.P. Technology Co. Ltd
-148d  DIGICOM Systems, Inc.
-       1003  HCF 56k Data/Fax Modem
-148e  OSI Plus Corporation
-148f  Plant Equipment, Inc.
-1490  Stone Microsystems PTY Ltd.
-1491  ZEAL Corporation
-1492  Time Logic Corporation
-1493  MAKER Communications
-1494  WINTOP Technology, Inc.
-1495  TOKAI Communications Industry Co. Ltd
-1496  JOYTECH Computer Co., Ltd.
-1497  SMA Regelsysteme GmBH
-1498  TEWS Datentechnik GmBH
-       30c8  TPCI200
-1499  EMTEC CO., Ltd
-149a  ANDOR Technology Ltd
-149b  SEIKO Instruments Inc
-149c  OVISLINK Corp.
-149d  NEWTEK Inc
-       0001  Video Toaster for PC
-149e  Mapletree Networks Inc.
-149f  LECTRON Co Ltd
-14a0  SOFTING GmBH
-14a1  Systembase Co Ltd
-14a2  Millennium Engineering Inc
-14a3  Maverick Networks
-14a4  GVC/BCM Advanced Research
-14a5  XIONICS Document Technologies Inc
-14a6  INOVA Computers GmBH & Co KG
-14a7  MYTHOS Systems Inc
-14a8  FEATRON Technologies Corporation
-14a9  HIVERTEC Inc
-14aa  Advanced MOS Technology Inc
-14ab  Mentor Graphics Corp.
-14ac  Novaweb Technologies Inc
-14ad  Time Space Radio AB
-14ae  CTI, Inc
-14af  Guillemot Corporation
-       7102  3D Prophet II MX
-14b0  BST Communication Technology Ltd
-14b1  Nextcom K.K.
-14b2  ENNOVATE Networks Inc
-14b3  XPEED Inc
-       0000  DSL NIC
-14b4  PHILIPS Business Electronics B.V.
-14b5  Creamware GmBH
-       0200  Scope
-       0300  Pulsar
-       0400  PulsarSRB
-       0600  Pulsar2
-       0800  DSP-Board
-       0900  DSP-Board
-       0a00  DSP-Board
-       0b00  DSP-Board
-14b6  Quantum Data Corp.
-14b7  PROXIM Inc
-       0001  Symphony 4110
-14b8  Techsoft Technology Co Ltd
-14b9  AIRONET Wireless Communications
-       0001  PC4800
-       0340  PC4800
-       0350  PC4800
-       4500  PC4500
-       4800  Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800
-       a504  Cisco Aironet Wireless 802.11b
-       a505  Cisco Aironet CB20a 802.11a Wireless LAN Adapter
-       a506  Cisco Aironet Mini PCI b/g
-14ba  INTERNIX Inc.
-14bb  SEMTECH Corporation
-14bc  Globespan Semiconductor Inc.
-14bd  CARDIO Control N.V.
-14be  L3 Communications
-14bf  SPIDER Communications Inc.
-14c0  COMPAL Electronics Inc
-14c1  MYRICOM Inc.
-       8043  Myrinet 2000 Scalable Cluster Interconnect
-14c2  DTK Computer
-14c3  MEDIATEK Corp.
-14c4  IWASAKI Information Systems Co Ltd
-14c5  Automation Products AB
-14c6  Data Race Inc
-14c7  Modular Technology Holdings Ltd
-14c8  Turbocomm Tech. Inc.
-14c9  ODIN Telesystems Inc
-14ca  PE Logic Corp.
-14cb  Billionton Systems Inc
-14cc  NAKAYO Telecommunications Inc
-14cd  Universal Scientific Ind.
-14ce  Whistle Communications
-14cf  TEK Microsystems Inc.
-14d0  Ericsson Axe R & D
-14d1  Computer Hi-Tech Co Ltd
-14d2  Titan Electronics Inc
-       8001  VScom 010L 1 port parallel adaptor
-       8002  VScom 020L 2 port parallel adaptor
-       8010  VScom 100L 1 port serial adaptor
-       8011  VScom 110L 1 port serial and 1 port parallel adaptor
-       8020  VScom 200L 1 port serial adaptor
-       8021  VScom 210L 2 port serial and 1 port parallel adaptor
-       8040  VScom 400L 4 port serial adaptor
-       8080  VScom 800L 8 port serial adaptor
-       a000  VScom 010H 1 port parallel adaptor
-       a001  VScom 100H 1 port serial adaptor
-       a003  VScom 400H 4 port serial adaptor
-       a004  VScom 400HF1 4 port serial adaptor
-       a005  VScom 200H 2 port serial adaptor
-       e001  VScom 010HV2 1 port parallel adaptor
-       e010  VScom 100HV2 1 port serial adaptor
-       e020  VScom 200HV2 2 port serial adaptor
-14d3  CIRTECH (UK) Ltd
-14d4  Panacom Technology Corp
-14d5  Nitsuko Corporation
-14d6  Accusys Inc
-14d7  Hirakawa Hewtech Corp
-14d8  HOPF Elektronik GmBH
-# Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc.
-14d9  Alliance Semiconductor Corporation
-       0010  AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
-       9000  AS90L10204/10208 HyperTransport to PCI-X Bridge
-14da  National Aerospace Laboratories
-14db  AFAVLAB Technology Inc
-       2120  TK9902
-14dc  Amplicon Liveline Ltd
-       0000  PCI230
-       0001  PCI242
-       0002  PCI244
-       0003  PCI247
-       0004  PCI248
-       0005  PCI249
-       0006  PCI260
-       0007  PCI224
-       0008  PCI234
-       0009  PCI236
-       000a  PCI272
-       000b  PCI215
-14dd  Boulder Design Labs Inc
-14de  Applied Integration Corporation
-14df  ASIC Communications Corp
-14e1  INVERTEX
-14e2  INFOLIBRIA
-14e3  AMTELCO
-14e4  Broadcom Corporation
-       0800  Sentry5 Chipcommon I/O Controller
-       0804  Sentry5 PCI Bridge
-       0805  Sentry5 MIPS32 CPU
-       0806  Sentry5 Ethernet Controller
-       080b  Sentry5 Crypto Accelerator
-       080f  Sentry5 DDR/SDR RAM Controller
-       0811  Sentry5 External Interface Core
-       0816  BCM3302 Sentry5 MIPS32 CPU
-       1600  NetXtreme BCM5752 Gigabit Ethernet PCI Express
-       1644  NetXtreme BCM5700 Gigabit Ethernet
-               1014 0277  Broadcom Vigil B5700 1000Base-T
-               1028 00d1  Broadcom BCM5700
-               1028 0106  Broadcom BCM5700
-               1028 0109  Broadcom BCM5700 1000Base-T
-               1028 010a  Broadcom BCM5700 1000BaseTX
-               10b7 1000  3C996-T 1000Base-T
-               10b7 1001  3C996B-T 1000Base-T
-               10b7 1002  3C996C-T 1000Base-T
-               10b7 1003  3C997-T 1000Base-T Dual Port
-               10b7 1004  3C996-SX 1000Base-SX
-               10b7 1005  3C997-SX 1000Base-SX Dual Port
-               10b7 1008  3C942 Gigabit LOM (31X31)
-               14e4 0002  NetXtreme 1000Base-SX
-               14e4 0003  NetXtreme 1000Base-SX
-               14e4 0004  NetXtreme 1000Base-T
-               14e4 1028  NetXtreme 1000BaseTX
-               14e4 1644  BCM5700 1000Base-T
-       1645  NetXtreme BCM5701 Gigabit Ethernet
-               0e11 007c  NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
-               0e11 007d  NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
-               0e11 0085  NC7780 Gigabit Server Adapter (embedded, WOL)
-               0e11 0099  NC7780 Gigabit Server Adapter (embedded, WOL)
-               0e11 009a  NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
-               0e11 00c1  NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
-               1028 0121  Broadcom BCM5701 1000Base-T
-               103c 128a  HP 1000Base-T (PCI) [A7061A]
-               103c 128b  HP 1000Base-SX (PCI) [A7073A]
-               103c 12a4  HP Core Lan 1000Base-T
-               103c 12c1  HP IOX Core Lan 1000Base-T [A7109AX]
-               10a9 8010  SGI IO9 Gigabit Ethernet (Copper)
-               10a9 8011  SGI Gigabit Ethernet (Copper)
-               10a9 8012  SGI Gigabit Ethernet (Fiber)
-               10b7 1004  3C996-SX 1000Base-SX
-               10b7 1006  3C996B-T 1000Base-T
-               10b7 1007  3C1000-T 1000Base-T
-               10b7 1008  3C940-BR01 1000Base-T
-               14e4 0001  BCM5701 1000Base-T
-               14e4 0005  BCM5701 1000Base-T
-               14e4 0006  BCM5701 1000Base-T
-               14e4 0007  BCM5701 1000Base-SX
-               14e4 0008  BCM5701 1000Base-T
-               14e4 8008  BCM5701 1000Base-T
-       1646  NetXtreme BCM5702 Gigabit Ethernet
-               0e11 00bb  NC7760 1000BaseTX
-               1028 0126  Broadcom BCM5702 1000BaseTX
-               14e4 8009  BCM5702 1000BaseTX
-       1647  NetXtreme BCM5703 Gigabit Ethernet
-               0e11 0099  NC7780 1000BaseTX
-               0e11 009a  NC7770 1000BaseTX
-               10a9 8010  SGI IO9 Gigabit Ethernet (Copper)
-               14e4 0009  BCM5703 1000BaseTX
-               14e4 000a  BCM5703 1000BaseSX
-               14e4 000b  BCM5703 1000BaseTX
-               14e4 8009  BCM5703 1000BaseTX
-               14e4 800a  BCM5703 1000BaseTX
-       1648  NetXtreme BCM5704 Gigabit Ethernet
-               0e11 00cf  NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               0e11 00d0  NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               0e11 00d1  NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               10b7 2000  3C998-T Dual Port 10/100/1000 PCI-X
-               10b7 3000  3C999-T Quad Port 10/100/1000 PCI-X
-               1166 1648  NetXtreme CIOB-E 1000Base-T
-       164a  NetXtreme II BCM5706 Gigabit Ethernet
-       164d  NetXtreme BCM5702FE Gigabit Ethernet
-       1653  NetXtreme BCM5705 Gigabit Ethernet
-               0e11 00e3  NC7761 Gigabit Server Adapter
-       1654  NetXtreme BCM5705_2 Gigabit Ethernet
-               0e11 00e3  NC7761 Gigabit Server Adapter
-               103c 3100  NC1020 HP ProLiant Gigabit Server Adapter 32 PCI
-       1659  NetXtreme BCM5721 Gigabit Ethernet PCI Express
-       165d  NetXtreme BCM5705M Gigabit Ethernet
-       165e  NetXtreme BCM5705M_2 Gigabit Ethernet
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-       166e  570x 10/100 Integrated Controller
-       1677  NetXtreme BCM5751 Gigabit Ethernet PCI Express
-               1028 0179  Optiplex GX280
-       167d  NetXtreme BCM5751M Gigabit Ethernet PCI Express
-       167e  NetXtreme BCM5751F Fast Ethernet PCI Express
-       1696  NetXtreme BCM5782 Gigabit Ethernet
-               103c 12bc  HP d530 CMT (DG746A)
-               14e4 000d  NetXtreme BCM5782 1000Base-T
-       169c  NetXtreme BCM5788 Gigabit Ethernet
-       169d  NetLink BCM5789 Gigabit Ethernet PCI Express
-       16a6  NetXtreme BCM5702X Gigabit Ethernet
-               0e11 00bb  NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
-               1028 0126  BCM5702 1000Base-T
-               14e4 000c  BCM5702 1000Base-T
-               14e4 8009  BCM5702 1000Base-T
-       16a7  NetXtreme BCM5703X Gigabit Ethernet
-               0e11 00ca  NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               0e11 00cb  NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               14e4 0009  NetXtreme BCM5703 1000Base-T
-               14e4 000a  NetXtreme BCM5703 1000Base-SX
-               14e4 000b  NetXtreme BCM5703 1000Base-T
-               14e4 800a  NetXtreme BCM5703 1000Base-T
-       16a8  NetXtreme BCM5704S Gigabit Ethernet
-               10b7 2001  3C998-SX Dual Port 1000-SX PCI-X
-       16aa  NetXtreme II BCM5706S Gigabit Ethernet
-       16c6  NetXtreme BCM5702A3 Gigabit Ethernet
-               10b7 1100  3C1000B-T 10/100/1000 PCI
-               14e4 000c  BCM5702 1000Base-T
-               14e4 8009  BCM5702 1000Base-T
-       16c7  NetXtreme BCM5703 Gigabit Ethernet
-               0e11 00ca  NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               0e11 00cb  NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
-               103c 12c3  HP Combo FC/GigE-SX [A9782A]
-               103c 12ca  HP Combo FC/GigE-T [A9784A]
-               14e4 0009  NetXtreme BCM5703 1000Base-T
-               14e4 000a  NetXtreme BCM5703 1000Base-SX
-       16dd  NetLink BCM5781 Gigabit Ethernet PCI Express
-       16f7  NetXtreme BCM5753 Gigabit Ethernet PCI Express
-       16fd  NetXtreme BCM5753M Gigabit Ethernet PCI Express
-       16fe  NetXtreme BCM5753F Fast Ethernet PCI Express
-       170c  BCM4401-B0 100Base-TX
-       170d  NetXtreme BCM5901 100Base-TX
-               1014 0545  ThinkPad R40e (2684-HVG) builtin ethernet controller
-       170e  NetXtreme BCM5901 100Base-TX
-       3352  BCM3352
-       3360  BCM3360
-       4210  BCM4210 iLine10 HomePNA 2.0
-       4211  BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
-       4212  BCM4212 v.90 56k modem
-       4301  BCM4303 802.11b Wireless LAN Controller
-               1028 0407  TrueMobile 1180 Onboard WLAN
-               1043 0120  WL-103b Wireless LAN PC Card
-       4305  BCM4307 V.90 56k Modem
-       4306  BCM4307 Ethernet Controller
-       4307  BCM4307 802.11b Wireless LAN Controller
-       4310  BCM4310 Chipcommon I/OController
-       4312  BCM4310 UART
-       4313  BCM4310 Ethernet Controller
-       4315  BCM4310 USB Controller
-       4320  BCM4306 802.11b/g Wireless LAN Controller
-               1028 0001  TrueMobile 1300 WLAN Mini-PCI Card
-               1028 0003  Wireless 1350 WLAN Mini-PCI Card
-               1043 100f  WL-100G
-               14e4 4320  Linksys WMP54G PCI
-               1737 4320  WPC54G
-               1799 7010  Belkin F5D7010 54g Wireless Network card
-       4321  BCM4306 802.11a Wireless LAN Controller
-       4322  BCM4306 UART
-       4324  BCM4309 802.11a/b/g
-               1028 0001  Truemobile 1400
-               1028 0003  Truemobile 1450 MiniPCI
-       4325  BCM43xG 802.11b/g
-               1414 0003  Wireless Notebook Adapter MN-720
-               1414 0004  Wireless PCI Adapter MN-730
-# probably this is a correct ID...
-       4326  BCM4307 Chipcommon I/O Controller?
-       4401  BCM4401 100Base-T
-               1043 80a8  A7V8X motherboard
-       4402  BCM4402 Integrated 10/100BaseT
-       4403  BCM4402 V.90 56k Modem
-       4410  BCM4413 iLine32 HomePNA 2.0
-       4411  BCM4413 V.90 56k modem
-       4412  BCM4412 10/100BaseT
-       4430  BCM44xx CardBus iLine32 HomePNA 2.0
-       4432  BCM4432 CardBus 10/100BaseT
-       4610  BCM4610 Sentry5 PCI to SB Bridge
-       4611  BCM4610 Sentry5 iLine32 HomePNA 1.0
-       4612  BCM4610 Sentry5 V.90 56k Modem
-       4613  BCM4610 Sentry5 Ethernet Controller
-       4614  BCM4610 Sentry5 External Interface
-       4615  BCM4610 Sentry5 USB Controller
-       4704  BCM4704 PCI to SB Bridge
-       4705  BCM4704 Sentry5 802.11b Wireless LAN Controller
-       4706  BCM4704 Sentry5 Ethernet Controller
-       4707  BCM4704 Sentry5 USB Controller
-       4708  BCM4704 Crypto Accelerator
-       4710  BCM4710 Sentry5 PCI to SB Bridge
-       4711  BCM47xx Sentry5 iLine32 HomePNA 2.0
-       4712  BCM47xx V.92 56k modem
-       4713  Sentry5 Ethernet Controller
-       4714  BCM47xx Sentry5 External Interface
-       4715  Sentry5 USB Controller
-       4716  BCM47xx Sentry5 USB Host Controller
-       4717  BCM47xx Sentry5 USB Device Controller
-       4718  Sentry5 Crypto Accelerator
-       4720  BCM4712 MIPS CPU
-       5365  BCM5365P Sentry5 Host Bridge
-       5600  BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
-       5605  BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
-       5615  BCM5615 StrataSwitch 24+2 Ethernet Switch Controller
-       5625  BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
-       5645  BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
-       5670  BCM5670 8-Port 10GE Ethernet Switch Fabric
-       5680  BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller
-       5690  BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
-       5691  BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
-       5820  BCM5820 Crypto Accelerator
-       5821  BCM5821 Crypto Accelerator
-       5822  BCM5822 Crypto Accelerator
-       5823  BCM5823 Crypto Accelerator
-       5824  BCM5824 Crypto Accelerator
-       5840  BCM5840 Crypto Accelerator
-       5841  BCM5841 Crypto Accelerator
-       5850  BCM5850 Crypto Accelerator
-14e5  Pixelfusion Ltd
-14e6  SHINING Technology Inc
-14e7  3CX
-14e8  RAYCER Inc
-14e9  GARNETS System CO Ltd
-14ea  Planex Communications, Inc
-       ab06  FNW-3603-TX CardBus Fast Ethernet
-       ab07  RTL81xx RealTek Ethernet
-14eb  SEIKO EPSON Corp
-14ec  ACQIRIS
-14ed  DATAKINETICS Ltd
-14ee  MASPRO KENKOH Corp
-14ef  CARRY Computer ENG. CO Ltd
-14f0  CANON RESEACH CENTRE FRANCE
-14f1  Conexant
-       1002  HCF 56k Modem
-       1003  HCF 56k Modem
-       1004  HCF 56k Modem
-       1005  HCF 56k Modem
-       1006  HCF 56k Modem
-       1022  HCF 56k Modem
-       1023  HCF 56k Modem
-       1024  HCF 56k Modem
-       1025  HCF 56k Modem
-       1026  HCF 56k Modem
-       1032  HCF 56k Modem
-       1033  HCF 56k Data/Fax Modem
-               1033 8077  NEC
-               122d 4027  Dell Zeus - MDP3880-W(B) Data Fax Modem
-               122d 4030  Dell Mercury - MDP3880-U(B) Data Fax Modem
-               122d 4034  Dell Thor - MDP3880-W(U) Data Fax Modem
-               13e0 020d  Dell Copper
-               13e0 020e  Dell Silver
-               13e0 0261  IBM
-               13e0 0290  Compaq Goldwing
-               13e0 02a0  IBM
-               13e0 02b0  IBM
-               13e0 02c0  Compaq Scooter
-               13e0 02d0  IBM
-               144f 1500  IBM P85-DF (1)
-               144f 1501  IBM P85-DF (2)
-               144f 150a  IBM P85-DF (3)
-               144f 150b  IBM P85-DF Low Profile (1)
-               144f 1510  IBM P85-DF Low Profile (2)
-       1034  HCF 56k Data/Fax/Voice Modem
-       1035  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-               10cf 1098  Fujitsu P85-DFSV
-       1036  HCF 56k Data/Fax/Voice/Spkp Modem
-               104d 8067  HCF 56k Modem
-               122d 4029  MDP3880SP-W
-               122d 4031  MDP3880SP-U
-               13e0 0209  Dell Titanium
-               13e0 020a  Dell Graphite
-               13e0 0260  Gateway Red Owl
-               13e0 0270  Gateway White Horse
-       1052  HCF 56k Data/Fax Modem (Worldwide)
-       1053  HCF 56k Data/Fax Modem (Worldwide)
-       1054  HCF 56k Data/Fax/Voice Modem (Worldwide)
-       1055  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
-       1056  HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
-       1057  HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
-       1059  HCF 56k Data/Fax/Voice Modem (Worldwide)
-       1063  HCF 56k Data/Fax Modem
-       1064  HCF 56k Data/Fax/Voice Modem
-       1065  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-       1066  HCF 56k Data/Fax/Voice/Spkp Modem
-               122d 4033  Dell Athena - MDP3900V-U
-       1433  HCF 56k Data/Fax Modem
-       1434  HCF 56k Data/Fax/Voice Modem
-       1435  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-       1436  HCF 56k Data/Fax Modem
-       1453  HCF 56k Data/Fax Modem
-               13e0 0240  IBM
-               13e0 0250  IBM
-               144f 1502  IBM P95-DF (1)
-               144f 1503  IBM P95-DF (2)
-       1454  HCF 56k Data/Fax/Voice Modem
-       1455  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-       1456  HCF 56k Data/Fax/Voice/Spkp Modem
-               122d 4035  Dell Europa - MDP3900V-W
-               122d 4302  Dell MP3930V-W(C) MiniPCI
-       1610  ADSL AccessRunner PCI Arbitration Device
-       1611  AccessRunner PCI ADSL Interface Device
-       1620  ADSL AccessRunner V2 PCI Arbitration Device
-       1621  AccessRunner V2 PCI ADSL Interface Device
-       1622  AccessRunner V2 PCI ADSL Yukon WAN Adapter
-       1803  HCF 56k Modem
-               0e11 0023  623-LAN Grizzly
-               0e11 0043  623-LAN Yogi
-       1815  HCF 56k Modem
-               0e11 0022  Grizzly
-               0e11 0042  Yogi
-       2003  HSF 56k Data/Fax Modem
-       2004  HSF 56k Data/Fax/Voice Modem
-       2005  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-       2006  HSF 56k Data/Fax/Voice/Spkp Modem
-       2013  HSF 56k Data/Fax Modem
-               0e11 b195  Bear
-               0e11 b196  Seminole 1
-               0e11 b1be  Seminole 2
-               1025 8013  Acer
-               1033 809d  NEC
-               1033 80bc  NEC
-               155d 6793  HP
-               155d 8850  E Machines
-       2014  HSF 56k Data/Fax/Voice Modem
-       2015  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
-       2016  HSF 56k Data/Fax/Voice/Spkp Modem
-       2043  HSF 56k Data/Fax Modem (WorldW SmartDAA)
-       2044  HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA)
-       2045  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
-       2046  HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
-       2063  HSF 56k Data/Fax Modem (SmartDAA)
-       2064  HSF 56k Data/Fax/Voice Modem (SmartDAA)
-       2065  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
-       2066  HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
-       2093  HSF 56k Modem
-               155d 2f07  Legend
-       2143  HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
-       2144  HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA)
-       2145  HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA)
-       2146  HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA)
-       2163  HSF 56k Data/Fax/Cell Modem (Mob SmartDAA)
-       2164  HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA)
-       2165  HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA)
-       2166  HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA)
-       2343  HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA)
-       2344  HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA)
-       2345  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA)
-       2346  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA)
-       2363  HSF 56k Data/Fax CardBus Modem (Mob SmartDAA)
-       2364  HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA)
-       2365  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
-       2366  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
-       2443  HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
-               104d 8075  Modem
-               104d 8083  Modem
-               104d 8097  Modem
-       2444  HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
-       2445  HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
-       2446  HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
-       2463  HSF 56k Data/Fax Modem (Mob SmartDAA)
-       2464  HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
-       2465  HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
-       2466  HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
-       2f00  HSF 56k HSFi Modem
-               13e0 8d84  IBM HSFi V.90
-               13e0 8d85  Compaq Stinger
-               14f1 2004  Dynalink 56PMi
-       2f02  HSF 56k HSFi Data/Fax
-       2f11  HSF 56k HSFi Modem
-       8234  RS8234 ATM SAR Controller [ServiceSAR Plus]
-       8800  CX22702 DVB-T 2k/8k
-               17de 08a1  XPert DVB-T PCI BDA DVBT 23880 Video Capture
-       8802  CX23883 Broadcast Decoder
-               17de 08a1  Xpert DVB-T PCI 2388x Transport Stream Capture
-14f2  MOBILITY Electronics
-       0120  EV1000 bridge
-       0121  EV1000 Parallel port
-       0122  EV1000 Serial port
-       0123  EV1000 Keyboard controller
-       0124  EV1000 Mouse controller
-14f3  BroadLogic
-       2030  2030 DVB-S Satellite Reciever
-       2050  2050 DVB-T Terrestrial (Cable) Reciever
-       2060  2060 ATSC Terrestrial (Cable) Reciever
-14f4  TOKYO Electronic Industry CO Ltd
-14f5  SOPAC Ltd
-14f6  COYOTE Technologies LLC
-14f7  WOLF Technology Inc
-14f8  AUDIOCODES Inc
-       2077  TP-240 dual span E1 VoIP PCI card
-14f9  AG COMMUNICATIONS
-14fa  WANDEL & GOCHERMANN
-14fb  TRANSAS MARINE (UK) Ltd
-14fc  Quadrics Ltd
-       0000  QsNet Elan3 Network Adapter
-       0001  QsNetII Elan4 Network Adapter
-14fd  JAPAN Computer Industry Inc
-14fe  ARCHTEK TELECOM Corp
-14ff  TWINHEAD INTERNATIONAL Corp
-1500  DELTA Electronics, Inc
-       1360  RTL81xx RealTek Ethernet
-1501  BANKSOFT CANADA Ltd
-1502  MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd
-1503  KAWASAKI LSI USA Inc
-1504  KAISER Electronics
-1505  ITA INGENIEURBURO FUR TESTAUFGABEN GmbH
-1506  CHAMELEON Systems Inc
-# Should be HTEC Ltd, but there are no known HTEC chips and 1507 is already used by mistake by Motorola (see vendor ID 1057).
-1507  Motorola ?? / HTEC
-       0001  MPC105 [Eagle]
-       0002  MPC106 [Grackle]
-       0003  MPC8240 [Kahlua]
-       0100  MC145575 [HFC-PCI]
-       0431  KTI829c 100VG
-       4801  Raven
-       4802  Falcon
-       4803  Hawk
-       4806  CPX8216
-1508  HONDA CONNECTORS/MHOTRONICS Inc
-1509  FIRST INTERNATIONAL Computer Inc
-150a  FORVUS RESEARCH Inc
-150b  YAMASHITA Systems Corp
-150c  KYOPAL CO Ltd
-150d  WARPSPPED Inc
-150e  C-PORT Corp
-150f  INTEC GmbH
-1510  BEHAVIOR TECH Computer Corp
-1511  CENTILLIUM Technology Corp
-1512  ROSUN Technologies Inc
-1513  Raychem
-1514  TFL LAN Inc
-1515  Advent design
-1516  MYSON Technology Inc
-       0800  MTD-8xx 100/10M Ethernet PCI Adapter
-       0803  SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
-               1320 10bd  SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
-       0891  MTD-8xx 100/10M Ethernet PCI Adapter
-1517  ECHOTEK Corp
-1518  PEP MODULAR Computers GmbH
-1519  TELEFON AKTIEBOLAGET LM Ericsson
-151a  Globetek
-       1002  PCI-1002
-       1004  PCI-1004
-       1008  PCI-1008
-151b  COMBOX Ltd
-151c  DIGITAL AUDIO LABS Inc
-       0003  Prodif T 2496
-       4000  Prodif 88
-151d  Fujitsu Computer Products Of America
-151e  MATRIX Corp
-151f  TOPIC SEMICONDUCTOR Corp
-       0000  TP560 Data/Fax/Voice 56k modem
-1520  CHAPLET System Inc
-1521  BELL Corp
-1522  MainPine Ltd
-       0100  PCI <-> IOBus Bridge
-               1522 0200  RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
-               1522 0300  RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
-               1522 0400  RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
-               1522 0500  RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
-               1522 0600  RockForce+ 2 Port V.90 Data/Fax/Voice Modem
-               1522 0700  RockForce+ 4 Port V.90 Data/Fax/Voice Modem
-               1522 0800  RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
-               1522 0c00  RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
-               1522 0d00  RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
-# this is a correction to a recent entry. 1522:0E00 should be 1522:1D00
-               1522 1d00  RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
-1523  MUSIC Semiconductors
-1524  ENE Technology Inc
-       0510  CB710 Memory Card Reader Controller
-       0610  PCI Smart Card Reader Controller
-       1211  CB1211 Cardbus Controller
-       1225  CB1225 Cardbus Controller
-       1410  CB1410 Cardbus Controller
-               1025 005a  TravelMate 290
-       1411  CB-710/2/4 Cardbus Controller
-       1412  CB-712/4 Cardbus Controller
-       1420  CB1420 Cardbus Controller
-       1421  CB-720/2/4 Cardbus Controller
-       1422  CB-722/4 Cardbus Controller
-1525  IMPACT Technologies
-1526  ISS, Inc
-1527  SOLECTRON
-1528  ACKSYS
-1529  AMERICAN MICROSystems Inc
-152a  QUICKTURN DESIGN Systems
-152b  FLYTECH Technology CO Ltd
-152c  MACRAIGOR Systems LLC
-152d  QUANTA Computer Inc
-152e  MELEC Inc
-152f  PHILIPS - CRYPTO
-1530  ACQIS Technology Inc
-1531  CHRYON Corp
-1532  ECHELON Corp
-1533  BALTIMORE
-1534  ROAD Corp
-1535  EVERGREEN Technologies Inc
-1537  DATALEX COMMUNCATIONS
-1538  ARALION Inc
-       0303  ARS106S Ultra ATA 133/100/66 Host Controller
-1539  ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A.
-153a  ONO SOKKI
-153b  TERRATEC Electronic GmbH
-       1144  Aureon 5.1
-# Terratec seems to use several IDs for the same card.
-       1147  Aureon 5.1 Sky
-       1158  Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV]
-153c  ANTAL Electronic
-153d  FILANET Corp
-153e  TECHWELL Inc
-153f  MIPS DENMARK
-1540  PROVIDEO MULTIMEDIA Co Ltd
-1541  MACHONE Communications
-1542  VIVID Technology Inc
-1543  SILICON Laboratories
-       3052  Intel 537 [Winmodem]
-       4c22  Si3036 MC'97 DAA
-1544  DCM DATA Systems
-1545  VISIONTEK
-1546  IOI Technology Corp
-1547  MITUTOYO Corp
-1548  JET PROPULSION Laboratory
-1549  INTERCONNECT Systems Solutions
-154a  MAX Technologies Inc
-154b  COMPUTEX Co Ltd
-154c  VISUAL Technology Inc
-154d  PAN INTERNATIONAL Industrial Corp
-154e  SERVOTEST Ltd
-154f  STRATABEAM Technology
-1550  OPEN NETWORK Co Ltd
-1551  SMART Electronic DEVELOPMENT GmBH
-1552  RACAL AIRTECH Ltd
-1553  CHICONY Electronics Co Ltd
-1554  PROLINK Microsystems Corp
-1555  GESYTEC GmBH
-1556  PLD APPLICATIONS
-1557  MEDIASTAR Co Ltd
-1558  CLEVO/KAPOK Computer
-1559  SI LOGIC Ltd
-155a  INNOMEDIA Inc
-155b  PROTAC INTERNATIONAL Corp
-155c  Cemax-Icon Inc
-155d  Mac System Co Ltd
-155e  LP Elektronik GmbH
-155f  Perle Systems Ltd
-1560  Terayon Communications Systems
-1561  Viewgraphics Inc
-1562  Symbol Technologies
-1563  A-Trend Technology Co Ltd
-1564  Yamakatsu Electronics Industry Co Ltd
-1565  Biostar Microtech Int'l Corp
-1566  Ardent Technologies Inc
-1567  Jungsoft
-1568  DDK Electronics Inc
-1569  Palit Microsystems Inc.
-156a  Avtec Systems
-156b  2wire Inc
-156c  Vidac Electronics GmbH
-156d  Alpha-Top Corp
-156e  Alfa Inc
-156f  M-Systems Flash Disk Pioneers Ltd
-1570  Lecroy Corp
-1571  Contemporary Controls
-       a001  CCSI PCI20-485 ARCnet
-       a002  CCSI PCI20-485D ARCnet
-       a003  CCSI PCI20-485X ARCnet
-       a004  CCSI PCI20-CXB ARCnet
-       a005  CCSI PCI20-CXS ARCnet
-       a006  CCSI PCI20-FOG-SMA ARCnet
-       a007  CCSI PCI20-FOG-ST ARCnet
-       a008  CCSI PCI20-TB5 ARCnet
-       a009  CCSI PCI20-5-485 5Mbit ARCnet
-       a00a  CCSI PCI20-5-485D 5Mbit ARCnet
-       a00b  CCSI PCI20-5-485X 5Mbit ARCnet
-       a00c  CCSI PCI20-5-FOG-ST 5Mbit ARCnet
-       a00d  CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
-       a201  CCSI PCI22-485 10Mbit ARCnet
-       a202  CCSI PCI22-485D 10Mbit ARCnet
-       a203  CCSI PCI22-485X 10Mbit ARCnet
-       a204  CCSI PCI22-CHB 10Mbit ARCnet
-       a205  CCSI PCI22-FOG_ST 10Mbit ARCnet
-       a206  CCSI PCI22-THB 10Mbit ARCnet
-1572  Otis Elevator Company
-1573  Lattice - Vantis
-1574  Fairchild Semiconductor
-1575  Voltaire Advanced Data Security Ltd
-1576  Viewcast COM
-1578  HITT
-       5615  VPMK3 [Video Processor Mk III]
-1579  Dual Technology Corp
-157a  Japan Elecronics Ind Inc
-157b  Star Multimedia Corp
-157c  Eurosoft (UK)
-       8001  Fix2000 PCI Y2K Compliance Card
-157d  Gemflex Networks
-157e  Transition Networks
-157f  PX Instruments Technology Ltd
-1580  Primex Aerospace Co
-1581  SEH Computertechnik GmbH
-1582  Cytec Corp
-1583  Inet Technologies Inc
-1584  Uniwill Computer Corp
-1585  Logitron
-1586  Lancast Inc
-1587  Konica Corp
-1588  Solidum Systems Corp
-1589  Atlantek Microsystems Pty Ltd
-158a  Digalog Systems Inc
-158b  Allied Data Technologies
-158c  Hitachi Semiconductor & Devices Sales Co Ltd
-158d  Point Multimedia Systems
-158e  Lara Technology Inc
-158f  Ditect Coop
-1590  3pardata Inc
-1591  ARN
-1592  Syba Tech Ltd
-       0781  Multi-IO Card
-       0782  Parallel Port Card 2xEPP
-       0783  Multi-IO Card
-       0785  Multi-IO Card
-       0786  Multi-IO Card
-       0787  Multi-IO Card
-       0788  Multi-IO Card
-       078a  Multi-IO Card
-1593  Bops Inc
-1594  Netgame Ltd
-1595  Diva Systems Corp
-1596  Folsom Research Inc
-1597  Memec Design Services
-1598  Granite Microsystems
-1599  Delta Electronics Inc
-159a  General Instrument
-159b  Faraday Technology Corp
-159c  Stratus Computer Systems
-159d  Ningbo Harrison Electronics Co Ltd
-159e  A-Max Technology Co Ltd
-159f  Galea Network Security
-15a0  Compumaster SRL
-15a1  Geocast Network Systems
-15a2  Catalyst Enterprises Inc
-       0001  TA700 PCI Bus Analyzer/Exerciser
-15a3  Italtel
-15a4  X-Net OY
-15a5  Toyota Macs Inc
-15a6  Sunlight Ultrasound Technologies Ltd
-15a7  SSE Telecom Inc
-15a8  Shanghai Communications Technologies Center
-15aa  Moreton Bay
-15ab  Bluesteel Networks Inc
-15ac  North Atlantic Instruments
-15ad  VMware Inc
-       0405  [VMware SVGA II] PCI Display Adapter
-       0710  Virtual SVGA
-       0720  VMware High-Speed Virtual NIC [vmxnet]
-15ae  Amersham Pharmacia Biotech
-15b0  Zoltrix International Ltd
-15b1  Source Technology Inc
-15b2  Mosaid Technologies Inc
-15b3  Mellanox Technologies
-       5274  MT21108 InfiniBridge
-       5a44  MT23108 InfiniHost
-       5a45  MT23108 [Infinihost HCA Flash Recovery]
-       5a46  MT23108 PCI Bridge
-       5e8c  MT24204 [InfiniHost III Lx HCA]
-       5e8d  MT24204 [InfiniHost III Lx HCA Flash Recovery]
-       6278  MT25208 InfiniHost III Ex (Tavor compatibility mode)
-       6279  MT25208 [InfiniHost III Ex HCA Flash Recovery]
-       6282  MT25208 InfiniHost III Ex
-15b4  CCI/TRIAD
-15b5  Cimetrics Inc
-15b6  Texas Memory Systems Inc
-15b7  Sandisk Corp
-15b8  ADDI-DATA GmbH
-15b9  Maestro Digital Communications
-15ba  Impacct Technology Corp
-15bb  Portwell Inc
-15bc  Agilent Technologies
-       2922  64 Bit, 133MHz PCI-X Exerciser & Protocol Checker
-       2928  64 Bit, 66MHz PCI Exerciser & Analyzer
-       2929  64 Bit, 133MHz PCI-X Analyzer & Exerciser
-15bd  DFI Inc
-15be  Sola Electronics
-15bf  High Tech Computer Corp (HTC)
-15c0  BVM Ltd
-15c1  Quantel
-15c2  Newer Technology Inc
-15c3  Taiwan Mycomp Co Ltd
-15c4  EVSX Inc
-15c5  Procomp Informatics Ltd
-       8010  1394b - 1394 Firewire 3-Port Host Adapter Card
-15c6  Technical University of Budapest
-15c7  Tateyama System Laboratory Co Ltd
-       0349  Tateyama C-PCI PLC/NC card Rev.01A
-15c8  Penta Media Co Ltd
-15c9  Serome Technology Inc
-15ca  Bitboys OY
-15cb  AG Electronics Ltd
-15cc  Hotrail Inc
-15cd  Dreamtech Co Ltd
-15ce  Genrad Inc
-15cf  Hilscher GmbH
-15d1  Infineon Technologies AG
-15d2  FIC (First International Computer Inc)
-15d3  NDS Technologies Israel Ltd
-15d4  Iwill Corp
-15d5  Tatung Co
-15d6  Entridia Corp
-15d7  Rockwell-Collins Inc
-15d8  Cybernetics Technology Co Ltd
-15d9  Super Micro Computer Inc
-15da  Cyberfirm Inc
-15db  Applied Computing Systems Inc
-15dc  Litronic Inc
-       0001  Argus 300 PCI Cryptography Module
-15dd  Sigmatel Inc
-15de  Malleable Technologies Inc
-15df  Infinilink Corp
-15e0  Cacheflow Inc
-15e1  Voice Technologies Group Inc
-15e2  Quicknet Technologies Inc
-15e3  Networth Technologies Inc
-15e4  VSN Systemen BV
-15e5  Valley technologies Inc
-15e6  Agere Inc
-15e7  Get Engineering Corp
-15e8  National Datacomm Corp
-       0130  Wireless PCI Card
-15e9  Pacific Digital Corp
-       1841  ADMA-100 DiscStaQ ATA Controller
-15ea  Tokyo Denshi Sekei K.K.
-15eb  Drsearch GmbH
-15ec  Beckhoff GmbH
-       3101  FC3101 Profibus DP 1 Channel PCI
-       5102  FC5102
-15ed  Macrolink Inc
-15ee  In Win Development Inc
-15ef  Intelligent Paradigm Inc
-15f0  B-Tree Systems Inc
-15f1  Times N Systems Inc
-15f2  Diagnostic Instruments Inc
-15f3  Digitmedia Corp
-15f4  Valuesoft
-15f5  Power Micro Research
-15f6  Extreme Packet Device Inc
-15f7  Banctec
-15f8  Koga Electronics Co
-15f9  Zenith Electronics Corp
-15fa  J.P. Axzam Corp
-15fb  Zilog Inc
-15fc  Techsan Electronics Co Ltd
-15fd  N-CUBED.NET
-15fe  Kinpo Electronics Inc
-15ff  Fastpoint Technologies Inc
-1600  Northrop Grumman - Canada Ltd
-1601  Tenta Technology
-1602  Prosys-tec Inc
-1603  Nokia Wireless Communications
-1604  Central System Research Co Ltd
-1605  Pairgain Technologies
-1606  Europop AG
-1607  Lava Semiconductor Manufacturing Inc
-1608  Automated Wagering International
-1609  Scimetric Instruments Inc
-1612  Telesynergy Research Inc.
-1619  FarSite Communications Ltd
-       0400  FarSync T2P (2 port X.21/V.35/V.24)
-       0440  FarSync T4P (4 port X.21/V.35/V.24)
-# www.rioworks.com
-161f  Rioworks
-1626  TDK Semiconductor Corp.
-       8410  RTL81xx Fast Ethernet
-1629  Kongsberg Spacetec AS
-       1003  Format synchronizer v3.0
-       2002  Fast Universal Data Output
-# This seems to occur on their 802.11b Wireless card WMP-11
-1637  Linksys
-       3874  Linksys 802.11b WMP11 PCI Wireless card
-1638  Standard Microsystems Corp [SMC]
-       1100  SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000
-163c  Smart Link Ltd.
-       3052  SmartLink SmartPCI562 56K Modem
-       5449  SmartPCI561 Modem
-1657  Brocade Communications Systems, Inc.
-165a  Epix Inc
-       c100  PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
-       d200  PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
-       d300  PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
-165d  Hsing Tech. Enterprise Co., Ltd.
-1661  Worldspace Corp.
-1668  Actiontec Electronics Inc
-       0100  Mini-PCI bridge
-# Formerly SiByte, Inc.
-166d  Broadcom Corporation
-       0001  SiByte BCM1125/1125H/1250 System-on-a-Chip PCI
-       0002  SiByte BCM1125H/1250 System-on-a-Chip HyperTransport
-1677  Bernecker + Rainer
-       104e  5LS172.6 B&R Dual CAN Interface Card
-       12d7  5LS172.61 B&R Dual CAN Interface Card
-167b  ZyDAS Technology Corp.
-       2102  ZyDAS ZD1202
-               187e 3406  ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
-1681  Hercules
-# More specs, more accurate desc.
-       0010  Hercules 3d Prophet II Ultra 64MB [ 350 MHz NV15BR core, 128-bit DDR @ 460 MHz, 1.5v AGP4x  ]
-1682  XFX Pine Group Inc.
-1688  CastleNet Technology Inc.
-       1170  WLAN 802.11b card
-168c  Atheros Communications, Inc.
-       0007  AR5000 802.11a Wireless Adapter
-       0011  AR5210 802.11a NIC
-       0012  AR5211 802.11ab NIC
-       0013  AR5212 802.11abg NIC
-               1113 d301  Philips CPWNA100 Wireless CardBus adapter
-               1186 3202  D-link DWL-G650 B3 Wireless cardbus adapter
-               1186 3203  DWL-G520 Wireless PCI Adapter
-               1186 3a13  DWL-G520 Wireless PCI Adapter rev. B
-               1186 3a94  C54C Wireless 801.11g cardbus
-               1385 4d00  Netgear WG311T Wireless PCI Adapter
-               14b7 0a60  8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
-               168c 0013  WG511T Wireless CardBus Adapter
-               168c 1025  DWL-G650B2 Wireless CardBus Adapter
-               168c 1027  Netgate NL-3054CB ARIES b/g CardBus Adapter
-               168c 2026  Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
-               168c 2041  Netgate 5354MP Plus ARIES2 b/g MiniPCI Adapter
-               168c 2042  Netgate 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
-       1014  AR5212 802.11abg NIC
-169c  Netcell Corporation
-       0044  SyncRAID SR3000/5000 Series SATA RAID Controllers
-16a5  Tekram Technology Co.,Ltd.
-16ab  Global Sun Technology Inc
-       1100  GL24110P
-       1101  PLX9052 PCMCIA-to-PCI Wireless LAN
-       1102  PCMCIA-to-PCI Wireless Network Bridge
-       8501  WL-8305 Wireless LAN PCI Adapter
-16ae  Safenet Inc
-       1141  SafeXcel-1141
-16b4  Aspex Semiconductor Ltd
-16be  Creatix Polymedia GmbH
-16ca  CENATEK Inc
-       0001  Rocket Drive DL
-16cd  Densitron Technologies
-16ce  Roland Corp.
-# www.pikatechnologies.com
-16df  PIKA Technologies Inc.
-16e3  European Space Agency
-       1e0f  LEON2FT Processor
-16ec  U.S. Robotics
-       00ff  USR997900 10/100 Mbps PCI Network Card
-       0116  USR997902 10/100/1000 Mbps PCI Network Card
-       3685  Wireless Access PCI Adapter Model 022415
-16ed  Sycron N. V.
-       1001  UMIO communication card
-16f3  Jetway Information Co., Ltd.
-16f4  Vweb Corp
-       8000  VW2010
-16f6  VideoTele.com, Inc.
-# www.internetmachines.com
-1702  Internet Machines Corporation (IMC)
-1705  Digital First, Inc.
-170b  NetOctave
-       0100  NSP2000-SSL crypto accelerator
-170c  YottaYotta Inc.
-# Seems to be a 2nd ID for Vitesse Semiconductor
-1725  Vitesse Semiconductor
-       7174  VSC7174 PCI/PCI-X Serial ATA Host Bus Controller
-172a  Accelerated Encryption
-1734  Fujitsu Siemens Computer GmbH
-1737  Linksys
-       0013  WMP54G Wireless Pci Card
-       0015  WMP54GS Wireless Pci Card
-       1032  Gigabit Network Adapter
-               1737 0015  EG1032 v2 Instant Gigabit Network Adapter
-       1064  Gigabit Network Adapter
-               1737 0016  EG1064 v2 Instant Gigabit Network Adapter
-       ab08  21x4x DEC-Tulip compatible 10/100 Ethernet
-       ab09  21x4x DEC-Tulip compatible 10/100 Ethernet
-173b  Altima (nee Broadcom)
-       03e8  AC1000 Gigabit Ethernet
-       03e9  AC1001 Gigabit Ethernet
-       03ea  AC9100 Gigabit Ethernet
-               173b 0001  AC1002
-       03eb  AC1003 Gigabit Ethernet
-1743  Peppercon AG
-       8139  ROL/F-100 Fast Ethernet Adapter with ROL
-1749  RLX Technologies
-174b  PC Partner Limited
-174d  WellX Telecom SA
-175c  AudioScience Inc
-175e  Sanera Systems, Inc.
-1787  Hightech Information System Ltd.
-# also used by Struck Innovative Systeme for joint developments
-1796  Research Centre Juelich
-       0001  SIS1100 [Gigabit link]
-       0002  HOTlink
-       0003  Counter Timer
-       0004  CAMAC Controller
-       0005  PROFIBUS
-       0006  AMCC HOTlink
-1797  JumpTec h, GMBH
-1799  Belkin
-       6001  Wireless PCI Card - F5D6001
-       6020  Wireless PCMCIA Card - F5D6020
-       6060  Wireless PDA Card - F5D6060
-       7000  Wireless PCI Card - F5D7000
-17a0  Genesys Logic, Inc
-       8033  GL880S USB 1.1 controller
-       8034  GL880S USB 2.0 controller
-17af  Hightech Information System Ltd.
-17b3  Hawking Technologies
-       ab08  PN672TX 10/100 Ethernet
-17b4  Indra Networks, Inc.
-       0011  WebEnhance 100 GZIP Compression Card
-17c0  Wistron Corp.
-17c2  Newisys, Inc.
-17cc  NetChip Technology, Inc
-       2280  USB 2.0
-17d3  Areca Technology Corp.
-       1110  ARC-1110 4-Port PCI-X to SATA RAID Controller
-       1120  ARC-1120 8-Port PCI-X to SATA RAID Controller
-       1130  ARC-1130 12-Port PCI-X to SATA RAID Controller
-       1160  ARC-1160 16-Port PCI-X to SATA RAID Controller
-       1210  ARC-1210 4-Port PCI-Express to SATA RAID Controller
-       1220  ARC-1220 8-Port PCI-Express to SATA RAID Controller
-       1230  ARC-1230 12-Port PCI-Express to SATA RAID Controller
-       1260  ARC-1260 16-Port PCI-Express to SATA RAID Controller
-# S2io ships 10Gb PCI-X Ethernet adapters www.s2io.com
-17d5  S2io Inc.
-       5831  Xframe 10 Gigabit Ethernet PCI-X
-               103c 12d5  HP PCI-X 133MHz 10GbE SR Fiber [AB287A]
-17de  KWorld Computer Co. Ltd.
-# http://www.connect3d.com
-17ee  Connect Components Ltd
-17fe  Linksys, A Division of Cisco Systems
-       2120  WMP11v4 802.11b PCI card
-       2220  [AirConn] INPROCOMM IPN 2220 Wireless LAN Adapter (rev 01)
-1813  Ambient Technologies Inc
-       4000  HaM controllerless modem
-               16be 0001  V9x HAM Data Fax Modem
-       4100  HaM plus Data Fax Modem
-               16be 0002  V9x HAM 1394
-1814  RaLink
-       0101  Wireless PCI Adpator RT2400 / RT2460
-               3306 1113  Quidway WL100M
-       0201  Ralink RT2500 802.11 Cardbus Reference Card
-               1371 001e  CWC-854 Wireless-G CardBus Adapter
-               1371 001f  CWM-854 Wireless-G Mini PCI Adapter
-               1371 0020  CWP-854 Wireless-G PCI Adapter
-               1458 e381  GN-WMKG 802.11b/g Wireless CardBus Adapter
-1820  InfiniCon Systems Inc.
-1822  Twinhan Technology Co. Ltd
-182d  SiteCom Europe BV
-# HFC-based ISDN card
-       3069  ISDN PCI DC-105V2
-       9790  WL-121 Wireless Network Adapter 100g+ [Ver.3]
-1830  Credence Systems Corporation
-183b  MikroM GmbH
-       08a7  MVC100 DVI
-       08a8  MVC101 SDI
-       08a9  MVC102 DVI+Audio
-1849  ASRock Incorporation
-1851  Microtune, Inc.
-1852  Anritsu Corp.
-185f  Wistron NeWeb Corp.
-1867  Topspin Communications
-       5a44  MT23108 PCI-X HCA
-       5a45  MT23108 PCI-X HCA flash recovery
-       5a46  MT23108 PCI-X HCA bridge
-       6278  MT25208 InfiniHost III Ex (Tavor compatibility mode)
-       6282  MT25208 InfiniHost III Ex
-187e  ZyXEL Communication Corporation
-1888  Varisys Ltd
-       0301  VMFX1 FPGA PMC module
-       0601  VSM2 dual PMC carrier
-       0710  VS14x series PowerPC PCI board
-       0720  VS24x series PowerPC PCI board
-# found e.g. on KNC DVB-S card
-1894  KNC One
-1896  B&B Electronics Manufacturing Company, Inc.
-18a1  Astute Networks Inc.
-18ac  DViCO Corporation
-       d810  FusionHDTV 3 Gold
-18b8  Ammasso
-       b001  AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor
-18bc  Info-Tek Corp.
-# assigned to Octigabay System, which has been acquired by Cray
-18c8  Cray Inc
-18c9  ARVOO Engineering BV
-18ca  XGI - Xabre Graphics Inc
-       0040  Volari V8
-18e6  MPL AG
-       0001  OSCI [Octal Serial Communication Interface]
-18f7  Commtech, Inc.
-       0001  Fastcom ESCC-PCI-335
-       0002  Fastcom 422/4-PCI-335
-       0004  Fastcom 422/2-PCI-335
-       0005  Fastcom IGESCC-PCI-ISO/1
-       000a  Fastcom 232/4-PCI-335
-18fb  Resilience Corporation
-1924  Level 5 Networks Inc.
-1966  Orad Hi-Tec Systems
-       1975  DVG64 family
-1993  Innominate Security Technologies AG
-# http://www.progeny.net
-19ae  Progeny Systems Corporation
-1a08  Sierra semiconductor
-       0000  SC15064
-1b13  Jaton Corp
-1c1c  Symphony
-       0001  82C101
-1d44  DPT
-       a400  PM2x24/PM3224
-1de1  Tekram Technology Co.,Ltd.
-       0391  TRM-S1040
-       2020  DC-390
-       690c  690c
-       dc29  DC290
-1fc0  Tumsan Oy
-       0300  E2200 Dual E1/Rawpipe Card
-2000  Smart Link Ltd.
-2001  Temporal Research Ltd
-2003  Smart Link Ltd.
-2004  Smart Link Ltd.
-21c3  21st Century Computer Corp.
-2348  Racore
-       2010  8142 100VG/AnyLAN
-2646  Kingston Technologies
-270b  Xantel Corporation
-270f  Chaintech Computer Co. Ltd
-2711  AVID Technology Inc.
-2a15  3D Vision(???)
-3000  Hansol Electronics Inc.
-3142  Post Impression Systems.
-3388  Hint Corp
-       0013  HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
-       0014  HiNT HC4 PCI to ISDN bridge, Network controller
-       0020  HB6 Universal PCI-PCI bridge (transparent mode)
-       0021  HB6 Universal PCI-PCI bridge (non-transparent mode)
-               4c53 1050  CT7 mainboard
-               4c53 1080  CT8 mainboard
-               4c53 10a0  CA3/CR3 mainboard
-               4c53 3010  PPCI mezzanine (32-bit PMC)
-               4c53 3011  PPCI mezzanine (64-bit PMC)
-       0022  HiNT HB4 PCI-PCI Bridge (PCI6150)
-       0026  HB2 PCI-PCI Bridge
-       101a  E.Band [AudioTrak Inca88]
-       101b  E.Band [AudioTrak Inca88]
-       8011  VXPro II Chipset
-               3388 8011  VXPro II Chipset CPU to PCI Bridge
-       8012  VXPro II Chipset
-               3388 8012  VXPro II Chipset PCI to ISA Bridge
-       8013  VXPro II IDE
-               3388 8013  VXPro II Chipset EIDE Controller
-3411  Quantum Designs (H.K.) Inc
-3513  ARCOM Control Systems Ltd
-3842  eVga.com. Corp.
-38ef  4Links
-3d3d  3DLabs
-       0001  GLINT 300SX
-       0002  GLINT 500TX
-       0003  GLINT Delta
-       0004  Permedia
-       0005  Permedia
-       0006  GLINT MX
-       0007  3D Extreme
-       0008  GLINT Gamma G1
-       0009  Permedia II 2D+3D
-               1040 0011  AccelStar II
-               13e9 1000  6221L-4U
-               3d3d 0100  AccelStar II 3D Accelerator
-               3d3d 0111  Permedia 3:16
-               3d3d 0114  Santa Ana
-               3d3d 0116  Oxygen GVX1
-               3d3d 0119  Scirocco
-               3d3d 0120  Santa Ana PCL
-               3d3d 0125  Oxygen VX1
-               3d3d 0127  Permedia3 Create!
-       000a  GLINT R3
-               3d3d 0121  Oxygen VX1
-       000c  GLINT R3 [Oxygen VX1]
-               3d3d 0144  Oxygen VX1-4X AGP [Permedia 4]
-       000d  GLint R4 rev A
-       0011  GLint R4 rev B
-       0012  GLint R5 rev A
-       0013  GLint R5 rev B
-       0020  VP10 visual processor
-# P10 generic II
-       0022  VP10 visual processor
-       0024  VP9 visual processor
-       0100  Permedia II 2D+3D
-       07a1  Wildcat III 6210
-       07a2  Sun XVR-500 Graphics Accelerator
-       07a3  Wildcat IV 7210
-       1004  Permedia
-       3d04  Permedia
-       ffff  Glint VGA
-4005  Avance Logic Inc.
-       0300  ALS300 PCI Audio Device
-       0308  ALS300+ PCI Audio Device
-       0309  PCI Input Controller
-       1064  ALG-2064
-       2064  ALG-2064i
-       2128  ALG-2364A GUI Accelerator
-       2301  ALG-2301
-       2302  ALG-2302
-       2303  AVG-2302 GUI Accelerator
-       2364  ALG-2364A
-       2464  ALG-2464
-       2501  ALG-2564A/25128A
-       4000  ALS4000 Audio Chipset
-               4005 4000  ALS4000 Audio Chipset
-       4710  ALC200/200P
-4033  Addtron Technology Co, Inc.
-       1360  RTL8139 Ethernet
-4143  Digital Equipment Corp
-4144  Alpha Data
-       0044  ADM-XRCIIPro
-416c  Aladdin Knowledge Systems
-       0100  AladdinCARD
-       0200  CPC
-4444  Internext Compression Inc
-       0016  iTVC16 (CX23416) MPEG-2 Encoder
-               0070 4009  WinTV PVR 250
-               0070 8003  WinTV PVR 150
-       0803  iTVC15 MPEG-2 Encoder
-               0070 4000  WinTV PVR-350
-               0070 4001  WinTV PVR-250
-# video capture card
-               1461 a3cf  M179
-4468  Bridgeport machines
-4594  Cogetec Informatique Inc
-45fb  Baldor Electric Company
-4680  Umax Computer Corp
-4843  Hercules Computer Technology Inc
-4916  RedCreek Communications Inc
-       1960  RedCreek PCI adapter
-4943  Growth Networks
-494f  ACCES I/O Products, Inc.
-       10e8  LPCI-COM-8SM
-4978  Axil Computer Inc
-4a14  NetVin
-       5000  NV5000SC
-               4a14 5000  RT8029-Based Ethernet Adapter
-4b10  Buslogic Inc.
-4c48  LUNG HWA Electronics
-4c53  SBS Technologies
-       0000  PLUSTEST device
-               4c53 3000  PLUSTEST card (PC104+)
-               4c53 3001  PLUSTEST card (PMC)
-       0001  PLUSTEST-MM device
-               4c53 3002  PLUSTEST-MM card (PMC)
-4ca1  Seanix Technology Inc
-4d51  MediaQ Inc.
-       0200  MQ-200
-4d54  Microtechnica Co Ltd
-4ddc  ILC Data Device Corp
-       0100  DD-42924I5-300 (ARINC 429 Data Bus)
-       0801  BU-65570I1 MIL-STD-1553 Test and Simulation
-       0802  BU-65570I2 MIL-STD-1553 Test and Simulation
-       0811  BU-65572I1 MIL-STD-1553 Test and Simulation
-       0812  BU-65572I2 MIL-STD-1553 Test and Simulation
-       0881  BU-65570T1 MIL-STD-1553 Test and Simulation
-       0882  BU-65570T2 MIL-STD-1553 Test and Simulation
-       0891  BU-65572T1 MIL-STD-1553 Test and Simulation
-       0892  BU-65572T2 MIL-STD-1553 Test and Simulation
-       0901  BU-65565C1 MIL-STD-1553 Data Bus
-       0902  BU-65565C2 MIL-STD-1553 Data Bus
-       0903  BU-65565C3 MIL-STD-1553 Data Bus
-       0904  BU-65565C4 MIL-STD-1553 Data Bus
-       0b01  BU-65569I1 MIL-STD-1553 Data Bus
-       0b02  BU-65569I2 MIL-STD-1553 Data Bus
-       0b03  BU-65569I3 MIL-STD-1553 Data Bus
-       0b04  BU-65569I4 MIL-STD-1553 Data Bus
-5046  GemTek Technology Corporation
-       1001  PCI Radio
-5053  Voyetra Technologies
-       2010  Daytona Audio Adapter
-5136  S S Technologies
-5143  Qualcomm Inc
-5145  Ensoniq (Old)
-       3031  Concert AudioPCI
-5168  Animation Technologies Inc.
-5301  Alliance Semiconductor Corp.
-       0001  ProMotion aT3D
-5333  S3 Inc.
-       0551  Plato/PX (system)
-       5631  86c325 [ViRGE]
-       8800  86c866 [Vision 866]
-       8801  86c964 [Vision 964]
-       8810  86c764_0 [Trio 32 vers 0]
-       8811  86c764/765 [Trio32/64/64V+]
-       8812  86cM65 [Aurora64V+]
-       8813  86c764_3 [Trio 32/64 vers 3]
-       8814  86c767 [Trio 64UV+]
-       8815  86cM65 [Aurora 128]
-       883d  86c988 [ViRGE/VX]
-       8870  FireGL
-       8880  86c868 [Vision 868 VRAM] vers 0
-       8881  86c868 [Vision 868 VRAM] vers 1
-       8882  86c868 [Vision 868 VRAM] vers 2
-       8883  86c868 [Vision 868 VRAM] vers 3
-       88b0  86c928 [Vision 928 VRAM] vers 0
-       88b1  86c928 [Vision 928 VRAM] vers 1
-       88b2  86c928 [Vision 928 VRAM] vers 2
-       88b3  86c928 [Vision 928 VRAM] vers 3
-       88c0  86c864 [Vision 864 DRAM] vers 0
-       88c1  86c864 [Vision 864 DRAM] vers 1
-       88c2  86c864 [Vision 864-P DRAM] vers 2
-       88c3  86c864 [Vision 864-P DRAM] vers 3
-       88d0  86c964 [Vision 964 VRAM] vers 0
-       88d1  86c964 [Vision 964 VRAM] vers 1
-       88d2  86c964 [Vision 964-P VRAM] vers 2
-       88d3  86c964 [Vision 964-P VRAM] vers 3
-       88f0  86c968 [Vision 968 VRAM] rev 0
-       88f1  86c968 [Vision 968 VRAM] rev 1
-       88f2  86c968 [Vision 968 VRAM] rev 2
-       88f3  86c968 [Vision 968 VRAM] rev 3
-       8900  86c755 [Trio 64V2/DX]
-               5333 8900  86C775 Trio64V2/DX
-       8901  86c775/86c785 [Trio 64V2/DX or /GX]
-               5333 8901  86C775 Trio64V2/DX, 86C785 Trio64V2/GX
-       8902  Plato/PX
-       8903  Trio 3D business multimedia
-       8904  Trio 64 3D
-               1014 00db  Integrated Trio3D
-               5333 8904  86C365 Trio3D AGP
-       8905  Trio 64V+ family
-       8906  Trio 64V+ family
-       8907  Trio 64V+ family
-       8908  Trio 64V+ family
-       8909  Trio 64V+ family
-       890a  Trio 64V+ family
-       890b  Trio 64V+ family
-       890c  Trio 64V+ family
-       890d  Trio 64V+ family
-       890e  Trio 64V+ family
-       890f  Trio 64V+ family
-       8a01  ViRGE/DX or /GX
-               0e11 b032  ViRGE/GX
-               10b4 1617  Nitro 3D
-               10b4 1717  Nitro 3D
-               5333 8a01  ViRGE/DX
-       8a10  ViRGE/GX2
-               1092 8a10  Stealth 3D 4000
-       8a13  86c368 [Trio 3D/2X]
-               5333 8a13  Trio3D/2X
-       8a20  86c794 [Savage 3D]
-               5333 8a20  86C391 Savage3D
-       8a21  86c390 [Savage 3D/MV]
-               5333 8a21  86C390 Savage3D/MV
-       8a22  Savage 4
-               1033 8068  Savage 4
-               1033 8069  Savage 4
-               1033 8110  Savage4 LT
-               105d 0018  SR9 8Mb SDRAM
-               105d 002a  SR9 Pro 16Mb SDRAM
-               105d 003a  SR9 Pro 32Mb SDRAM
-               105d 092f  SR9 Pro+ 16Mb SGRAM
-               1092 4207  Stealth III S540
-               1092 4800  Stealth III S540
-               1092 4807  SpeedStar A90
-               1092 4808  Stealth III S540
-               1092 4809  Stealth III S540
-               1092 480e  Stealth III S540
-               1092 4904  Stealth III S520
-               1092 4905  SpeedStar A200
-               1092 4a09  Stealth III S540
-               1092 4a0b  Stealth III S540 Xtreme
-               1092 4a0f  Stealth III S540
-               1092 4e01  Stealth III S540
-               1102 101d  3d Blaster Savage 4
-               1102 101e  3d Blaster Savage 4
-               5333 8100  86C394-397 Savage4 SDRAM 100
-               5333 8110  86C394-397 Savage4 SDRAM 110
-               5333 8125  86C394-397 Savage4 SDRAM 125
-               5333 8143  86C394-397 Savage4 SDRAM 143
-               5333 8a22  86C394-397 Savage4
-               5333 8a2e  86C394-397 Savage4 32bit
-               5333 9125  86C394-397 Savage4 SGRAM 125
-               5333 9143  86C394-397 Savage4 SGRAM 143
-       8a23  Savage 4
-       8a25  ProSavage PM133
-       8a26  ProSavage KM133
-       8c00  ViRGE/M3
-       8c01  ViRGE/MX
-               1179 0001  ViRGE/MX
-       8c02  ViRGE/MX+
-       8c03  ViRGE/MX+MV
-       8c10  86C270-294 Savage/MX-MV
-       8c11  82C270-294 Savage/MX
-       8c12  86C270-294 Savage/IX-MV
-               1014 017f  ThinkPad T20
-               1179 0001  86C584 SuperSavage/IXC Toshiba
-       8c13  86C270-294 Savage/IX
-               1179 0001  Magnia Z310
-       8c22  SuperSavage MX/128
-       8c24  SuperSavage MX/64
-       8c26  SuperSavage MX/64C
-       8c2a  SuperSavage IX/128 SDR
-       8c2b  SuperSavage IX/128 DDR
-       8c2c  SuperSavage IX/64 SDR
-       8c2d  SuperSavage IX/64 DDR
-       8c2e  SuperSavage IX/C SDR
-               1014 01fc  ThinkPad T23 (2647-4MG)
-       8c2f  SuperSavage IX/C DDR
-       8d01  86C380 [ProSavageDDR K4M266]
-       8d02  VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
-       8d03  VT8751 [ProSavageDDR P4M266]
-       8d04  VT8375 [ProSavage8 KM266/KL266]
-       9102  86C410 Savage 2000
-               1092 5932  Viper II Z200
-               1092 5934  Viper II Z200
-               1092 5952  Viper II Z200
-               1092 5954  Viper II Z200
-               1092 5a35  Viper II Z200
-               1092 5a37  Viper II Z200
-               1092 5a55  Viper II Z200
-               1092 5a57  Viper II Z200
-       ca00  SonicVibes
-544c  Teralogic Inc
-       0350  TL880-based HDTV/ATSC tuner
-5455  Technische University Berlin
-       4458  S5933
-5519  Cnet Technologies, Inc.
-5544  Dunord Technologies
-       0001  I-30xx Scanner Interface
-5555  Genroco, Inc
-       0003  TURBOstor HFP-832 [HiPPI NIC]
-5654  VoiceTronix Pty Ltd
-       3132  OpenSwitch12
-5700  Netpower
-5851  Exacq Technologies
-6356  UltraStor
-6374  c't Magazin für Computertechnik
-       6773  GPPCI
-6409  Logitec Corp.
-6666  Decision Computer International Co.
-       0001  PCCOM4
-       0002  PCCOM8
-7604  O.N. Electronic Co Ltd.
-7bde  MIDAC Corporation
-7fed  PowerTV
-8008  Quancom Electronic GmbH
-       0010  WDOG1 [PCI-Watchdog 1]
-       0011  PWDOG2 [PCI-Watchdog 2]
-# Wrong ID used in subsystem ID of AsusTek PCI-USB2 PCI card.
-807d  Asustek Computer, Inc.
-8086  Intel Corporation
-       0007  82379AB
-       0008  Extended Express System Support Controller
-               0008 1000  WorldMark 4300 INCA ASIC
-       0039  21145 Fast Ethernet
-       0122  82437FX
-       0309  80303 I/O Processor PCI-to-PCI Bridge
-       030d  80312 I/O Companion Chip PCI-to-PCI Bridge
-       0326  6700/6702PXH I/OxAPIC Interrupt Controller A
-       0327  6700PXH I/OxAPIC Interrupt Controller B
-       0329  6700PXH PCI Express-to-PCI Bridge A
-       032a  6700PXH PCI Express-to-PCI Bridge B
-       032c  6702PXH PCI Express-to-PCI Bridge A
-# A-segment bridge
-       0330  80332 [Dobson] I/O processor
-# A-segment IOAPIC
-       0331  80332 [Dobson] I/O processor
-# B-segment bridge
-       0332  80332 [Dobson] I/O processor
-# B-segment IOAPIC
-       0333  80332 [Dobson] I/O processor
-# Address Translation Unit (ATU)
-       0334  80332 [Dobson] I/O processor
-# PCI-X bridge
-       0335  80331 [Lindsay] I/O processor
-# Address Translation Unit (ATU)
-       0336  80331 [Lindsay] I/O processor
-# A-segment bridge
-       0340  41210 [Lanai] Serial to Parallel PCI Bridge
-# B-segment bridge
-       0341  41210 [Lanai] Serial to Parallel PCI Bridge
-       0482  82375EB/SB PCI to EISA Bridge
-       0483  82424TX/ZX [Saturn] CPU to PCI bridge
-       0484  82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge
-       0486  82425EX/ZX [Aries] PCIset with ISA bridge
-       04a3  82434LX/NX [Mercury/Neptune] Processor to PCI bridge
-       04d0  82437FX [Triton FX]
-       0500  E8870 Processor bus control
-       0501  E8870 Memory controller
-# and registers common to both SPs
-       0502  E8870 Scalability Port 0
-# and global performance monitoring
-       0503  E8870 Scalability Port 1
-       0510  E8870IO Hub Interface Port 0 registers (8-bit compatibility port)
-       0511  E8870IO Hub Interface Port 1 registers
-       0512  E8870IO Hub Interface Port 2 registers
-       0513  E8870IO Hub Interface Port 3 registers
-       0514  E8870IO Hub Interface Port 4 registers
-       0515  E8870IO General SIOH registers
-       0516  E8870IO RAS registers
-       0530  E8870SP Scalability Port 0 registers
-       0531  E8870SP Scalability Port 1 registers
-       0532  E8870SP Scalability Port 2 registers
-       0533  E8870SP Scalability Port 3 registers
-       0534  E8870SP Scalability Port 4 registers
-       0535  E8870SP Scalability Port 5 registers
-# (bi-interleave 0) and global registers that are neither per-port nor per-interleave
-       0536  E8870SP Interleave registers 0 and 1
-# (bi-interleave 1)
-       0537  E8870SP Interleave registers 2 and 3
-       0600  RAID Controller
-               8086 01c1  ICP Vortex GDT8546RZ
-               8086 01f7  SCRU32
-# uninitialized SRCU32 RAID Controller
-       061f  80303 I/O Processor
-       0960  80960RP [i960 RP Microprocessor/Bridge]
-       0962  80960RM [i960RM Bridge]
-       0964  80960RP [i960 RP Microprocessor/Bridge]
-       1000  82542 Gigabit Ethernet Controller
-               0e11 b0df  NC1632 Gigabit Ethernet Adapter (1000-SX)
-               0e11 b0e0  NC1633 Gigabit Ethernet Adapter (1000-LX)
-               0e11 b123  NC1634 Gigabit Ethernet Adapter (1000-SX)
-               1014 0119  Netfinity Gigabit Ethernet SX Adapter
-               8086 1000  PRO/1000 Gigabit Server Adapter
-       1001  82543GC Gigabit Ethernet Controller (Fiber)
-               0e11 004a  NC6136 Gigabit Server Adapter
-               1014 01ea  Netfinity Gigabit Ethernet SX Adapter
-               8086 1002  PRO/1000 F Server Adapter
-               8086 1003  PRO/1000 F Server Adapter
-       1002  Pro 100 LAN+Modem 56 Cardbus II
-               8086 200e  Pro 100 LAN+Modem 56 Cardbus II
-               8086 2013  Pro 100 SR Mobile Combo Adapter
-               8086 2017  Pro 100 S Combo Mobile Adapter
-       1004  82543GC Gigabit Ethernet Controller (Copper)
-               0e11 0049  NC7132 Gigabit Upgrade Module
-               0e11 b1a4  NC7131 Gigabit Server Adapter
-               1014 10f2  Gigabit Ethernet Server Adapter
-               8086 1004  PRO/1000 T Server Adapter
-               8086 2004  PRO/1000 T Server Adapter
-       1008  82544EI Gigabit Ethernet Controller (Copper)
-               1014 0269  iSeries 1000/100/10 Ethernet Adapter
-               1028 011c  PRO/1000 XT Network Connection
-               8086 1107  PRO/1000 XT Server Adapter
-               8086 2107  PRO/1000 XT Server Adapter
-               8086 2110  PRO/1000 XT Server Adapter
-               8086 3108  PRO/1000 XT Network Connection
-       1009  82544EI Gigabit Ethernet Controller (Fiber)
-               1014 0268  iSeries Gigabit Ethernet Adapter
-               8086 1109  PRO/1000 XF Server Adapter
-               8086 2109  PRO/1000 XF Server Adapter
-       100c  82544GC Gigabit Ethernet Controller (Copper)
-               8086 1112  PRO/1000 T Desktop Adapter
-               8086 2112  PRO/1000 T Desktop Adapter
-       100d  82544GC Gigabit Ethernet Controller (LOM)
-               1028 0123  PRO/1000 XT Network Connection
-               1079 891f  82544GC Based Network Connection
-               4c53 1080  CT8 mainboard
-               8086 110d  82544GC Based Network Connection
-       100e  82540EM Gigabit Ethernet Controller
-               1014 0265  PRO/1000 MT Network Connection
-               1014 0267  PRO/1000 MT Network Connection
-               1014 026a  PRO/1000 MT Network Connection
-               1028 002e  Optiplex GX260
-               1028 0151  PRO/1000 MT Network Connection
-               107b 8920  PRO/1000 MT Desktop Adapter
-               8086 001e  PRO/1000 MT Desktop Adapter
-               8086 002e  PRO/1000 MT Desktop Adapter
-       100f  82545EM Gigabit Ethernet Controller (Copper)
-               1014 0269  iSeries 1000/100/10 Ethernet Adapter
-               1014 028e  PRO/1000 MT Network Connection
-               8086 1000  PRO/1000 MT Network Connection
-               8086 1001  PRO/1000 MT Server Adapter
-       1010  82546EB Gigabit Ethernet Controller (Copper)
-               1014 027c  PRO/1000 MT Dual Port Network Adapter
-               18fb 7872  RESlink-X
-               4c53 1080  CT8 mainboard
-               4c53 10a0  CA3/CR3 mainboard
-               8086 1011  PRO/1000 MT Dual Port Server Adapter
-               8086 101a  PRO/1000 MT Dual Port Network Adapter
-               8086 3424  SE7501HG2 Mainboard
-       1011  82545EM Gigabit Ethernet Controller (Fiber)
-               1014 0268  iSeries Gigabit Ethernet Adapter
-               8086 1002  PRO/1000 MF Server Adapter
-               8086 1003  PRO/1000 MF Server Adapter (LX)
-       1012  82546EB Gigabit Ethernet Controller (Fiber)
-               8086 1012  PRO/1000 MF Dual Port Server Adapter
-       1013  82541EI Gigabit Ethernet Controller (Copper)
-               8086 0013  PRO/1000 MT Network Connection
-               8086 1013  IBM ThinkCentre Network Card
-               8086 1113  PRO/1000 MT Desktop Adapter
-       1014  82541ER Gigabit Ethernet Controller
-       1015  82540EM Gigabit Ethernet Controller (LOM)
-       1016  82540EP Gigabit Ethernet Controller (LOM)
-               1014 052c  PRO/1000 MT Mobile Connection
-               1179 0001  PRO/1000 MT Mobile Connection
-               8086 1016  PRO/1000 MT Mobile Connection
-       1017  82540EP Gigabit Ethernet Controller (LOM)
-               8086 1017  PR0/1000 MT Desktop Connection
-# Update controller name from 82541EP to 82541EI
-       1018  82541EI Gigabit Ethernet Controller
-               8086 1018  PRO/1000 MT Desktop Adapter
-       1019  82547EI Gigabit Ethernet Controller (LOM)
-               1458 1019  GA-8IPE1000 Pro2 motherboard (865PE)
-               1458 e000  Intel Gigabit Ethernet (Kenai II)
-               8086 1019  PRO/1000 CT Desktop Connection
-               8086 301f  D865PERL mainboard
-               8086 3427  S875WP1-E mainboard
-       101d  82546EB Gigabit Ethernet Controller
-               8086 1000  PRO/1000 MT Quad Port Server Adapter
-       101e  82540EP Gigabit Ethernet Controller (Mobile)
-               1014 0549  PRO/1000 MT Mobile Connection
-               1179 0001  PRO/1000 MT Mobile Connection
-               8086 101e  PRO/1000 MT Mobile Connection
-       1026  82545GM Gigabit Ethernet Controller
-               8086 1000  PRO/1000 MT Server Connection
-               8086 1001  PRO/1000 MT Server Adapter
-               8086 1002  PRO/1000 MT Server Adapter
-               8086 1026  PRO/1000 MT Server Connection
-       1027  82545GM Gigabit Ethernet Controller
-               8086 1001  PRO/1000 MF Server Adapter(LX)
-               8086 1002  PRO/1000 MF Server Adapter(LX)
-               8086 1003  PRO/1000 MF Server Adapter(LX)
-               8086 1027  PRO/1000 MF Server Adapter
-       1028  82545GM Gigabit Ethernet Controller
-               8086 1028  PRO/1000 MB Server Adapter
-       1029  82559 Ethernet Controller
-       1030  82559 InBusiness 10/100
-       1031  82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
-               1014 0209  ThinkPad A/T/X Series
-               104d 80e7  Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               107b 5350  EtherExpress PRO/100 VE
-               1179 0001  EtherExpress PRO/100 VE
-               144d c000  EtherExpress PRO/100 VE
-               144d c001  EtherExpress PRO/100 VE
-               144d c003  EtherExpress PRO/100 VE
-               144d c006  vpr Matrix 170B4
-       1032  82801CAM (ICH3) PRO/100 VE Ethernet Controller
-       1033  82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
-       1034  82801CAM (ICH3) PRO/100 VM Ethernet Controller
-       1035  82801CAM (ICH3)/82562EH (LOM)  Ethernet Controller
-       1036  82801CAM (ICH3) 82562EH Ethernet Controller
-       1037  82801CAM (ICH3) Chipset Ethernet Controller
-       1038  82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
-       1039  82801DB PRO/100 VE (LOM) Ethernet Controller
-               1014 0267  NetVista A30p
-       103a  82801DB PRO/100 VE (CNR) Ethernet Controller
-       103b  82801DB PRO/100 VM (LOM) Ethernet Controller
-       103c  82801DB PRO/100 VM (CNR) Ethernet Controller
-       103d  82801DB PRO/100 VE (MOB) Ethernet Controller
-       103e  82801DB PRO/100 VM (MOB) Ethernet Controller
-       1040  536EP Data Fax Modem
-               16be 1040  V.9X DSP Data Fax Modem
-       1043  PRO/Wireless LAN 2100 3B Mini PCI Adapter
-               8086 2527  MIM2000/Centrino
-       1048  PRO/10GbE LR Server Adapter
-               8086 a01f  PRO/10GbE LR Server Adapter
-               8086 a11f  PRO/10GbE LR Server Adapter
-       1050  82562EZ 10/100 Ethernet Controller
-               1462 728c  865PE Neo2 (MS-6728)
-               1462 758c  MS-6758 (875P Neo)
-               8086 3020  D865PERL mainboard
-               8086 3427  S875WP1-E mainboard
-       1051  82801EB/ER (ICH5/ICH5R) integrated LAN Controller
-       1059  82551QM Ethernet Controller
-# ICH-6 Component
-       1064  82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
-# ICH-6 Component
-       1065  82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
-# ICH-6 Component
-       1066  82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller
-# ICH-6 Component
-       1067  82562 EM/EX/GX - PRO/100 VM Ethernet Controller
-# ICH-6 Component
-       1068  82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile
-# ICH-6 Component
-       1069  82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile
-# ICH-6 Component
-       106a  82562G \t- PRO/100 VE (LOM) Ethernet Controller
-# ICH-6 Component
-       106b  82562G \t- PRO/100 VE Ethernet Controller Mobile
-       1075  82547GI Gigabit Ethernet Controller
-               1028 0165  PowerEdge 750
-               8086 0075  PRO/1000 CT Network Connection
-               8086 1075  PRO/1000 CT Network Connection
-       1076  82541GI/PI Gigabit Ethernet Controller
-               1028 0165  PowerEdge 750
-               8086 0076  PRO/1000 MT Network Connection
-               8086 1076  PRO/1000 MT Network Connection
-               8086 1176  PRO/1000 MT Desktop Adapter
-               8086 1276  PRO/1000 MT Desktop Adapter
-       1077  82541GI Gigabit Ethernet Controller
-               1179 0001  PRO/1000 MT Mobile Connection
-               8086 0077  PRO/1000 MT Mobile Connection
-               8086 1077  PRO/1000 MT Mobile Connection
-       1078  82541EI Gigabit Ethernet Controller
-               8086 1078  PRO/1000 MT Network Connection
-       1079  82546GB Gigabit Ethernet Controller
-               103c 12a6  HP Dual Port 1000Base-T [A9900A]
-               103c 12cf  HP Core Dual Port 1000Base-T [AB352A]
-               4c53 1090  Cx9 / Vx9 mainboard
-               4c53 10b0  CL9 mainboard
-               8086 0079  PRO/1000 MT Dual Port Network Connection
-               8086 1079  PRO/1000 MT Dual Port Network Connection
-               8086 1179  PRO/1000 MT Dual Port Network Connection
-               8086 117a  PRO/1000 MT Dual Port Server Adapter
-       107a  82546GB Gigabit Ethernet Controller
-               103c 12a8  HP Dual Port 1000base-SX [A9899A]
-               8086 107a  PRO/1000 MF Dual Port Server Adapter
-               8086 127a  PRO/1000 MF Dual Port Server Adapter
-       107b  82546GB Gigabit Ethernet Controller
-               8086 007b  PRO/1000 MB Dual Port Server Connection
-               8086 107b  PRO/1000 MB Dual Port Server Connection
-       1107  PRO/1000 MF Server Adapter (LX)
-       1130  82815 815 Chipset Host Bridge and Memory Controller Hub
-               1025 1016  Travelmate 612 TX
-               1043 8027  TUSL2-C Mainboard
-               104d 80df  Vaio PCG-FX403
-               8086 4532  D815EEA2 mainboard
-               8086 4557  D815EGEW Mainboard
-       1131  82815 815 Chipset AGP Bridge
-       1132  82815 CGC [Chipset Graphics Controller]
-               1025 1016  Travelmate 612 TX
-               104d 80df  Vaio PCG-FX403
-               8086 4532  D815EEA2 Mainboard
-               8086 4557  D815EGEW Mainboard
-       1161  82806AA PCI64 Hub Advanced Programmable Interrupt Controller
-               8086 1161  82806AA PCI64 Hub APIC
-       1162  Xscale 80200 Big Endian Companion Chip
-       1200  Intel IXP1200 Network Processor
-               172a 0000  AEP SSL Accelerator
-       1209  8255xER/82551IT Fast Ethernet Controller
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-               4c53 1070  PC6 mainboard
-       1221  82092AA PCI to PCMCIA Bridge
-       1222  82092AA IDE Controller
-       1223  SAA7116
-       1225  82452KX/GX [Orion]
-       1226  82596 PRO/10 PCI
-       1227  82865 EtherExpress PRO/100A
-       1228  82556 EtherExpress PRO/100 Smart
-# the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER)
-       1229  82557/8/9 [Ethernet Pro 100]
-               0e11 3001  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 3002  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 3003  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 3004  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 3005  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 3006  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 3007  82559 Fast Ethernet LOM with Alert on LAN*
-               0e11 b01e  NC3120 Fast Ethernet NIC
-               0e11 b01f  NC3122 Fast Ethernet NIC (dual port)
-               0e11 b02f  NC1120 Ethernet NIC
-               0e11 b04a  Netelligent 10/100TX NIC with Wake on LAN
-               0e11 b0c6  NC3161 Fast Ethernet NIC (embedded, WOL)
-               0e11 b0c7  NC3160 Fast Ethernet NIC (embedded)
-               0e11 b0d7  NC3121 Fast Ethernet NIC (WOL)
-               0e11 b0dd  NC3131 Fast Ethernet NIC (dual port)
-               0e11 b0de  NC3132 Fast Ethernet Module (dual port)
-               0e11 b0e1  NC3133 Fast Ethernet Module (100-FX)
-               0e11 b134  NC3163 Fast Ethernet NIC (embedded, WOL)
-               0e11 b13c  NC3162 Fast Ethernet NIC (embedded)
-               0e11 b144  NC3123 Fast Ethernet NIC (WOL)
-               0e11 b163  NC3134 Fast Ethernet NIC (dual port)
-               0e11 b164  NC3135 Fast Ethernet Upgrade Module (dual port)
-               0e11 b1a4  NC7131 Gigabit Server Adapter
-               1014 005c  82558B Ethernet Pro 10/100
-               1014 01bc  82559 Fast Ethernet LAN On Motherboard
-               1014 01f1  10/100 Ethernet Server Adapter
-               1014 01f2  10/100 Ethernet Server Adapter
-               1014 0207  Ethernet Pro/100 S
-               1014 0232  10/100 Dual Port Server Adapter
-               1014 023a  ThinkPad R30
-               1014 105c  Netfinity 10/100
-               1014 2205  ThinkPad A22p
-               1014 305c  10/100 EtherJet Management Adapter
-               1014 405c  10/100 EtherJet Adapter with Alert on LAN
-               1014 505c  10/100 EtherJet Secure Management Adapter
-               1014 605c  10/100 EtherJet Secure Management Adapter
-               1014 705c  10/100 Netfinity 10/100 Ethernet Security Adapter
-               1014 805c  10/100 Netfinity 10/100 Ethernet Security Adapter
-               1028 009b  PowerEdge 2500/2550
-               1028 00ce  PowerEdge 1400
-               1033 8000  PC-9821X-B06
-               1033 8016  PK-UG-X006
-               1033 801f  PK-UG-X006
-               1033 8026  PK-UG-X006
-               1033 8063  82559-based Fast Ethernet Adapter
-               1033 8064  82559-based Fast Ethernet Adapter
-               103c 10c0  NetServer 10/100TX
-               103c 10c3  NetServer 10/100TX
-               103c 10ca  NetServer 10/100TX
-               103c 10cb  NetServer 10/100TX
-               103c 10e3  NetServer 10/100TX
-               103c 10e4  NetServer 10/100TX
-               103c 1200  NetServer 10/100TX
-               10c3 1100  SmartEther100 SC1100
-               10cf 1115  8255x-based Ethernet Adapter (10/100)
-               10cf 1143  8255x-based Ethernet Adapter (10/100)
-               1179 0001  8255x-based Ethernet Adapter (10/100)
-               1179 0002  PCI FastEther LAN on Docker
-               1179 0003  8255x-based Fast Ethernet
-               1259 2560  AT-2560 100
-               1259 2561  AT-2560 100 FX Ethernet Adapter
-               1266 0001  NE10/100 Adapter
-               13e9 1000  6221L-4U
-               144d 2501  SEM-2000 MiniPCI LAN Adapter
-               144d 2502  SEM-2100IL MiniPCI LAN Adapter
-               1668 1100  EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
-               4c53 1080  CT8 mainboard
-               8086 0001  EtherExpress PRO/100B (TX)
-               8086 0002  EtherExpress PRO/100B (T4)
-               8086 0003  EtherExpress PRO/10+
-               8086 0004  EtherExpress PRO/100 WfM
-               8086 0005  82557 10/100
-               8086 0006  82557 10/100 with Wake on LAN
-               8086 0007  82558 10/100 Adapter
-               8086 0008  82558 10/100 with Wake on LAN
-               8086 0009  EtherExpress PRO/100+
-               8086 000a  EtherExpress PRO/100+ Management Adapter
-               8086 000b  EtherExpress PRO/100+
-               8086 000c  EtherExpress PRO/100+ Management Adapter
-               8086 000d  EtherExpress PRO/100+ Alert On LAN II* Adapter
-               8086 000e  EtherExpress PRO/100+ Management Adapter with Alert On LAN*
-               8086 000f  EtherExpress PRO/100 Desktop Adapter
-               8086 0010  EtherExpress PRO/100 S Management Adapter
-               8086 0011  EtherExpress PRO/100 S Management Adapter
-               8086 0012  EtherExpress PRO/100 S Advanced Management Adapter (D)
-               8086 0013  EtherExpress PRO/100 S Advanced Management Adapter (E)
-               8086 0030  EtherExpress PRO/100  Management Adapter with Alert On LAN* GC
-               8086 0031  EtherExpress PRO/100 Desktop Adapter
-               8086 0040  EtherExpress PRO/100 S Desktop Adapter
-               8086 0041  EtherExpress PRO/100 S Desktop Adapter
-               8086 0042  EtherExpress PRO/100 Desktop Adapter
-               8086 0050  EtherExpress PRO/100 S Desktop Adapter
-               8086 1009  EtherExpress PRO/100+ Server Adapter
-               8086 100c  EtherExpress PRO/100+ Server Adapter (PILA8470B)
-               8086 1012  EtherExpress PRO/100 S Server Adapter (D)
-               8086 1013  EtherExpress PRO/100 S Server Adapter (E)
-               8086 1015  EtherExpress PRO/100 S Dual Port Server Adapter
-               8086 1017  EtherExpress PRO/100+ Dual Port Server Adapter
-               8086 1030  EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
-               8086 1040  EtherExpress PRO/100 S Server Adapter
-               8086 1041  EtherExpress PRO/100 S Server Adapter
-               8086 1042  EtherExpress PRO/100 Server Adapter
-               8086 1050  EtherExpress PRO/100 S Server Adapter
-               8086 1051  EtherExpress PRO/100 Server Adapter
-               8086 1052  EtherExpress PRO/100 Server Adapter
-               8086 10f0  EtherExpress PRO/100+ Dual Port Adapter
-               8086 2009  EtherExpress PRO/100 S Mobile Adapter
-               8086 200d  EtherExpress PRO/100 Cardbus
-               8086 200e  EtherExpress PRO/100 LAN+V90 Cardbus Modem
-               8086 200f  EtherExpress PRO/100 SR Mobile Adapter
-               8086 2010  EtherExpress PRO/100 S Mobile Combo Adapter
-               8086 2013  EtherExpress PRO/100 SR Mobile Combo Adapter
-               8086 2016  EtherExpress PRO/100 S Mobile Adapter
-               8086 2017  EtherExpress PRO/100 S Combo Mobile Adapter
-               8086 2018  EtherExpress PRO/100 SR Mobile Adapter
-               8086 2019  EtherExpress PRO/100 SR Combo Mobile Adapter
-               8086 2101  EtherExpress PRO/100 P Mobile Adapter
-               8086 2102  EtherExpress PRO/100 SP Mobile Adapter
-               8086 2103  EtherExpress PRO/100 SP Mobile Adapter
-               8086 2104  EtherExpress PRO/100 SP Mobile Adapter
-               8086 2105  EtherExpress PRO/100 SP Mobile Adapter
-               8086 2106  EtherExpress PRO/100 P Mobile Adapter
-               8086 2107  EtherExpress PRO/100 Network Connection
-               8086 2108  EtherExpress PRO/100 Network Connection
-               8086 2200  EtherExpress PRO/100 P Mobile Combo Adapter
-               8086 2201  EtherExpress PRO/100 P Mobile Combo Adapter
-               8086 2202  EtherExpress PRO/100 SP Mobile Combo Adapter
-               8086 2203  EtherExpress PRO/100+ MiniPCI
-               8086 2204  EtherExpress PRO/100+ MiniPCI
-               8086 2205  EtherExpress PRO/100 SP Mobile Combo Adapter
-               8086 2206  EtherExpress PRO/100 SP Mobile Combo Adapter
-               8086 2207  EtherExpress PRO/100 SP Mobile Combo Adapter
-               8086 2208  EtherExpress PRO/100 P Mobile Combo Adapter
-               8086 2402  EtherExpress PRO/100+ MiniPCI
-               8086 2407  EtherExpress PRO/100+ MiniPCI
-               8086 2408  EtherExpress PRO/100+ MiniPCI
-               8086 2409  EtherExpress PRO/100+ MiniPCI
-               8086 240f  EtherExpress PRO/100+ MiniPCI
-               8086 2410  EtherExpress PRO/100+ MiniPCI
-               8086 2411  EtherExpress PRO/100+ MiniPCI
-               8086 2412  EtherExpress PRO/100+ MiniPCI
-               8086 2413  EtherExpress PRO/100+ MiniPCI
-               8086 3000  82559 Fast Ethernet LAN on Motherboard
-               8086 3001  82559 Fast Ethernet LOM with Basic Alert on LAN*
-               8086 3002  82559 Fast Ethernet LOM with Alert on LAN II*
-               8086 3006  EtherExpress PRO/100 S Network Connection
-               8086 3007  EtherExpress PRO/100 S Network Connection
-               8086 3008  EtherExpress PRO/100 Network Connection
-               8086 3010  EtherExpress PRO/100 S Network Connection
-               8086 3011  EtherExpress PRO/100 S Network Connection
-               8086 3012  EtherExpress PRO/100 Network Connection
-               8086 3411  SDS2 Mainboard
-       122d  430FX - 82437FX TSC [Triton I]
-       122e  82371FB PIIX ISA [Triton I]
-       1230  82371FB PIIX IDE [Triton I]
-       1231  DSVD Modem
-       1234  430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)
-       1235  430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP)
-       1237  440FX - 82441FX PMC [Natoma]
-       1239  82371FB PIIX IDE Interface
-       123b  82380PB PCI to PCI Docking Bridge
-       123c  82380AB (MISA) Mobile PCI-to-ISA Bridge
-       123d  683053 Programmable Interrupt Device
-# in" hidden" mode
-       123e  82466GX (IHPC) Integrated Hot-Plug Controller
-       123f  82466GX Integrated Hot-Plug Controller (IHPC)
-       1240  82752 (752) AGP Graphics Accelerator
-       124b  82380FB (MPCI2) Mobile Docking Controller
-       1250  430HX - 82439HX TXC [Triton II]
-       1360  82806AA PCI64 Hub PCI Bridge
-       1361  82806AA PCI64 Hub Controller (HRes)
-               8086 1361  82806AA PCI64 Hub Controller (HRes)
-               8086 8000  82806AA PCI64 Hub Controller (HRes)
-       1460  82870P2 P64H2 Hub PCI Bridge
-       1461  82870P2 P64H2 I/OxAPIC
-               15d9 3480  P4DP6
-               4c53 1090  Cx9 / Vx9 mainboard
-       1462  82870P2 P64H2 Hot Plug Controller
-       1960  80960RP [i960RP Microprocessor]
-               101e 0431  MegaRAID 431 RAID Controller
-               101e 0438  MegaRAID 438 Ultra2 LVD RAID Controller
-               101e 0466  MegaRAID 466 Express Plus RAID Controller
-               101e 0467  MegaRAID 467 Enterprise 1500 RAID Controller
-               101e 0490  MegaRAID 490 Express 300 RAID Controller
-               101e 0762  MegaRAID 762 Express RAID Controller
-               101e 09a0  PowerEdge Expandable RAID Controller 2/SC
-               1028 0467  PowerEdge Expandable RAID Controller 2/DC
-               1028 1111  PowerEdge Expandable RAID Controller 2/SC
-               103c 03a2  MegaRAID
-               103c 10c6  MegaRAID 438, HP NetRAID-3Si
-               103c 10c7  MegaRAID T5, Integrated HP NetRAID
-               103c 10cc  MegaRAID, Integrated HP NetRAID
-               103c 10cd  HP NetRAID-1Si
-               105a 0000  SuperTrak
-               105a 2168  SuperTrak Pro
-               105a 5168  SuperTrak66/100
-               1111 1111  MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
-               1111 1112  PowerEdge Expandable RAID Controller 2/SC
-               113c 03a2  MegaRAID
-               e4bf 1010  CG1-RADIO
-               e4bf 1020  CU2-QUARTET
-               e4bf 1040  CU1-CHORUS
-               e4bf 3100  CX1-BAND
-       1962  80960RM [i960RM Microprocessor]
-               105a 0000  SuperTrak SX6000 I2O CPU
-       1a21  82840 840 (Carmel) Chipset Host Bridge (Hub A)
-       1a23  82840 840 (Carmel) Chipset AGP Bridge
-       1a24  82840 840 (Carmel) Chipset PCI Bridge (Hub B)
-       1a30  82845 845 (Brookdale) Chipset Host Bridge
-               1028 010e  Optiplex GX240
-       1a31  82845 845 (Brookdale) Chipset AGP Bridge
-       2410  82801AA ISA Bridge (LPC)
-       2411  82801AA IDE
-       2412  82801AA USB
-       2413  82801AA SMBus
-       2415  82801AA AC'97 Audio
-               1028 0095  Precision Workstation 220 Integrated Digital Audio
-               11d4 0040  SoundMAX Integrated Digital Audio
-               11d4 0048  SoundMAX Integrated Digital Audio
-               11d4 5340  SoundMAX Integrated Digital Audio
-       2416  82801AA AC'97 Modem
-       2418  82801AA PCI Bridge
-       2420  82801AB ISA Bridge (LPC)
-       2421  82801AB IDE
-       2422  82801AB USB
-       2423  82801AB SMBus
-       2425  82801AB AC'97 Audio
-               11d4 0040  SoundMAX Integrated Digital Audio
-               11d4 0048  SoundMAX Integrated Digital Audio
-       2426  82801AB AC'97 Modem
-       2428  82801AB PCI Bridge
-       2440  82801BA ISA Bridge (LPC)
-       2442  82801BA/BAM USB (Hub #1)
-               1014 01c6  Netvista A40/A40p
-               1025 1016  Travelmate 612 TX
-               1028 010e  Optiplex GX240
-               1043 8027  TUSL2-C Mainboard
-               104d 80df  Vaio PCG-FX403
-               147b 0507  TH7II-RAID
-               8086 4532  D815EEA2 mainboard
-               8086 4557  D815EGEW Mainboard
-       2443  82801BA/BAM SMBus
-               1014 01c6  Netvista A40/A40p
-               1025 1016  Travelmate 612 TX
-               1028 010e  Optiplex GX240
-               1043 8027  TUSL2-C Mainboard
-               104d 80df  Vaio PCG-FX403
-               147b 0507  TH7II-RAID
-               8086 4532  D815EEA2 mainboard
-               8086 4557  D815EGEW Mainboard
-       2444  82801BA/BAM USB (Hub #2)
-               1025 1016  Travelmate 612 TX
-               1028 010e  Optiplex GX240
-               1043 8027  TUSL2-C Mainboard
-               104d 80df  Vaio PCG-FX403
-               147b 0507  TH7II-RAID
-               8086 4532  D815EEA2 mainboard
-       2445  82801BA/BAM AC'97 Audio
-               1014 01c6  Netvista A40/A40p
-               1025 1016  Travelmate 612 TX
-               104d 80df  Vaio PCG-FX403
-               1462 3370  STAC9721 AC
-               147b 0507  TH7II-RAID
-               8086 4557  D815EGEW Mainboard
-       2446  82801BA/BAM AC'97 Modem
-               1025 1016  Travelmate 612 TX
-               104d 80df  Vaio PCG-FX403
-       2448  82801 Mobile PCI Bridge
-       2449  82801BA/BAM/CA/CAM Ethernet Controller
-               0e11 0012  EtherExpress PRO/100 VM
-               0e11 0091  EtherExpress PRO/100 VE
-               1014 01ce  EtherExpress PRO/100 VE
-               1014 01dc  EtherExpress PRO/100 VE
-               1014 01eb  EtherExpress PRO/100 VE
-               1014 01ec  EtherExpress PRO/100 VE
-               1014 0202  EtherExpress PRO/100 VE
-               1014 0205  EtherExpress PRO/100 VE
-               1014 0217  EtherExpress PRO/100 VE
-               1014 0234  EtherExpress PRO/100 VE
-               1014 023d  EtherExpress PRO/100 VE
-               1014 0244  EtherExpress PRO/100 VE
-               1014 0245  EtherExpress PRO/100 VE
-               1014 0265  PRO/100 VE Desktop Connection
-               1014 0267  PRO/100 VE Desktop Connection
-               1014 026a  PRO/100 VE Desktop Connection
-               109f 315d  EtherExpress PRO/100 VE
-               109f 3181  EtherExpress PRO/100 VE
-               1179 ff01  PRO/100 VE Network Connection
-               1186 7801  EtherExpress PRO/100 VE
-               144d 2602  HomePNA 1M CNR
-               8086 3010  EtherExpress PRO/100 VE
-               8086 3011  EtherExpress PRO/100 VM
-               8086 3012  82562EH based Phoneline
-               8086 3013  EtherExpress PRO/100 VE
-               8086 3014  EtherExpress PRO/100 VM
-               8086 3015  82562EH based Phoneline
-               8086 3016  EtherExpress PRO/100 P Mobile Combo
-               8086 3017  EtherExpress PRO/100 P Mobile
-               8086 3018  EtherExpress PRO/100
-       244a  82801BAM IDE U100
-               1025 1016  Travelmate 612TX
-               104d 80df  Vaio PCG-FX403
-       244b  82801BA IDE U100
-               1014 01c6  Netvista A40/A40p
-               1028 010e  Optiplex GX240
-               1043 8027  TUSL2-C Mainboard
-               147b 0507  TH7II-RAID
-               8086 4532  D815EEA2 mainboard
-               8086 4557  D815EGEW Mainboard
-       244c  82801BAM ISA Bridge (LPC)
-       244e  82801 PCI Bridge
-               1014 0267  NetVista A30p
-       2450  82801E ISA Bridge (LPC)
-       2452  82801E USB
-       2453  82801E SMBus
-       2459  82801E Ethernet Controller 0
-       245b  82801E IDE U100
-       245d  82801E Ethernet Controller 1
-       245e  82801E PCI Bridge
-       2480  82801CA LPC Interface Controller
-       2482  82801CA/CAM USB (Hub #1)
-               1014 0220  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               15d9 3480  P4DP6
-               8086 1958  vpr Matrix 170B4
-               8086 3424  SE7501HG2 Mainboard
-               8086 4541  Latitude C640
-       2483  82801CA/CAM SMBus Controller
-               1014 0220  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               15d9 3480  P4DP6
-               8086 1958  vpr Matrix 170B4
-       2484  82801CA/CAM USB (Hub #2)
-               1014 0220  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               15d9 3480  P4DP6
-               8086 1958  vpr Matrix 170B4
-       2485  82801CA/CAM AC'97 Audio Controller
-               1013 5959  Crystal WMD Audio Codec
-               1014 0222  ThinkPad T23 (2647-4MG) or A30/A30p (2652/2653)
-               1014 0508  ThinkPad T30
-               1014 051c  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               144d c006  vpr Matrix 170B4
-       2486  82801CA/CAM AC'97 Modem Controller
-               1014 0223  ThinkPad A/T/X Series
-               1014 0503  ThinkPad R31 2656BBG
-               1014 051a  ThinkPad A/T/X Series
-               101f 1025  Acer 620 Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               1179 0001  Toshiba Satellite 1110 Z15 internal Modem
-               134d 4c21  Dell Inspiron 2100 internal modem
-               144d 2115  vpr Matrix 170B4 internal modem
-               14f1 5421  MD56ORD V.92 MDC Modem
-       2487  82801CA/CAM USB (Hub #3)
-               1014 0220  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               15d9 3480  P4DP6
-               8086 1958  vpr Matrix 170B4
-       248a  82801CAM IDE U100
-               1014 0220  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-               8086 1958  vpr Matrix 170B4
-               8086 4541  Latitude C640
-       248b  82801CA Ultra ATA Storage Controller
-               15d9 3480  P4DP6
-       248c  82801CAM ISA Bridge (LPC)
-       24c0  82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
-               1014 0267  NetVista A30p
-               1462 5800  845PE Max (MS-6580)
-       24c1  82801DBL (ICH4-L) IDE Controller
-       24c2  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
-               1014 0267  NetVista A30p
-               1025 005a  TravelMate 290
-               1028 0126  Optiplex GX260
-               1028 0163  Latitude D505
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-               1462 5800  845PE Max (MS-6580)
-               1509 2990  Averatec 5110H laptop
-               4c53 1090  Cx9 / Vx9 mainboard
-       24c3  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
-               1014 0267  NetVista A30p
-               1025 005a  TravelMate 290
-               1028 0126  Optiplex GX260
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-               1458 24c2  GA-8PE667 Ultra
-               1462 5800  845PE Max (MS-6580)
-               4c53 1090  Cx9 / Vx9 mainboard
-       24c4  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
-               1014 0267  NetVista A30p
-               1025 005a  TravelMate 290
-               1028 0126  Optiplex GX260
-               1028 0163  Latitude D505
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-               1462 5800  845PE Max (MS-6580)
-               1509 2990  Averatec 5110H
-               4c53 1090  Cx9 / Vx9 mainboard
-       24c5  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
-               0e11 00b8  Analog Devices Inc. codec [SoundMAX]
-               1014 0267  NetVista A30p
-               1025 005a  TravelMate 290
-               1028 0163  Latitude D505
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-               1458 a002  GA-8PE667 Ultra
-               1462 5800  845PE Max (MS-6580)
-       24c6  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
-               1025 005a  TravelMate 290
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-       24c7  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
-               1014 0267  NetVista A30p
-               1025 005a  TravelMate 290
-               1028 0126  Optiplex GX260
-               1028 0163  Latitude D505
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-               1462 5800  845PE Max (MS-6580)
-               1509 2990  Averatec 5110H
-               4c53 1090  Cx9 / Vx9 mainboard
-       24ca  82801DBM (ICH4-M) IDE Controller
-               1025 005a  TravelMate 290
-               1028 0163  Latitude D505
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-       24cb  82801DB (ICH4) IDE Controller
-               1014 0267  NetVista A30p
-               1028 0126  Optiplex GX260
-               1458 24c2  GA-8PE667 Ultra
-               1462 5800  845PE Max (MS-6580)
-               4c53 1090  Cx9 / Vx9 mainboard
-       24cc  82801DBM (ICH4-M) LPC Interface Bridge
-       24cd  82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
-               1014 0267  NetVista A30p
-               1025 005a  TravelMate 290
-               1028 0126  Optiplex GX260
-               1028 0163  Latitude D505
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-               1071 8160  MIM2000
-               1462 3981  845PE Max (MS-6580)
-               1509 1968  Averatec 5110H
-               4c53 1090  Cx9 / Vx9 mainboard
-       24d0  82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
-       24d1  82801EB (ICH5) SATA Controller
-               103c 12bc  d530 CMT (DG746A)
-               1458 24d1  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24d2  82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
-               1028 0183  PowerEdge 1800
-               103c 12bc  d530 CMT (DG746A)
-               1043 80a6  P4P800 Mainboard
-               1458 24d2  GA-8IPE1000/8KNXP motherboard
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24d3  82801EB/ER (ICH5/ICH5R) SMBus Controller
-               1043 80a6  P4P800 Mainboard
-               1458 24d2  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24d4  82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
-               1028 0183  PowerEdge 1800
-               103c 12bc  d530 CMT (DG746A)
-               1043 80a6  P4P800 Mainboard
-               1458 24d2  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24d5  82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
-               103c 12bc  Analog Devices codec [SoundMAX Integrated Digital Audio]
-               1043 80f3  P4P800 Mainboard
-# Again, I suppose they use the same in different subsystems
-               1458 a002  GA-8IPE1000/8KNXP motherboard
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 a000  D865PERL mainboard
-               8086 e000  D865PERL mainboard
-       24d6  82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
-       24d7  82801EB/ER (ICH5/ICH5R) USB UHCI #3
-               1028 0183  PowerEdge 1800
-               103c 12bc  d530 CMT (DG746A)
-               1043 80a6  P4P800 Mainboard
-               1458 24d2  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24db  82801EB/ER (ICH5/ICH5R) IDE Controller
-               103c 12bc  d530 CMT (DG746A)
-               1043 80a6  P4P800 Mainboard
-               1458 24d2  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               1462 7580  MSI 875P
-               8086 24db  P4C800 Mainboard
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24dc  82801EB (ICH5) LPC Interface Bridge
-       24dd  82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
-               1028 0183  PowerEdge 1800
-               103c 12bc  d530 CMT (DG746A)
-               1043 80a6  P4P800 Mainboard
-               1458 5006  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24de  82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
-               1043 80a6  P4P800 Mainboard
-               1458 24d2  GA-8IPE1000 Pro2 motherboard (865PE)
-               1462 7280  865PE Neo2 (MS-6728)
-               8086 3427  S875WP1-E mainboard
-               8086 524c  D865PERL mainboard
-       24df  82801ER (ICH5R) SATA Controller
-       2500  82820 820 (Camino) Chipset Host Bridge (MCH)
-               1028 0095  Precision Workstation 220 Chipset
-               1043 801c  P3C-2000 system chipset
-       2501  82820 820 (Camino) Chipset Host Bridge (MCH)
-               1043 801c  P3C-2000 system chipset
-       250b  82820 820 (Camino) Chipset Host Bridge
-       250f  82820 820 (Camino) Chipset AGP Bridge
-       2520  82805AA MTH Memory Translator Hub
-       2521  82804AA MRH-S Memory Repeater Hub for SDRAM
-       2530  82850 850 (Tehama) Chipset Host Bridge (MCH)
-               147b 0507  TH7II-RAID
-       2531  82860 860 (Wombat) Chipset Host Bridge (MCH)
-       2532  82850 850 (Tehama) Chipset AGP Bridge
-       2533  82860 860 (Wombat) Chipset AGP Bridge
-       2534  82860 860 (Wombat) Chipset PCI Bridge
-       2540  E7500 Memory Controller Hub
-               15d9 3480  P4DP6
-       2541  E7500/E7501 Host RASUM Controller
-               15d9 3480  P4DP6
-               4c53 1090  Cx9 / Vx9 mainboard
-               8086 3424  SE7501HG2 Mainboard
-       2543  E7500/E7501 Hub Interface B PCI-to-PCI Bridge
-       2544  E7500/E7501 Hub Interface B RASUM Controller
-               4c53 1090  Cx9 / Vx9 mainboard
-       2545  E7500/E7501 Hub Interface C PCI-to-PCI Bridge
-       2546  E7500/E7501 Hub Interface C RASUM Controller
-       2547  E7500/E7501 Hub Interface D PCI-to-PCI Bridge
-       2548  E7500/E7501 Hub Interface D RASUM Controller
-       254c  E7501 Memory Controller Hub
-               4c53 1090  Cx9 / Vx9 mainboard
-               8086 3424  SE7501HG2 Mainboard
-       2550  E7505 Memory Controller Hub
-       2551  E7505/E7205 Series RAS Controller
-       2552  E7505/E7205 PCI-to-AGP Bridge
-       2553  E7505 Hub Interface B PCI-to-PCI Bridge
-       2554  E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller
-       255d  E7205 Memory Controller Hub
-       2560  82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
-               1028 0126  Optiplex GX260
-               1458 2560  GA-8PE667 Ultra
-               1462 5800  845PE Max (MS-6580)
-       2561  82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
-       2562  82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
-               1014 0267  NetVista A30p
-       2570  82865G/PE/P DRAM Controller/Host-Hub Interface
-               1043 80f2  P4P800 Mainboard
-               1458 2570  GA-8IPE1000 Pro2 motherboard (865PE)
-       2571  82865G/PE/P PCI to AGP Controller
-       2572  82865G Integrated Graphics Controller
-       2573  82865G/PE/P PCI to CSA Bridge
-       2576  82865G/PE/P Processor to I/O Memory Interface
-       2578  82875P/E7210 Memory Controller Hub
-               1458 2578  GA-8KNXP motherboard (875P)
-               1462 7580  MS-6758 (875P Neo)
-# Motherboard P4SCE
-               15d9 4580  Super Micro Computer Inc. P4SCE
-       2579  82875P Processor to AGP Controller
-       257b  82875P/E7210 Processor to PCI to CSA Bridge
-       257e  82875P/E7210 Processor to I/O Memory Interface
-       2580  915G/P/GV/GL/PL/910GL Processor to I/O Controller
-       2581  915G/P/GV/GL/PL/910GL PCI Express Root Port
-       2582  82915G/GV/910GL Express Chipset Family Graphics Controller
-               1028 1079  Optiplex GX280
-       2584  925X/XE Memory Controller Hub
-       2585  925X/XE PCI Express Root Port
-       2588  E7220/E7221 Memory Controller Hub
-       2589  E7220/E7221 PCI Express Root Port
-       258a  E7221 Integrated Graphics Controller
-       2590  Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
-       2591  Mobile 915GM/PM Express PCI Express Root Port
-       2592  Mobile 915GM/GMS/910GML Express Graphics Controller
-       25a1  6300ESB LPC Interface Controller
-       25a2  6300ESB PATA Storage Controller
-               4c53 10b0  CL9 mainboard
-       25a3  6300ESB SATA Storage Controller
-               4c53 10b0  CL9 mainboard
-       25a4  6300ESB SMBus Controller
-               4c53 10b0  CL9 mainboard
-       25a6  6300ESB AC'97 Audio Controller
-               4c53 10b0  CL9 mainboard
-       25a7  6300ESB AC'97 Modem Controller
-       25a9  6300ESB USB Universal Host Controller
-               4c53 10b0  CL9 mainboard
-       25aa  6300ESB USB Universal Host Controller
-               4c53 10b0  CL9 mainboard
-       25ab  6300ESB Watchdog Timer
-               4c53 10b0  CL9 mainboard
-       25ac  6300ESB I/O Advanced Programmable Interrupt Controller
-               4c53 10b0  CL9 mainboard
-       25ad  6300ESB USB2 Enhanced Host Controller
-       25ae  6300ESB 64-bit PCI-X Bridge
-       25b0  6300ESB SATA RAID Controller
-       2600  E8500 Hub Interface
-       2601  E8500 PCI Express x4 Port D
-       2602  E8500 PCI Express x4 Port C0
-       2603  E8500 PCI Express x4 Port C1
-       2604  E8500 PCI Express x4 Port B0
-       2605  E8500 PCI Express x4 Port B1
-       2606  E8500 PCI Express x4 Port A0
-       2607  E8500 PCI Express x4 Port A1
-       2608  E8500 PCI Express x8 Port C
-       2609  E8500 PCI Express x8 Port B
-       260a  E8500 PCI Express x8 Port A
-       260c  E8500 IMI Registers
-       2610  E8500 System Bus, Boot, and Interrupt Registers
-       2611  E8500 Address Mapping Registers
-       2612  E8500 RAS Registers
-       2613  E8500 Reserved Registers
-       2614  E8500 Reserved Registers
-       2615  E8500 Miscellaneous Registers
-       2617  E8500 Reserved Registers
-       2618  E8500 Reserved Registers
-       2619  E8500 Reserved Registers
-       261a  E8500 Reserved Registers
-       261b  E8500 Reserved Registers
-       261c  E8500 Reserved Registers
-       261d  E8500 Reserved Registers
-       261e  E8500 Reserved Registers
-       2620  E8500 eXternal Memory Bridge
-       2621  E8500 XMB Miscellaneous Registers
-       2622  E8500 XMB Memory Interleaving Registers
-       2623  E8500 XMB DDR Initialization and Calibration
-       2624  E8500 XMB Reserved Registers
-       2625  E8500 XMB Reserved Registers
-       2626  E8500 XMB Reserved Registers
-       2627  E8500 XMB Reserved Registers
-       2640  82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
-       2641  82801FBM (ICH6M) LPC Interface Bridge
-       2642  82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
-       2651  82801FB/FW (ICH6/ICH6W) SATA Controller
-               1028 0179  Optiplex GX280
-       2652  82801FR/FRW (ICH6R/ICH6RW) SATA Controller
-       2653  82801FBM (ICH6M) SATA Controller
-       2658  82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
-               1028 0179  Optiplex GX280
-       2659  82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
-               1028 0179  Optiplex GX280
-       265a  82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
-               1028 0179  Optiplex GX280
-       265b  82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
-               1028 0179  Optiplex GX280
-       265c  82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
-               1028 0179  Optiplex GX280
-       2660  82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
-       2662  82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
-       2664  82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
-       2666  82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
-       2668  82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
-       266a  82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
-               1028 0179  Optiplex GX280
-       266c  82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
-       266d  82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
-       266e  82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
-               1028 0179  Optiplex GX280
-       266f  82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
-       2770  Memory Controller Hub
-       2771  PCI Express Graphics Port
-       2772  Integrated Graphics Controller
-       2774  Workstation Memory Controller Hub
-       2775  PCI Express Graphics Port
-       2776  Integrated Graphics Controller
-       2778  Server Memory Controller Hub
-       2779  PCI Express Root Port
-       2782  82915G Express Chipset Family Graphics Controller
-       2792  Mobile 915GM/GMS/910GML Express Graphics Controller
-       27b8  I/O Controller Hub LPC
-       27b9  Mobile I/O Controller Hub LPC
-       27c0  I/O Controller Hub SATA cc=IDE
-       27c1  I/O Controller Hub SATA cc=AHCI
-       27c3  I/O Controller Hub SATA cc=RAID
-       27c4  Mobile I/O Controller Hub SATA cc=IDE
-       27c5  Mobile I/O Controller Hub SATA cc=AHCI
-       27c8  I/O Controller Hub UHCI USB #1
-       27c9  I/O Controller Hub UHCI USB #2
-       27ca  I/O Controller Hub UHCI USB #3
-       27cb  I/O Controller Hub UHCI USB #4
-       27cc  I/O Controller Hub EHCI USB
-       27d0  I/O Controller Hub PCI Express Port 1
-       27d2  I/O Controller Hub PCI Express Port 2
-       27d4  I/O Controller Hub PCI Express Port 3
-       27d6  I/O Controller Hub PCI Express Port 4
-       27d8  I/O Controller Hub High Definition Audio
-       27da  I/O Controller Hub SMBus
-       27dc  I/O Controller Hub LAN
-       27dd  I/O Controller Hub AC'97 Modem
-       27de  I/O Controller Hub AC'97 Audio
-       27df  I/O Controller Hub PATA
-       27e0  I/O Controller Hub PCI Express Port 5
-       27e2  I/O Controller Hub PCI Express Port 6
-       3092  Integrated RAID
-       3200  GD31244 PCI-X SATA HBA
-       3340  82855PM Processor to I/O Controller
-               1025 005a  TravelMate 290
-               103c 088c  nc8000 laptop
-               103c 0890  nc6000 laptop
-       3341  82855PM Processor to AGP Controller
-       3575  82830 830 Chipset Host Bridge
-               1014 021d  ThinkPad A/T/X Series
-               104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-       3576  82830 830 Chipset AGP Bridge
-       3577  82830 CGC [Chipset Graphics Controller]
-               1014 0513  ThinkPad A/T/X Series
-       3578  82830 830 Chipset Host Bridge
-       3580  82852/82855 GM/GME/PM/GMV Processor to I/O Controller
-               1028 0163  Latitude D505
-               4c53 10b0  CL9 mainboard
-       3581  82852/82855 GM/GME/PM/GMV Processor to AGP Controller
-       3582  82852/855GM Integrated Graphics Device
-               1028 0163  Latitude D505
-               4c53 10b0  CL9 mainboard
-       3584  82852/82855 GM/GME/PM/GMV Processor to I/O Controller
-               1028 0163  Latitude D505
-               4c53 10b0  CL9 mainboard
-       3585  82852/82855 GM/GME/PM/GMV Processor to I/O Controller
-               1028 0163  Latitude D505
-               4c53 10b0  CL9 mainboard
-       3590  E7520 Memory Controller Hub
-       3591  E7525/E7520 Error Reporting Registers
-       3592  E7320 Memory Controller Hub
-       3593  E7320 Error Reporting Registers
-       3594  E7520 DMA Controller
-       3595  E7525/E7520/E7320 PCI Express Port A
-       3596  E7525/E7520/E7320 PCI Express Port A1
-       3597  E7525/E7520 PCI Express Port B
-       3598  E7520 PCI Express Port B1
-       3599  E7520 PCI Express Port C
-       359a  E7520 PCI Express Port C1
-       359b  E7525/E7520/E7320 Extended Configuration Registers
-       359e  E7525 Memory Controller Hub
-       4220  PRO/Wireless 2200BG
-       4223  PRO/Wireless 2915ABG MiniPCI Adapter
-       5200  EtherExpress PRO/100 Intelligent Server
-       5201  EtherExpress PRO/100 Intelligent Server
-               8086 0001  EtherExpress PRO/100 Server Ethernet Adapter
-       530d  80310 IOP [IO Processor]
-       7000  82371SB PIIX3 ISA [Natoma/Triton II]
-       7010  82371SB PIIX3 IDE [Natoma/Triton II]
-       7020  82371SB PIIX3 USB [Natoma/Triton II]
-       7030  430VX - 82437VX TVX [Triton VX]
-       7050  Intel Intercast Video Capture Card
-       7100  430TX - 82439TX MTXC
-       7110  82371AB/EB/MB PIIX4 ISA
-               15ad 1976  virtualHW v3
-       7111  82371AB/EB/MB PIIX4 IDE
-               15ad 1976  virtualHW v3
-       7112  82371AB/EB/MB PIIX4 USB
-               15ad 1976  virtualHW v3
-       7113  82371AB/EB/MB PIIX4 ACPI
-               15ad 1976  virtualHW v3
-       7120  82810 GMCH [Graphics Memory Controller Hub]
-               4c53 1040  CL7 mainboard
-               4c53 1060  PC7 mainboard
-       7121  82810 CGC [Chipset Graphics Controller]
-               4c53 1040  CL7 mainboard
-               4c53 1060  PC7 mainboard
-               8086 4341  Cayman (CA810) Mainboard
-       7122  82810 DC-100 GMCH [Graphics Memory Controller Hub]
-       7123  82810 DC-100 CGC [Chipset Graphics Controller]
-       7124  82810E DC-133 GMCH [Graphics Memory Controller Hub]
-       7125  82810E DC-133 CGC [Chipset Graphics Controller]
-       7126  82810 DC-133 System and Graphics Controller
-       7128  82810-M DC-100 System and Graphics Controller
-       712a  82810-M DC-133 System and Graphics Controller
-       7180  440LX/EX - 82443LX/EX Host bridge
-       7181  440LX/EX - 82443LX/EX AGP bridge
-       7190  440BX/ZX/DX - 82443BX/ZX/DX Host bridge
-               0e11 0500  Armada 1750 Laptop System Chipset
-               0e11 b110  Armada M700/E500
-               1179 0001  Toshiba Tecra 8100 Laptop System Chipset
-               15ad 1976  virtualHW v3
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-       7191  440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
-       7192  440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
-               0e11 0460  Armada 1700 Laptop System Chipset
-               4c53 1000  CC7/CR7/CP7/VC7/VP7/VR7 mainboard
-       7194  82440MX Host Bridge
-               1033 0000  Versa Note Vxi
-               4c53 10a0  CA3/CR3 mainboard
-       7195  82440MX AC'97 Audio Controller
-               1033 80cc  Versa Note VXi
-               10cf 1099  QSound_SigmaTel Stac97 PCI Audio
-               11d4 0040  SoundMAX Integrated Digital Audio
-               11d4 0048  SoundMAX Integrated Digital Audio
-       7196  82440MX AC'97 Modem Controller
-       7198  82440MX ISA Bridge
-       7199  82440MX EIDE Controller
-       719a  82440MX USB Universal Host Controller
-       719b  82440MX Power Management Controller
-       71a0  440GX - 82443GX Host bridge
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-       71a1  440GX - 82443GX AGP bridge
-       71a2  440GX - 82443GX Host bridge (AGP disabled)
-               4c53 1000  CC7/CR7/CP7/VC7/VP7/VR7 mainboard
-       7600  82372FB PIIX5 ISA
-       7601  82372FB PIIX5 IDE
-       7602  82372FB PIIX5 USB
-       7603  82372FB PIIX5 SMBus
-       7800  82740 (i740) AGP Graphics Accelerator
-               003d 0008  Starfighter AGP
-               003d 000b  Starfighter AGP
-               1092 0100  Stealth II G460
-               10b4 201a  Lightspeed 740
-               10b4 202f  Lightspeed 740
-               8086 0000  Terminator 2x/i
-               8086 0100  Intel740 Graphics Accelerator
-       84c4  450KX/GX [Orion] - 82454KX/GX PCI bridge
-       84c5  450KX/GX [Orion] - 82453KX/GX Memory controller
-       84ca  450NX - 82451NX Memory & I/O Controller
-       84cb  450NX - 82454NX/84460GX PCI Expander Bridge
-       84e0  460GX - 84460GX System Address Controller (SAC)
-       84e1  460GX - 84460GX System Data Controller (SDC)
-       84e2  460GX - 84460GX AGP Bridge (GXB function 2)
-       84e3  460GX - 84460GX Memory Address Controller (MAC)
-       84e4  460GX - 84460GX Memory Data Controller (MDC)
-       84e6  460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
-       84ea  460GX - 84460GX AGP Bridge (GXB function 1)
-       8500  IXP4XX - Intel Network Processor family. IXP420, IXP421, IXP422, IXP425 and IXC1100
-               1993 0dee  mGuard-PCI AV#1
-               1993 0def  mGuard-PCI AV#0
-       9000  IXP2000 Family Network Processor
-       9001  IXP2400 Network Processor
-       9004  IXP2800 Network Processor
-       9621  Integrated RAID
-       9622  Integrated RAID
-       9641  Integrated RAID
-       96a1  Integrated RAID
-# retail verson
-       a01f  PRO/10GbE LR Server Adapter
-# OEM version
-       a11f  PRO/10GbE LR Server Adapter
-       b152  21152 PCI-to-PCI Bridge
-# observed, and documented in Intel revision note; new mask of 1011:0026
-       b154  21154 PCI-to-PCI Bridge
-       b555  21555 Non transparent PCI-to-PCI Bridge
-               12d9 000a  PCI VoIP Gateway
-               4c53 1050  CT7 mainboard
-               4c53 1051  CE7 mainboard
-               e4bf 1000  CC8-1-BLUES
-       ffff  450NX/GX [Orion] - 82453KX/GX Memory controller [BUG]
-8401  TRENDware International Inc.
-8800  Trigem Computer Inc.
-       2008  Video assistent component
-8866  T-Square Design Inc.
-8888  Silicon Magic
-# 8c4a is not Winbond but there is a board misprogrammed
-8c4a  Winbond
-       1980  W89C940 misprogrammed [ne2k]
-8e0e  Computone Corporation
-8e2e  KTI
-       3000  ET32P2
-9004  Adaptec
-       0078  AHA-2940U_CN
-       1078  AIC-7810
-       1160  AIC-1160 [Family Fibre Channel Adapter]
-       2178  AIC-7821
-       3860  AHA-2930CU
-       3b78  AHA-4844W/4844UW
-       5075  AIC-755x
-       5078  AHA-7850
-               9004 7850  AHA-2904/Integrated AIC-7850
-       5175  AIC-755x
-       5178  AIC-7851
-       5275  AIC-755x
-       5278  AIC-7852
-       5375  AIC-755x
-       5378  AIC-7850
-       5475  AIC-755x
-       5478  AIC-7850
-       5575  AVA-2930
-       5578  AIC-7855
-       5647  ANA-7711 TCP Offload Engine
-               9004 7710  ANA-7711F TCP Offload Engine - Optical
-               9004 7711  ANA-7711LP TCP Offload Engine - Copper
-       5675  AIC-755x
-       5678  AIC-7856
-       5775  AIC-755x
-       5778  AIC-7850
-       5800  AIC-5800
-       5900  ANA-5910/5930/5940 ATM155 & 25 LAN Adapter
-       5905  ANA-5910A/5930A/5940A ATM Adapter
-       6038  AIC-3860
-       6075  AIC-1480 / APA-1480
-               9004 7560  AIC-1480 / APA-1480 Cardbus
-       6078  AIC-7860
-       6178  AIC-7861
-               9004 7861  AHA-2940AU Single
-       6278  AIC-7860
-       6378  AIC-7860
-       6478  AIC-786x
-       6578  AIC-786x
-       6678  AIC-786x
-       6778  AIC-786x
-       6915  ANA620xx/ANA69011A
-               9004 0008  ANA69011A/TX 10/100
-               9004 0009  ANA69011A/TX 10/100
-               9004 0010  ANA62022 2-port 10/100
-               9004 0018  ANA62044 4-port 10/100
-               9004 0019  ANA62044 4-port 10/100
-               9004 0020  ANA62022 2-port 10/100
-               9004 0028  ANA69011A/TX 10/100
-               9004 8008  ANA69011A/TX 64 bit 10/100
-               9004 8009  ANA69011A/TX 64 bit 10/100
-               9004 8010  ANA62022 2-port 64 bit 10/100
-               9004 8018  ANA62044 4-port 64 bit 10/100
-               9004 8019  ANA62044 4-port 64 bit 10/100
-               9004 8020  ANA62022 2-port 64 bit 10/100
-               9004 8028  ANA69011A/TX 64 bit 10/100
-       7078  AHA-294x / AIC-7870
-       7178  AHA-2940/2940W / AIC-7871
-       7278  AHA-3940/3940W / AIC-7872
-       7378  AHA-3985 / AIC-7873
-       7478  AHA-2944/2944W / AIC-7874
-       7578  AHA-3944/3944W / AIC-7875
-       7678  AHA-4944W/UW / AIC-7876
-       7710  ANA-7711F Network Accelerator Card (NAC) - Optical
-       7711  ANA-7711C Network Accelerator Card (NAC) - Copper
-       7778  AIC-787x
-       7810  AIC-7810
-       7815  AIC-7815 RAID+Memory Controller IC
-               9004 7815  ARO-1130U2 RAID Controller
-               9004 7840  AIC-7815 RAID+Memory Controller IC
-       7850  AIC-7850
-       7855  AHA-2930
-       7860  AIC-7860
-       7870  AIC-7870
-       7871  AHA-2940
-       7872  AHA-3940
-       7873  AHA-3980
-       7874  AHA-2944
-       7880  AIC-7880P
-       7890  AIC-7890
-       7891  AIC-789x
-       7892  AIC-789x
-       7893  AIC-789x
-       7894  AIC-789x
-       7895  AHA-2940U/UW / AHA-39xx / AIC-7895
-               9004 7890  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
-               9004 7891  AHA-2940U/2940UW Dual
-               9004 7892  AHA-3940AU/AUW/AUWD/UWD
-               9004 7894  AHA-3944AUWD
-               9004 7895  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
-               9004 7896  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
-               9004 7897  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
-       7896  AIC-789x
-       7897  AIC-789x
-       8078  AIC-7880U
-               9004 7880  AIC-7880P Ultra/Ultra Wide SCSI Chipset
-       8178  AHA-2940U/UW/D / AIC-7881U
-               9004 7881  AHA-2940UW SCSI Host Adapter
-       8278  AHA-3940U/UW/UWD / AIC-7882U
-       8378  AHA-3940U/UW / AIC-7883U
-       8478  AHA-2944UW / AIC-7884U
-       8578  AHA-3944U/UWD / AIC-7885
-       8678  AHA-4944UW / AIC-7886
-       8778  AHA-2940UW Pro / AIC-788x
-               9004 7887  2940UW Pro Ultra-Wide SCSI Controller
-       8878  AHA-2930UW / AIC-7888
-               9004 7888  AHA-2930UW SCSI Controller
-       8b78  ABA-1030
-       ec78  AHA-4944W/UW
-9005  Adaptec
-       0010  AHA-2940U2/U2W
-               9005 2180  AHA-2940U2 SCSI Controller
-               9005 8100  AHA-2940U2B SCSI Controller
-               9005 a100  AHA-2940U2B SCSI Controller
-               9005 a180  AHA-2940U2W SCSI Controller
-               9005 e100  AHA-2950U2B SCSI Controller
-       0011  AHA-2930U2
-       0013  78902
-               9005 0003  AAA-131U2 Array1000 1 Channel RAID Controller
-               9005 000f  AIC7890_ARO
-       001f  AHA-2940U2/U2W / 7890/7891
-               9005 000f  2940U2W SCSI Controller
-               9005 a180  2940U2W SCSI Controller
-       0020  AIC-7890
-       002f  AIC-7890
-       0030  AIC-7890
-       003f  AIC-7890
-       0050  AHA-3940U2x/395U2x
-               9005 f500  AHA-3950U2B
-               9005 ffff  AHA-3950U2B
-       0051  AHA-3950U2D
-               9005 b500  AHA-3950U2D
-       0053  AIC-7896 SCSI Controller
-               9005 ffff  AIC-7896 SCSI Controller mainboard implementation
-       005f  AIC-7896U2/7897U2
-       0080  AIC-7892A U160/m
-               0e11 e2a0  Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
-               9005 6220  AHA-29160C
-               9005 62a0  29160N Ultra160 SCSI Controller
-               9005 e220  29160LP Low Profile Ultra160 SCSI Controller
-               9005 e2a0  29160 Ultra160 SCSI Controller
-       0081  AIC-7892B U160/m
-               9005 62a1  19160 Ultra160 SCSI Controller
-       0083  AIC-7892D U160/m
-       008f  AIC-7892P U160/m
-               1179 0001  Magnia Z310
-               15d9 9005  Onboard SCSI Host Adapter
-       00c0  AHA-3960D / AIC-7899A U160/m
-               0e11 f620  Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
-               9005 f620  AHA-3960D U160/m
-       00c1  AIC-7899B U160/m
-       00c3  AIC-7899D U160/m
-       00c5  RAID subsystem HBA
-               1028 00c5  PowerEdge 2400,2500,2550,4400
-       00cf  AIC-7899P U160/m
-               1028 00ce  PowerEdge 1400
-               1028 00d1  PowerEdge 2550
-               1028 00d9  PowerEdge 2500
-               10f1 2462  Thunder K7 S2462
-               15d9 9005  Onboard SCSI Host Adapter
-               8086 3411  SDS2 Mainboard
-       0250  ServeRAID Controller
-               1014 0279  ServeRAID-xx
-               1014 028c  ServeRAID-xx
-# from kernel sources
-       0279  ServeRAID 6M
-       0283  AAC-RAID
-               9005 0283  Catapult
-       0284  AAC-RAID
-               9005 0284  Tomcat
-       0285  AAC-RAID
-               0e11 0295  SATA 6Ch (Bearcat)
-               1014 02f2  ServeRAID 8i
-               1028 0287  PowerEdge Expandable RAID Controller 320/DC
-               1028 0291  CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
-               103c 3227  AAR-2610SA
-               17aa 0286  Legend S220 (Legend Crusader)
-               17aa 0287  Legend S230 (Legend Vulcan)
-               9005 0285  2200S (Vulcan)
-               9005 0286  2120S (Crusader)
-               9005 0287  2200S (Vulcan-2m)
-               9005 0288  3230S (Harrier)
-               9005 0289  3240S (Tornado)
-               9005 028a  ASR-2020S PCI-X ZCR (Skyhawk)
-               9005 028b  ASR-2020S SO-DIMM PCI-X ZCR (Terminator)
-               9005 0290  AAR-2410SA PCI SATA 4ch (Jaguar II)
-               9005 0292  AAR-2810SA PCI SATA 8ch (Corsair-8)
-               9005 0293  AAR-21610SA PCI SATA 16ch (Corsair-16)
-               9005 0294  ESD SO-DIMM PCI-X SATA ZCR (Prowler)
-       0286  AAC-RAID (Rocket)
-               9005 028c  ASR-2230S + ASR-2230SLP PCI-X (Lancer)
-       0503  Scamp chipset SCSI controller
-               1014 02BF  Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
-       8000  ASC-29320A U320
-       800f  AIC-7901 U320
-       8010  ASC-39320 U320
-       8011  ASC-32320D U320
-               0e11 00ac  ASC-39320D U320
-               9005 0041  ASC-39320D U320
-       8012  ASC-29320 U320
-       8013  ASC-29320B U320
-       8014  ASC-29320LP U320
-       8015  ASC-39320B U320
-       8016  ASC-39320A U320
-       8017  ASC-29320ALP U320
-       801c  ASC-39320D U320
-       801d  AIC-7902B U320
-       801e  AIC-7901A U320
-       801f  AIC-7902 U320
-       8080  ASC-29320A U320 w/HostRAID
-       808f  AIC-7901 U320 w/HostRAID
-       8090  ASC-39320 U320 w/HostRAID
-       8091  ASC-39320D U320 w/HostRAID
-       8092  ASC-29320 U320 w/HostRAID
-       8093  ASC-29320B U320 w/HostRAID
-       8094  ASC-29320LP U320 w/HostRAID
-       8095  ASC-39320(B) U320 w/HostRAID
-       8096  ASC-39320A U320 w/HostRAID
-       8097  ASC-29320ALP U320 w/HostRAID
-       809c  ASC-39320D(B) U320 w/HostRAID
-       809d  AIC-7902(B) U320 w/HostRAID
-       809e  AIC-7901A U320 w/HostRAID
-       809f  AIC-7902 U320 w/HostRAID
-907f  Atronics
-       2015  IDE-2015PL
-919a  Gigapixel Corp
-9412  Holtek
-       6565  6565
-9699  Omni Media Technology Inc
-       6565  6565
-9710  NetMos Technology
-       7780  USB IRDA-port
-       9705  PCI 9705 Parallel Port
-       9715  PCI 9715 Dual Parallel Port
-       9735  PCI 9735 Multi-I/O Controller
-               1000 0002  0P2S (2 serial)
-               1000 0012  1P2S (1 parallel + 2 serial)
-       9745  PCI 9745 Multi-I/O Controller
-               1000 0002  0P2S (2 serial)
-               1000 0012  1P2S (1 parallel + 2 serial)
-       9755  PCI 9755 Parallel Port and ISA Bridge
-       9805  PCI 9805 Parallel Port
-       9815  PCI 9815 Dual Parallel Port
-               1000 0020  2P0S (2 port parallel adaptor)
-       9835  PCI 9835 Multi-I/O Controller
-               1000 0002  0P2S (16C550 UART)
-               1000 0012  1P2S
-       9845  PCI 9845 Multi-I/O Controller
-               1000 0004  0P4S (4 port 16550A serial card)
-               1000 0006  0P6S (6 port 16550A serial card)
-               1000 0014  1P4S (4 port 16550A serial card + parallel)
-       9855  PCI 9855 Multi-I/O Controller
-               1000 0014  1P4S
-9902  Stargen Inc.
-       0001  SG2010 PCI over Starfabric Bridge
-       0002  SG2010 PCI to Starfabric Gateway
-       0003  SG1010 Starfabric Switch and PCI Bridge
-a0a0  AOPEN Inc.
-a0f1  UNISYS Corporation
-a200  NEC Corporation
-a259  Hewlett Packard
-a25b  Hewlett Packard GmbH PL24-MKT
-a304  Sony
-a727  3Com Corporation
-       0013  3CRPAG175 Wireless PC Card
-aa42  Scitex Digital Video
-ac1e  Digital Receiver Technology Inc
-ac3d  Actuality Systems
-aecb  Adrienne Electronics Corporation
-b1b3  Shiva Europe Limited
-# Pinnacle should be 11bd, but they got it wrong several times --mj
-bd11  Pinnacle Systems, Inc. (Wrong ID)
-c001  TSI Telsys
-c0a9  Micron/Crucial Technology
-c0de  Motorola
-c0fe  Motion Engineering, Inc.
-ca50  Varian Australia Pty Ltd
-cafe  Chrysalis-ITS
-cccc  Catapult Communications
-cddd  Tyzx, Inc.
-       0101  DeepSea 1 High Speed Stereo Vision Frame Grabber
-       0200  DeepSea 2 High Speed Stereo Vision Frame Grabber
-d4d4  Dy4 Systems Inc
-       0601  PCI Mezzanine Card
-d531  I+ME ACTIA GmbH
-d84d  Exsys
-dead  Indigita Corporation
-deaf  Middle Digital Inc.
-       9050  PC Weasel Virtual VGA
-       9051  PC Weasel Serial Port
-       9052  PC Weasel Watchdog Timer
-e000  Winbond
-       e000  W89C940
-# see also : http://www.schoenfeld.de/inside/Inside_CWMK3.txt maybe a misuse of TJN id or it use the TJN 3XX chip for other applic
-e159  Tiger Jet Network Inc.
-       0001  Tiger3XX Modem/ISDN interface
-               0059 0001  128k ISDN-S/T Adapter
-               0059 0003  128k ISDN-U Adapter
-       0002  Tiger100APC ISDN chipset
-e4bf  EKF Elektronik GmbH
-# Innovative and scalable network IC vendor
-e55e  Essence Technology, Inc.
-ea01  Eagle Technology
-# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID.
-ea60  RME
-       9896  Digi32
-       9897  Digi32 Pro
-       9898  Digi32/8
-eabb  Aashima Technology B.V.
-eace  Endace Measurement Systems, Ltd
-       3100  DAG 3.10 OC-3/OC-12
-       3200  DAG 3.2x OC-3/OC-12
-       320e  DAG 3.2E Fast Ethernet
-       340e  DAG 3.4E Fast Ethernet
-       341e  DAG 3.41E Fast Ethernet
-       3500  DAG 3.5 OC-3/OC-12
-       351c  DAG 3.5ECM Fast Ethernet
-       4100  DAG 4.10 OC-48
-       4110  DAG 4.11 OC-48
-       4220  DAG 4.2 OC-48
-       422e  DAG 4.2E Dual Gigabit Ethernet
-ec80  Belkin Corporation
-       ec00  F5D6000
-ecc0  Echo Digital Audio Corporation
-edd8  ARK Logic Inc
-       a091  1000PV [Stingray]
-       a099  2000PV [Stingray]
-       a0a1  2000MT
-       a0a9  2000MI
-f1d0  AJA Video
-# All boards I have seen have this ID not efac, though all docs say efac...
-       cafe  KONA SD SMPTE 259M I/O
-       efac  KONA SD SMPTE 259M I/O
-       facd  KONA HD SMPTE 292M I/O
-fa57  Interagon AS
-       0001  PMC [Pattern Matching Chip]
-febd  Ultraview Corp.
-feda  Broadcom Inc (nee Epigram)
-       a0fa  BCM4210 iLine10 HomePNA 2.0
-       a10e  BCM4230 iLine10 HomePNA 2.0
-# IT & Telecom company, develops PCI Trunk cards <www.fedetec.es>
-fede  Fedetec Inc.
-       0003  TABIC PCI v3
-fffe  VMWare Inc
-       0405  Virtual SVGA 4.0
-       0710  Virtual SVGA
-ffff  Illegal Vendor ID
-
-
-# List of known device classes, subclasses and programming interfaces
-
-# Syntax:
-# C class      class_name
-#      subclass        subclass_name           <-- single tab
-#              prog-if  prog-if_name   <-- two tabs
-
-C 00  Unclassified device
-       00  Non-VGA unclassified device
-       01  VGA compatible unclassified device
-C 01  Mass storage controller
-       00  SCSI storage controller
-       01  IDE interface
-       02  Floppy disk controller
-       03  IPI bus controller
-       04  RAID bus controller
-       80  Unknown mass storage controller
-C 02  Network controller
-       00  Ethernet controller
-       01  Token ring network controller
-       02  FDDI network controller
-       03  ATM network controller
-       04  ISDN controller
-       80  Network controller
-C 03  Display controller
-       00  VGA compatible controller
-               00  VGA
-               01  8514
-       01  XGA compatible controller
-       02  3D controller
-       80  Display controller
-C 04  Multimedia controller
-       00  Multimedia video controller
-       01  Multimedia audio controller
-       02  Computer telephony device
-       80  Multimedia controller
-C 05  Memory controller
-       00  RAM memory
-       01  FLASH memory
-       80  Memory controller
-C 06  Bridge
-       00  Host bridge
-       01  ISA bridge
-       02  EISA bridge
-       03  MicroChannel bridge
-       04  PCI bridge
-               00  Normal decode
-               01  Subtractive decode
-       05  PCMCIA bridge
-       06  NuBus bridge
-       07  CardBus bridge
-       08  RACEway bridge
-               00  Transparent mode
-               01  Endpoint mode
-       09  Semi-transparent PCI-to-PCI bridge
-               40  Primary bus towards host CPU
-               80  Secondary bus towards host CPU
-       0a  InfiniBand to PCI host bridge
-       80  Bridge
-C 07  Communication controller
-       00  Serial controller
-               00  8250
-               01  16450
-               02  16550
-               03  16650
-               04  16750
-               05  16850
-               06  16950
-       01  Parallel controller
-               00  SPP
-               01  BiDir
-               02  ECP
-               03  IEEE1284
-               fe  IEEE1284 Target
-       02  Multiport serial controller
-       03  Modem
-               00  Generic
-               01  Hayes/16450
-               02  Hayes/16550
-               03  Hayes/16650
-               04  Hayes/16750
-       80  Communication controller
-C 08  Generic system peripheral
-       00  PIC
-               00  8259
-               01  ISA PIC
-               02  EISA PIC
-               10  IO-APIC
-               20  IO(X)-APIC
-       01  DMA controller
-               00  8237
-               01  ISA DMA
-               02  EISA DMA
-       02  Timer
-               00  8254
-               01  ISA Timer
-               02  EISA Timers
-       03  RTC
-               00  Generic
-               01  ISA RTC
-       04  PCI Hot-plug controller
-       80  System peripheral
-C 09  Input device controller
-       00  Keyboard controller
-       01  Digitizer Pen
-       02  Mouse controller
-       03  Scanner controller
-       04  Gameport controller
-               00  Generic
-               10  Extended
-       80  Input device controller
-C 0a  Docking station
-       00  Generic Docking Station
-       80  Docking Station
-C 0b  Processor
-       00  386
-       01  486
-       02  Pentium
-       10  Alpha
-       20  Power PC
-       30  MIPS
-       40  Co-processor
-C 0c  Serial bus controller
-       00  FireWire (IEEE 1394)
-               00  Generic
-               10  OHCI
-       01  ACCESS Bus
-       02  SSA
-       03  USB Controller
-               00  UHCI
-               10  OHCI
-               20  EHCI
-               80  Unspecified
-               fe  USB Device
-       04  Fibre Channel
-       05  SMBus
-       06  InfiniBand
-C 0d  Wireless controller
-       00  IRDA controller
-       01  Consumer IR controller
-       10  RF controller
-       80  Wireless controller
-C 0e  Intelligent controller
-       00  I2O
-C 0f  Satellite communications controller
-       00  Satellite TV controller
-       01  Satellite audio communication controller
-       03  Satellite voice communication controller
-       04  Satellite data communication controller
-C 10  Encryption controller
-       00  Network and computing encryption device
-       10  Entertainment encryption device
-       80  Encryption controller
-C 11  Signal processing controller
-       00  DPIO module
-       01  Performance counters
-       10  Communication synchronizer
-       80  Signal processing controller
index 30bac7ed7c16268d26c1f841a05b70a9e3a99fcf..3c565ce7f77b5aada24f3e4f44b89533c86bc14e 100644 (file)
@@ -90,15 +90,19 @@ static void pcie_portdrv_save_config(struct pci_dev *dev)
                pci_save_msi_state(dev);
 }
 
-static void pcie_portdrv_restore_config(struct pci_dev *dev)
+static int pcie_portdrv_restore_config(struct pci_dev *dev)
 {
        struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+       int retval;
 
        pci_restore_state(dev);
        if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
                pci_restore_msi_state(dev);
-       pci_enable_device(dev);
+       retval = pci_enable_device(dev);
+       if (retval)
+               return retval;
        pci_set_master(dev);
+       return 0;
 }
 
 /*
index 93e8a878ea951d379c2c1af147193928c728c480..b9c9b03919d449ff967f7359bbd6049fe15c0dc4 100644 (file)
@@ -584,7 +584,7 @@ static int pci_setup_device(struct pci_dev * dev)
                 dev->vendor, dev->device, class, dev->hdr_type);
 
        /* "Unknown power state" */
-       dev->current_state = 4;
+       dev->current_state = PCI_UNKNOWN;
 
        /* Early fixups, before probing the BARs */
        pci_fixup_device(pci_fixup_early, dev);
@@ -757,8 +757,6 @@ pci_scan_device(struct pci_bus *bus, int devfn)
        dev->dev.release = pci_release_dev;
        pci_dev_get(dev);
 
-       pci_name_device(dev);
-
        dev->dev.dma_mask = &dev->dma_mask;
        dev->dev.coherent_dma_mask = 0xffffffffull;
 
index 7988fc8df3fd24327d60c2cc24ed1e7b6fc5b3e3..9613f666c110b9561705afb38e5508229eee519d 100644 (file)
@@ -474,7 +474,7 @@ static int show_dev_config(struct seq_file *m, void *v)
        struct pci_dev *first_dev;
        struct pci_driver *drv;
        u32 class_rev;
-       unsigned char latency, min_gnt, max_lat, *class;
+       unsigned char latency, min_gnt, max_lat;
        int reg;
 
        first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
@@ -490,16 +490,8 @@ static int show_dev_config(struct seq_file *m, void *v)
        pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
        seq_printf(m, "  Bus %2d, device %3d, function %2d:\n",
               dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       class = pci_class_name(class_rev >> 16);
-       if (class)
-               seq_printf(m, "    %s", class);
-       else
-               seq_printf(m, "    Class %04x", class_rev >> 16);
-#ifdef CONFIG_PCI_NAMES
-       seq_printf(m, ": %s", dev->pretty_name);
-#else
+       seq_printf(m, "    Class %04x", class_rev >> 16);
        seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device);
-#endif
        seq_printf(m, " (rev %d).\n", class_rev & 0xff);
 
        if (dev->irq)
index 140354a2aa72a7534281619f5c53dd8b707fd5f1..4f0c1bd3674a6cf681a992b1f095eba5a5395de2 100644 (file)
@@ -245,12 +245,19 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, unsi
 {
        region &= ~(size-1);
        if (region) {
+               struct pci_bus_region bus_region;
                struct resource *res = dev->resource + nr;
 
                res->name = pci_name(dev);
                res->start = region;
                res->end = region + size - 1;
                res->flags = IORESOURCE_IO;
+
+               /* Convert from PCI bus to resource space.  */
+               bus_region.start = res->start;
+               bus_region.end = res->end;
+               pcibios_bus_to_resource(dev, res, &bus_region);
+
                pci_claim_resource(dev, nr);
        }
 }      
index 5598b4714f77ac2efaf0f545e404b4c9163c4fcf..50d6685dcbcce801682c9600a81be2a98f90f8a1 100644 (file)
@@ -26,7 +26,7 @@
 #include "pci.h"
 
 
-static void
+void
 pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
 {
        struct pci_bus_region region;
@@ -97,10 +97,7 @@ pci_claim_resource(struct pci_dev *dev, int resource)
        char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
        int err;
 
-       if (res->flags & IORESOURCE_IO)
-               root = &ioport_resource;
-       if (res->flags & IORESOURCE_MEM)
-               root = &iomem_resource;
+       root = pcibios_select_root(dev, res);
 
        err = -EINVAL;
        if (root != NULL)
index 320df6cd3defd6195ffd3eb759ac11906b377586..c2c8fa828e24e9d227aaf93a5efc4367dab40872 100644 (file)
@@ -865,22 +865,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
        return 0;
 }
 
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_intx(struct pci_dev *pdev, int enable)
-{
-       u16 pci_command, new;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-
-       if (enable)
-               new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
-       else
-               new = pci_command | PCI_COMMAND_INTX_DISABLE;
-
-       if (new != pci_command)
-               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-}
-
 static void ahci_print_info(struct ata_probe_ent *probe_ent)
 {
        struct ahci_host_priv *hpriv = probe_ent->private_data;
index 5f868852904149645e559ff2ac7c7ec2dd432756..87e0c36f1554a8b69597361a4a61dfd214db449f 100644 (file)
@@ -568,18 +568,6 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
        }
 }
 
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
-{
-       u16 pci_command;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-       if (pci_command & PCI_COMMAND_INTX_DISABLE) {
-               pci_command &= ~PCI_COMMAND_INTX_DISABLE;
-               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-       }
-}
-
 #define AHCI_PCI_BAR 5
 #define AHCI_GLOBAL_CTL 0x04
 #define AHCI_ENABLE (1 << 31)
@@ -677,7 +665,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
         * message-signalled interrupts currently).
         */
        if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
-               pci_enable_intx(pdev);
+               pci_intx(pdev, 1);
 
        if (combined) {
                port_info[sata_chan] = &piix_port_info[ent->driver_data];
index 7d1aaa99aaae0d502eaf838c5766779b36a42ed9..2bd3f11ac01012606a06afbf663cbd940eaf80fb 100644 (file)
@@ -233,18 +233,6 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
        }
 }
 
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
-{
-       u16 pci_command;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-       if (pci_command & PCI_COMMAND_INTX_DISABLE) {
-               pci_command &= ~PCI_COMMAND_INTX_DISABLE;
-               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-       }
-}
-
 static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        struct ata_probe_ent *probe_ent = NULL;
@@ -319,7 +307,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        pci_set_master(pdev);
-       pci_enable_intx(pdev);
+       pci_intx(pdev, 1);
 
        /* FIXME: check ata_device_add return value */
        ata_device_add(probe_ent);
index 42e13ed8eb5b55a9f9a473b19408bae775328e85..4c9fb8b71be1cb5cb64a047e71d64fd433776882 100644 (file)
@@ -176,18 +176,6 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
        uli_scr_cfg_write(ap, sc_reg, val);
 }
 
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
-{
-       u16 pci_command;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-       if (pci_command & PCI_COMMAND_INTX_DISABLE) {
-               pci_command &= ~PCI_COMMAND_INTX_DISABLE;
-               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-       }
-}
-
 static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        struct ata_probe_ent *probe_ent;
@@ -260,7 +248,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        pci_set_master(pdev);
-       pci_enable_intx(pdev);
+       pci_intx(pdev, 1);
 
        /* FIXME: check ata_device_add return value */
        ata_device_add(probe_ent);
index 30a0a3d1014527b991025958b7a2d36ab98cdac7..5b65e208893bc80df44179ceb2dd5d6a32b1dccc 100644 (file)
@@ -2536,7 +2536,7 @@ static int __init serial8250_init(void)
                goto out;
 
        serial8250_isa_devs = platform_device_register_simple("serial8250",
-                                                             -1, NULL, 0);
+                                        PLAT8250_DEV_LEGACY, NULL, 0);
        if (IS_ERR(serial8250_isa_devs)) {
                ret = PTR_ERR(serial8250_isa_devs);
                goto unreg;
index 1f2c276063eff982bb7400fdf5d81cbd2a8058c0..9c10262f2469ff821a5796e1772ebb4a379af5bb 100644 (file)
@@ -29,7 +29,7 @@ static struct plat_serial8250_port accent_data[] = {
 
 static struct platform_device accent_device = {
        .name                   = "serial8250",
-       .id                     = 2,
+       .id                     = PLAT8250_DEV_ACCENT,
        .dev                    = {
                .platform_data  = accent_data,
        },
index 465c9ea1e7a3772e52be846c9d8b9863abee0194..3bfe0f7b26fbaaeda1e6430a659388d6275a61b5 100644 (file)
@@ -43,7 +43,7 @@ static struct plat_serial8250_port boca_data[] = {
 
 static struct platform_device boca_device = {
        .name                   = "serial8250",
-       .id                     = 3,
+       .id                     = PLAT8250_DEV_BOCA,
        .dev                    = {
                .platform_data  = boca_data,
        },
index e9b4d908ef42901c3923e7230711f53779320fb1..6375d68b791318eba0d1de0c9791995e0e1d6df2 100644 (file)
@@ -35,7 +35,7 @@ static struct plat_serial8250_port fourport_data[] = {
 
 static struct platform_device fourport_device = {
        .name                   = "serial8250",
-       .id                     = 1,
+       .id                     = PLAT8250_DEV_FOURPORT,
        .dev                    = {
                .platform_data  = fourport_data,
        },
index 77f396f84b4c0eec8b0a4c318dd855209f1683ab..daf569cd3c8fcb19150069a548b06c83b58c3cf3 100644 (file)
@@ -40,7 +40,7 @@ static struct plat_serial8250_port hub6_data[] = {
 
 static struct platform_device hub6_device = {
        .name                   = "serial8250",
-       .id                     = 4,
+       .id                     = PLAT8250_DEV_HUB6,
        .dev                    = {
                .platform_data  = hub6_data,
        },
index f0c40d68b8c1837f2ca2ac1e4604fc35ad64b4a6..ac205256d5f308f758c5a325093bcaf2f3c86acd 100644 (file)
@@ -44,7 +44,7 @@ static struct plat_serial8250_port mca_data[] = {
 
 static struct platform_device mca_device = {
        .name                   = "serial8250",
-       .id                     = 5,
+       .id                     = PLAT8250_DEV_MCA,
        .dev                    = {
                .platform_data  = mca_data,
        },
index 8e184e2641cb236bf6edce6e9910b3efb7d9bb84..79861ee12a29c44c9837ea72f2feaf8312428848 100644 (file)
@@ -715,13 +715,11 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
                        usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
                        instance->rcv_buf, PAGE_SIZE,
                        cxacru_blocking_completion, &instance->rcv_done, 1);
-       instance->rcv_urb->transfer_flags |= URB_ASYNC_UNLINK;
 
        usb_fill_int_urb(instance->snd_urb,
                        usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
                        instance->snd_buf, PAGE_SIZE,
                        cxacru_blocking_completion, &instance->snd_done, 4);
-       instance->snd_urb->transfer_flags |= URB_ASYNC_UNLINK;
 
        init_MUTEX(&instance->cm_serialize);
 
index 0561d0234f2314fd963c02c55082c28d578d1473..333e39bb105f8c97a113a9ab6b1ac225d2b457b2 100644 (file)
@@ -4,9 +4,22 @@
 comment "USB Device Class drivers"
        depends on USB
 
+config OBSOLETE_OSS_USB_DRIVER
+       bool "Obsolete OSS USB drivers"
+       depends on USB && SOUND
+       help
+         This option enables support for the obsolete USB Audio and Midi
+         drivers that are scheduled for removal in the near future since
+         there are ALSA drivers for the same hardware.
+
+         Please contact Adrian Bunk <bunk@stusta.de> if you had to
+         say Y here because of missing support in the ALSA drivers.
+
+         If unsure, say N.
+
 config USB_AUDIO
        tristate "USB Audio support"
-       depends on USB && SOUND
+       depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
        help
          Say Y here if you want to connect USB audio equipment such as
          speakers to your computer's USB port. You only need this if you use
@@ -40,10 +53,12 @@ config USB_BLUETOOTH_TTY
 
 config USB_MIDI
        tristate "USB MIDI support"
-       depends on USB && SOUND
+       depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
        ---help---
          Say Y here if you want to connect a USB MIDI device to your
-         computer's USB port. This driver is for devices that comply with
+         computer's USB port.  You only need this if you use the OSS
+         sound system; USB MIDI devices are supported by ALSA's USB
+         audio driver. This driver is for devices that comply with
          'Universal Serial Bus Device Class Definition for MIDI Device'.
 
          The following devices are known to work:
index 7ce43fb8118a3b79e969711606390bdaafee96e5..e195709c9c7fabe8b2019032ab872cc69d45d81a 100644 (file)
@@ -310,8 +310,9 @@ static int usblp_check_status(struct usblp *usblp, int err)
 
        error = usblp_read_status (usblp, usblp->statusbuf);
        if (error < 0) {
-               err("usblp%d: error %d reading printer status",
-                       usblp->minor, error);
+               if (printk_ratelimit())
+                       err("usblp%d: error %d reading printer status",
+                               usblp->minor, error);
                return 0;
        }
 
@@ -604,7 +605,9 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                        case LPGETSTATUS:
                                if (usblp_read_status(usblp, usblp->statusbuf)) {
-                                       err("usblp%d: failed reading printer status", usblp->minor);
+                                       if (printk_ratelimit())
+                                               err("usblp%d: failed reading printer status",
+                                                       usblp->minor);
                                        retval = -EIO;
                                        goto done;
                                }
index 9e8c377b81612ab941339eb257178c64400a63e7..d5503cf0bf74c8586a5d7ed66b029014ec4b6d1f 100644 (file)
@@ -3,14 +3,14 @@
 #
 
 usbcore-objs   := usb.o hub.o hcd.o urb.o message.o \
-                       config.o file.o buffer.o sysfs.o
+                       config.o file.o buffer.o sysfs.o devio.o
 
 ifeq ($(CONFIG_PCI),y)
        usbcore-objs    += hcd-pci.o
 endif
 
 ifeq ($(CONFIG_USB_DEVICEFS),y)
-       usbcore-objs    += devio.o inode.o devices.o
+       usbcore-objs    += inode.o devices.o
 endif
 
 obj-$(CONFIG_USB)      += usbcore.o
index f86bf1454e21e69259146c02ea543e1e2d83bfca..b4265aa7d45e0c140ab650c5355952448e23cc92 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
+#include <linux/cdev.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/moduleparam.h>
 #include "hcd.h"       /* for usbcore internals */
 #include "usb.h"
 
+#define USB_MAXBUS                     64
+#define USB_DEVICE_MAX                 USB_MAXBUS * 128
+static struct class *usb_device_class;
+
 struct async {
        struct list_head asynclist;
        struct dev_state *ps;
@@ -71,6 +76,8 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic");
                        dev_info( dev , format , ## arg);       \
        } while (0)
 
+#define USB_DEVICE_DEV         MKDEV(USB_DEVICE_MAJOR, 0)
+
 
 #define        MAX_USBFS_BUFFER_SIZE   16384
 
@@ -487,7 +494,7 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
  */
 static int usbdev_open(struct inode *inode, struct file *file)
 {
-       struct usb_device *dev;
+       struct usb_device *dev = NULL;
        struct dev_state *ps;
        int ret;
 
@@ -501,11 +508,16 @@ static int usbdev_open(struct inode *inode, struct file *file)
 
        lock_kernel();
        ret = -ENOENT;
-       dev = usb_get_dev(inode->u.generic_ip);
+       /* check if we are called from a real node or usbfs */
+       if (imajor(inode) == USB_DEVICE_MAJOR)
+               dev = usbdev_lookup_minor(iminor(inode));
+       if (!dev)
+               dev = inode->u.generic_ip;
        if (!dev) {
                kfree(ps);
                goto out;
        }
+       usb_get_dev(dev);
        ret = 0;
        ps->dev = dev;
        ps->file = file;
@@ -1226,7 +1238,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
        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)))
@@ -1258,15 +1269,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
        /* 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);
@@ -1477,3 +1479,79 @@ struct file_operations usbfs_device_file_operations = {
        .open =         usbdev_open,
        .release =      usbdev_release,
 };
+
+struct usb_device *usbdev_lookup_minor(int minor)
+{
+       struct class_device *class_dev;
+       struct usb_device *dev = NULL;
+
+       down(&usb_device_class->sem);
+       list_for_each_entry(class_dev, &usb_device_class->children, node) {
+               if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
+                       dev = class_dev->class_data;
+                       break;
+               }
+       }
+       up(&usb_device_class->sem);
+
+       return dev;
+};
+
+void usbdev_add(struct usb_device *dev)
+{
+       int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
+
+       dev->class_dev = class_device_create(usb_device_class,
+                               MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
+                               "usbdev%d.%d", dev->bus->busnum, dev->devnum);
+
+       dev->class_dev->class_data = dev;
+}
+
+void usbdev_remove(struct usb_device *dev)
+{
+       class_device_unregister(dev->class_dev);
+}
+
+static struct cdev usb_device_cdev = {
+       .kobj   = {.name = "usb_device", },
+       .owner  = THIS_MODULE,
+};
+
+int __init usbdev_init(void)
+{
+       int retval;
+
+       retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
+                       "usb_device");
+       if (retval) {
+               err("unable to register minors for usb_device");
+               goto out;
+       }
+       cdev_init(&usb_device_cdev, &usbfs_device_file_operations);
+       retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
+       if (retval) {
+               err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
+               unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+               goto out;
+       }
+       usb_device_class = class_create(THIS_MODULE, "usb_device");
+       if (IS_ERR(usb_device_class)) {
+               err("unable to register usb_device class");
+               retval = PTR_ERR(usb_device_class);
+               usb_device_class = NULL;
+               cdev_del(&usb_device_cdev);
+               unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+       }
+
+out:
+       return retval;
+}
+
+void usbdev_cleanup(void)
+{
+       class_destroy(usb_device_class);
+       cdev_del(&usb_device_cdev);
+       unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+}
+
index fc056062c9602f8dac0c4c39e52d2a01c64ba9bc..cbb451d227d215a372110204ab89950f93f66aed 100644 (file)
@@ -121,10 +121,6 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
                }
        }
 
-#ifdef CONFIG_PCI_NAMES
-       hcd->product_desc = dev->pretty_name;
-#endif
-
        pci_set_master (dev);
 
        retval = usb_add_hcd (hcd, dev->irq, SA_SHIRQ);
@@ -264,8 +260,10 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
                retval = pci_set_power_state (dev, PCI_D3hot);
                if (retval == 0) {
                        dev_dbg (hcd->self.controller, "--> PCI D3\n");
-                       pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
-                       pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
+                       retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
+                       if (retval)
+                               break;
+                       retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
                } else if (retval < 0) {
                        dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
                                        retval);
@@ -339,8 +337,20 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
                                dev->current_state);
                }
 #endif
-               pci_enable_wake (dev, dev->current_state, 0);
-               pci_enable_wake (dev, PCI_D3cold, 0);
+               retval = pci_enable_wake (dev, dev->current_state, 0);
+               if (retval) {
+                       dev_err(hcd->self.controller,
+                               "can't enable_wake to %d, %d!\n",
+                               dev->current_state, retval);
+                       return retval;
+               }
+               retval = pci_enable_wake (dev, PCI_D3cold, 0);
+               if (retval) {
+                       dev_err(hcd->self.controller,
+                               "can't enable_wake to %d, %d!\n",
+                               PCI_D3cold, retval);
+                       return retval;
+               }
        } else {
                /* Same basic cases: clean (powered/not), dirty */
                dev_dbg(hcd->self.controller, "PCI legacy resume\n");
@@ -380,7 +390,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
                usb_hc_died (hcd);
        }
 
-       pci_enable_device(dev);
+       retval = pci_enable_device(dev);
        return retval;
 }
 EXPORT_SYMBOL (usb_hcd_pci_resume);
index 28055f95645b8dfc55ae9216a0b971f1e57479d9..ac451fa7e4d273787e814c08f5092c6fc1feab37 100644 (file)
@@ -339,11 +339,11 @@ extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
  * to preallocate bandwidth)
  */
 #define USB2_HOST_DELAY        5       /* nsec, guess */
-#define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \
-       + ((2083UL * (3167 + BitTime (bytes)))/1000) \
+#define HS_NSECS(bytes) ( ((55 * 8 * 2083) \
+       + (2083UL * (3 + BitTime(bytes))))/1000 \
        + USB2_HOST_DELAY)
-#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \
-       + ((2083UL * (3167 + BitTime (bytes)))/1000) \
+#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \
+       + (2083UL * (3 + BitTime(bytes))))/1000 \
        + USB2_HOST_DELAY)
 #define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
 #define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
index c9412daff682431a820d11c3595cde972929377d..758c7f0ed1597d7a5b40028fd60df841236c6423 100644 (file)
@@ -492,6 +492,23 @@ static int hub_hub_status(struct usb_hub *hub,
        return ret;
 }
 
+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[port1-1] && set_state) {
+               usb_set_device_state(hdev->children[port1-1],
+                               USB_STATE_NOTATTACHED);
+       }
+       ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
+       if (ret)
+               dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
+                       port1, ret);
+
+       return ret;
+}
+
 static int hub_configure(struct usb_hub *hub,
        struct usb_endpoint_descriptor *endpoint)
 {
@@ -610,19 +627,33 @@ static int hub_configure(struct usb_hub *hub,
                        break;
        }
 
+       /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
        switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
-               case 0x00:
-                       if (hdev->descriptor.bDeviceProtocol != 0)
-                               dev_dbg(hub_dev, "TT requires at most 8 FS bit times\n");
+               case HUB_TTTT_8_BITS:
+                       if (hdev->descriptor.bDeviceProtocol != 0) {
+                               hub->tt.think_time = 666;
+                               dev_dbg(hub_dev, "TT requires at most %d "
+                                               "FS bit times (%d ns)\n",
+                                       8, hub->tt.think_time);
+                       }
                        break;
-               case 0x20:
-                       dev_dbg(hub_dev, "TT requires at most 16 FS bit times\n");
+               case HUB_TTTT_16_BITS:
+                       hub->tt.think_time = 666 * 2;
+                       dev_dbg(hub_dev, "TT requires at most %d "
+                                       "FS bit times (%d ns)\n",
+                               16, hub->tt.think_time);
                        break;
-               case 0x40:
-                       dev_dbg(hub_dev, "TT requires at most 24 FS bit times\n");
+               case HUB_TTTT_24_BITS:
+                       hub->tt.think_time = 666 * 3;
+                       dev_dbg(hub_dev, "TT requires at most %d "
+                                       "FS bit times (%d ns)\n",
+                               24, hub->tt.think_time);
                        break;
-               case 0x60:
-                       dev_dbg(hub_dev, "TT requires at most 32 FS bit times\n");
+               case HUB_TTTT_32_BITS:
+                       hub->tt.think_time = 666 * 4;
+                       dev_dbg(hub_dev, "TT requires at most %d "
+                                       "FS bit times (%d ns)\n",
+                               32, hub->tt.think_time);
                        break;
        }
 
@@ -712,20 +743,36 @@ fail:
 
 static unsigned highspeed_hubs;
 
+/* Called after the hub driver is unbound from a hub with children */
+static void hub_remove_children_work(void *__hub)
+{
+       struct usb_hub          *hub = __hub;
+       struct usb_device       *hdev = hub->hdev;
+       int                     i;
+
+       kfree(hub);
+
+       usb_lock_device(hdev);
+       for (i = 0; i < hdev->maxchild; ++i) {
+               if (hdev->children[i])
+                       usb_disconnect(&hdev->children[i]);
+       }
+       usb_unlock_device(hdev);
+       usb_put_dev(hdev);
+}
+
 static void hub_disconnect(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata (intf);
        struct usb_device *hdev;
+       int n, port1;
 
-       if (!hub)
-               return;
+       usb_set_intfdata (intf, NULL);
        hdev = hub->hdev;
 
        if (hdev->speed == USB_SPEED_HIGH)
                highspeed_hubs--;
 
-       usb_set_intfdata (intf, NULL);
-
        hub_quiesce(hub);
        usb_free_urb(hub->urb);
        hub->urb = NULL;
@@ -746,8 +793,27 @@ static void hub_disconnect(struct usb_interface *intf)
                hub->buffer = NULL;
        }
 
-       /* Free the memory */
-       kfree(hub);
+       /* If there are any children then this is an unbind only, not a
+        * physical disconnection.  The active ports must be disabled
+        * and later on we must call usb_disconnect().  We can't call
+        * it now because we may not hold the hub's device lock.
+        */
+       n = 0;
+       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+               if (hdev->children[port1 - 1]) {
+                       ++n;
+                       hub_port_disable(hub, port1, 1);
+               }
+       }
+
+       if (n == 0)
+               kfree(hub);
+       else {
+               /* Reuse the hub->leds work_struct for our own purposes */
+               INIT_WORK(&hub->leds, hub_remove_children_work, hub);
+               schedule_work(&hub->leds);
+               usb_get_dev(hdev);
+       }
 }
 
 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1051,6 +1117,7 @@ void usb_disconnect(struct usb_device **pdev)
        dev_dbg (&udev->dev, "unregistering device\n");
        release_address(udev);
        usbfs_remove_device(udev);
+       usbdev_remove(udev);
        usb_remove_sysfs_dev_files(udev);
 
        /* Avoid races with recursively_mark_NOTATTACHED() */
@@ -1290,6 +1357,7 @@ int usb_new_device(struct usb_device *udev)
        /* USB device state == configured ... usable */
 
        /* add a /proc/bus/usb entry */
+       usbdev_add(udev);
        usbfs_add_device(udev);
        return 0;
 
@@ -1428,23 +1496,6 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
        return status;
 }
 
-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[port1-1] && set_state) {
-               usb_set_device_state(hdev->children[port1-1],
-                               USB_STATE_NOTATTACHED);
-       }
-       ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
-       if (ret)
-               dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
-                       port1, ret);
-
-       return ret;
-}
-
 /*
  * Disable a port and mark a logical connnect-change event, so that some
  * time later khubd will disconnect() any existing usb_device on the port
index 53bf5649621ef366485c4346e754cfc9f60ab893..e7fa9b5a521e7c48bffdac4097f6ea4e063c054e 100644 (file)
@@ -157,6 +157,12 @@ enum hub_led_mode {
 
 struct usb_device;
 
+/* Transaction Translator Think Times, in bits */
+#define HUB_TTTT_8_BITS                0x00
+#define HUB_TTTT_16_BITS       0x20
+#define HUB_TTTT_24_BITS       0x40
+#define HUB_TTTT_32_BITS       0x60
+
 /*
  * As of USB 2.0, full/low speed devices are segregated into trees.
  * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
@@ -170,6 +176,7 @@ struct usb_device;
 struct usb_tt {
        struct usb_device       *hub;   /* upstream highspeed hub */
        int                     multi;  /* true means one TT per port */
+       unsigned                think_time;     /* think time in ns */
 
        /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
        spinlock_t              lock;
index c3e3a95d3804ff8e48dd308f4272fdf2e9072a0a..640f41e470294d5911f04a2d7e4c92df4d225455 100644 (file)
@@ -728,15 +728,9 @@ int __init usbfs_init(void)
 {
        int retval;
 
-       retval = usb_register(&usbfs_driver);
-       if (retval)
-               return retval;
-
        retval = register_filesystem(&usb_fs_type);
-       if (retval) {
-               usb_deregister(&usbfs_driver);
+       if (retval)
                return retval;
-       }
 
        /* create mount point for usbfs */
        usbdir = proc_mkdir("usb", proc_bus);
@@ -746,7 +740,6 @@ int __init usbfs_init(void)
 
 void usbfs_cleanup(void)
 {
-       usb_deregister(&usbfs_driver);
        unregister_filesystem(&usb_fs_type);
        if (usbdir)
                remove_proc_entry("usb", proc_bus);
index 88d1b376f67cb2ee03d15ebfce7654de8a2d0b32..c47c8052b4866f536b7482e4452d7f99ec221051 100644 (file)
@@ -48,7 +48,6 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
 
        init_completion(&done);         
        urb->context = &done;
-       urb->transfer_flags |= URB_ASYNC_UNLINK;
        urb->actual_length = 0;
        status = usb_submit_urb(urb, GFP_NOIO);
 
@@ -266,7 +265,9 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs)
                                continue;
                        if (found) {
                                status = usb_unlink_urb (io->urbs [i]);
-                               if (status != -EINPROGRESS && status != -EBUSY)
+                               if (status != -EINPROGRESS
+                                               && status != -ENODEV
+                                               && status != -EBUSY)
                                        dev_err (&io->dev->dev,
                                                "%s, unlink --> %d\n",
                                                __FUNCTION__, status);
@@ -357,8 +358,7 @@ int usb_sg_init (
        if (!io->urbs)
                goto nomem;
 
-       urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP
-                       | URB_NO_INTERRUPT;
+       urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
        if (usb_pipein (pipe))
                urb_flags |= URB_SHORT_NOT_OK;
 
index c0feee25ff0a8ddce3ee8f8b19a6d77f82c17603..c846fefb73862049fa7960dce85c7a4c96780b05 100644 (file)
@@ -309,9 +309,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags)
        unsigned int    allowed;
 
        /* enforce simple/standard policy */
-       allowed = URB_ASYNC_UNLINK;     // affects later unlinks
-       allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
-       allowed |= URB_NO_INTERRUPT;
+       allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
+                       URB_NO_INTERRUPT);
        switch (temp) {
        case PIPE_BULK:
                if (is_out)
@@ -400,14 +399,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags)
  * canceled (rather than any other code) and will quickly be removed
  * from host controller data structures.
  *
- * In the past, clearing the URB_ASYNC_UNLINK transfer flag for the
- * URB indicated that the request was synchronous.  This usage is now
- * deprecated; if the flag is clear the call will be forwarded to
- * usb_kill_urb() and the return value will be 0.  In the future, drivers
- * should call usb_kill_urb() directly for synchronous unlinking.
- *
- * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
- * request is asynchronous.  Success is indicated by returning -EINPROGRESS,
+ * This request is always asynchronous.
+ * Success is indicated by returning -EINPROGRESS,
  * at which time the URB will normally have been unlinked but not yet
  * given back to the device driver.  When it is called, the completion
  * function will see urb->status == -ECONNRESET.  Failure is indicated
@@ -453,17 +446,6 @@ int usb_unlink_urb(struct urb *urb)
 {
        if (!urb)
                return -EINVAL;
-       if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) {
-#ifdef CONFIG_DEBUG_KERNEL
-               if (printk_ratelimit()) {
-                       printk(KERN_NOTICE "usb_unlink_urb() is deprecated for "
-                               "synchronous unlinks.  Use usb_kill_urb() instead.\n");
-                       WARN_ON(1);
-               }
-#endif
-               usb_kill_urb(urb);
-               return 0;
-       }
        if (!(urb->dev && urb->dev->bus && urb->dev->bus->op))
                return -ENODEV;
        return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET);
index 2cddd8a00437b8bede3f9814a66dc73a2190886a..087af73a59dd70aa270694abde9e9233a51fe241 100644 (file)
@@ -65,6 +65,16 @@ static int generic_probe (struct device *dev)
 }
 static int generic_remove (struct device *dev)
 {
+       struct usb_device *udev = to_usb_device(dev);
+
+       /* if this is only an unbind, not a physical disconnect, then
+        * unconfigure the device */
+       if (udev->state == USB_STATE_CONFIGURED)
+               usb_set_configuration(udev, 0);
+
+       /* in case the call failed or the device was suspended */
+       if (udev->state >= USB_STATE_CONFIGURED)
+               usb_disable_device(udev, 0);
        return 0;
 }
 
@@ -912,7 +922,7 @@ int usb_trylock_device(struct usb_device *udev)
  * is neither BINDING nor BOUND.  Rather than sleeping to wait for the
  * lock, the routine polls repeatedly.  This is to prevent deadlock with
  * disconnect; in some drivers (such as usb-storage) the disconnect()
- * callback will block waiting for a device reset to complete.
+ * or suspend() method will block waiting for a device reset to complete.
  *
  * Returns a negative error code for failure, otherwise 1 or 0 to indicate
  * that the device will or will not have to be unlocked.  (0 can be
@@ -922,6 +932,8 @@ int usb_trylock_device(struct usb_device *udev)
 int usb_lock_device_for_reset(struct usb_device *udev,
                struct usb_interface *iface)
 {
+       unsigned long jiffies_expire = jiffies + HZ;
+
        if (udev->state == USB_STATE_NOTATTACHED)
                return -ENODEV;
        if (udev->state == USB_STATE_SUSPENDED)
@@ -938,6 +950,12 @@ int usb_lock_device_for_reset(struct usb_device *udev,
        }
 
        while (!usb_trylock_device(udev)) {
+
+               /* If we can't acquire the lock after waiting one second,
+                * we're probably deadlocked */
+               if (time_after(jiffies, jiffies_expire))
+                       return -EBUSY;
+
                msleep(15);
                if (udev->state == USB_STATE_NOTATTACHED)
                        return -ENODEV;
@@ -1478,13 +1496,18 @@ static int __init usb_init(void)
        retval = usb_major_init();
        if (retval)
                goto major_init_failed;
+       retval = usb_register(&usbfs_driver);
+       if (retval)
+               goto driver_register_failed;
+       retval = usbdev_init();
+       if (retval)
+               goto usbdevice_init_failed;
        retval = usbfs_init();
        if (retval)
                goto fs_init_failed;
        retval = usb_hub_init();
        if (retval)
                goto hub_init_failed;
-
        retval = driver_register(&usb_generic_driver);
        if (!retval)
                goto out;
@@ -1493,7 +1516,11 @@ static int __init usb_init(void)
 hub_init_failed:
        usbfs_cleanup();
 fs_init_failed:
-       usb_major_cleanup();    
+       usbdev_cleanup();
+usbdevice_init_failed:
+       usb_deregister(&usbfs_driver);
+driver_register_failed:
+       usb_major_cleanup();
 major_init_failed:
        usb_host_cleanup();
 host_init_failed:
@@ -1514,6 +1541,8 @@ static void __exit usb_exit(void)
        driver_unregister(&usb_generic_driver);
        usb_major_cleanup();
        usbfs_cleanup();
+       usb_deregister(&usbfs_driver);
+       usbdev_cleanup();
        usb_hub_cleanup();
        usb_host_cleanup();
        bus_unregister(&usb_bus_type);
index 2c690f6d4c18b84dd83832f7aca4746dbd36d731..83d48c8133af5992913bfd33a8b94fd7a079423c 100644 (file)
@@ -37,6 +37,11 @@ extern struct file_operations usbfs_devices_fops;
 extern struct file_operations usbfs_device_file_operations;
 extern void usbfs_conn_disc_event(void);
 
+extern int usbdev_init(void);
+extern void usbdev_cleanup(void);
+extern void usbdev_add(struct usb_device *dev);
+extern void usbdev_remove(struct usb_device *dev);
+extern struct usb_device *usbdev_lookup_minor(int minor);
 
 struct dev_state {
        struct list_head list;      /* state list */
index 8509e955007dab54e0fd6e3ec5f5e3b1e606cf2f..49459e33e952a654b4a58ffff03f3a52851f3346 100644 (file)
@@ -2181,6 +2181,7 @@ eth_bind (struct usb_gadget *gadget)
        u8                      cdc = 1, zlp = 1, rndis = 1;
        struct usb_ep           *in_ep, *out_ep, *status_ep = NULL;
        int                     status = -ENOMEM;
+       int                     gcnum;
 
        /* these flags are only ever cleared; compiler take note */
 #ifndef        DEV_CONFIG_CDC
@@ -2194,44 +2195,26 @@ eth_bind (struct usb_gadget *gadget)
         * standard protocol is _strongly_ preferred for interop purposes.
         * (By everyone except Microsoft.)
         */
-       if (gadget_is_net2280 (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
-       } else if (gadget_is_dummy (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0202);
-       } else if (gadget_is_pxa (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
+       if (gadget_is_pxa (gadget)) {
                /* pxa doesn't support altsettings */
                cdc = 0;
        } else if (gadget_is_sh(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
                /* sh doesn't support multiple interfaces or configs */
                cdc = 0;
                rndis = 0;
        } else if (gadget_is_sa1100 (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
                /* hardware can't write zlps */
                zlp = 0;
                /* sa1100 CAN do CDC, without status endpoint ... we use
                 * non-CDC to be compatible with ARM Linux-2.4 "usb-eth".
                 */
                cdc = 0;
-       } else if (gadget_is_goku (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206);
-       } else if (gadget_is_mq11xx (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
-       } else if (gadget_is_omap (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
-       } else if (gadget_is_lh7a40x(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
-       } else if (gadget_is_n9604(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
-       } else if (gadget_is_pxa27x(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
-       } else if (gadget_is_s3c2410(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
-       } else if (gadget_is_at91(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213);
-       } else {
+       }
+
+       gcnum = usb_gadget_controller_number (gadget);
+       if (gcnum >= 0)
+               device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
+       else {
                /* can't assume CDC works.  don't want to default to
                 * anything less functional on CDC-capable hardware,
                 * so we fail in this case.
index 4f57085619b4fa26ea922e9c358f361210e4fc03..a41d9d4baee3c6eaa17cdff185e30d343b2d1171 100644 (file)
@@ -3713,6 +3713,7 @@ static void fsg_unbind(struct usb_gadget *gadget)
 static int __init check_parameters(struct fsg_dev *fsg)
 {
        int     prot;
+       int     gcnum;
 
        /* Store the default values */
        mod_data.transport_type = USB_PR_BULK;
@@ -3724,33 +3725,13 @@ static int __init check_parameters(struct fsg_dev *fsg)
                mod_data.can_stall = 0;
 
        if (mod_data.release == 0xffff) {       // Parameter wasn't set
-               if (gadget_is_net2280(fsg->gadget))
-                       mod_data.release = 0x0301;
-               else if (gadget_is_dummy(fsg->gadget))
-                       mod_data.release = 0x0302;
-               else if (gadget_is_pxa(fsg->gadget))
-                       mod_data.release = 0x0303;
-               else if (gadget_is_sh(fsg->gadget))
-                       mod_data.release = 0x0304;
-
                /* The sa1100 controller is not supported */
-
-               else if (gadget_is_goku(fsg->gadget))
-                       mod_data.release = 0x0306;
-               else if (gadget_is_mq11xx(fsg->gadget))
-                       mod_data.release = 0x0307;
-               else if (gadget_is_omap(fsg->gadget))
-                       mod_data.release = 0x0308;
-               else if (gadget_is_lh7a40x(fsg->gadget))
-                       mod_data.release = 0x0309;
-               else if (gadget_is_n9604(fsg->gadget))
-                       mod_data.release = 0x0310;
-               else if (gadget_is_pxa27x(fsg->gadget))
-                       mod_data.release = 0x0311;
-               else if (gadget_is_s3c2410(gadget))
-                       mod_data.release = 0x0312;
-               else if (gadget_is_at91(fsg->gadget))
-                       mod_data.release = 0x0313;
+               if (gadget_is_sa1100(fsg->gadget))
+                       gcnum = -1;
+               else
+                       gcnum = usb_gadget_controller_number(fsg->gadget);
+               if (gcnum >= 0)
+                       mod_data.release = 0x0300 + gcnum;
                else {
                        WARN(fsg, "controller '%s' not recognized\n",
                                fsg->gadget->name);
index ea2eb52c766d6a64940903b2722077cc212c9e4b..8cbae21d84b9bc6634c8f5854eac91d221d99ed3 100644 (file)
@@ -5,6 +5,7 @@
  *
  * This could eventually work like the ARM mach_is_*() stuff, driven by
  * some config file that gets updated as new hardware is supported.
+ * (And avoiding the runtime comparisons in typical one-choice cases.)
  *
  * NOTE:  some of these controller drivers may not be available yet.
  */
 #define gadget_is_at91(g)      0
 #endif
 
+#ifdef CONFIG_USB_GADGET_IMX
+#define gadget_is_imx(g)       !strcmp("imx_udc", (g)->name)
+#else
+#define gadget_is_imx(g)       0
+#endif
+
 // CONFIG_USB_GADGET_SX2
 // CONFIG_USB_GADGET_AU1X00
 // ...
 
+
+/**
+ * usb_gadget_controller_number - support bcdDevice id convention
+ * @gadget: the controller being driven
+ *
+ * Return a 2-digit BCD value associated with the peripheral controller,
+ * suitable for use as part of a bcdDevice value, or a negative error code.
+ *
+ * NOTE:  this convention is purely optional, and has no meaning in terms of
+ * any USB specification.  If you want to use a different convention in your
+ * gadget driver firmware -- maybe a more formal revision ID -- feel free.
+ *
+ * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
+ * to change their behavior accordingly.  For example it might help avoiding
+ * some chip bug.
+ */
+static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
+{
+       if (gadget_is_net2280(gadget))
+               return 0x01;
+       else if (gadget_is_dummy(gadget))
+               return 0x02;
+       else if (gadget_is_pxa(gadget))
+               return 0x03;
+       else if (gadget_is_sh(gadget))
+               return 0x04;
+       else if (gadget_is_sa1100(gadget))
+               return 0x05;
+       else if (gadget_is_goku(gadget))
+               return 0x06;
+       else if (gadget_is_mq11xx(gadget))
+               return 0x07;
+       else if (gadget_is_omap(gadget))
+               return 0x08;
+       else if (gadget_is_lh7a40x(gadget))
+               return 0x09;
+       else if (gadget_is_n9604(gadget))
+               return 0x10;
+       else if (gadget_is_pxa27x(gadget))
+               return 0x11;
+       else if (gadget_is_s3c2410(gadget))
+               return 0x12;
+       else if (gadget_is_at91(gadget))
+               return 0x13;
+       else if (gadget_is_imx(gadget))
+               return 0x14;
+       return -ENOENT;
+}
index 9e4f1c6935a54673ba19f71d24ed4aef2ed11150..c925d9222f53c4baaef730dd1046b8aa75620897 100644 (file)
@@ -1422,49 +1422,20 @@ static int gs_bind(struct usb_gadget *gadget)
        int ret;
        struct usb_ep *ep;
        struct gs_dev *dev;
+       int gcnum;
 
-       /* device specific */
-       if (gadget_is_net2280(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0001);
-       } else if (gadget_is_pxa(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0002);
-       } else if (gadget_is_sh(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0003);
-               /* sh doesn't support multiple interfaces or configs */
+       /* Some controllers can't support CDC ACM:
+        * - sh doesn't support multiple interfaces or configs;
+        * - sa1100 doesn't have a third interrupt endpoint
+        */
+       if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget))
                use_acm = 0;
-       } else if (gadget_is_sa1100(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0004);
-               /* sa1100 doesn't support necessary endpoints */
-               use_acm = 0;
-       } else if (gadget_is_goku(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0005);
-       } else if (gadget_is_mq11xx(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0006);
-       } else if (gadget_is_omap(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0007);
-       } else if (gadget_is_lh7a40x(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0008);
-       } else if (gadget_is_n9604(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0009);
-       } else if (gadget_is_pxa27x(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0011);
-       } else if (gadget_is_s3c2410(gadget)) {
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0012);
-       } else if (gadget_is_at91(gadget)) {
+
+       gcnum = usb_gadget_controller_number(gadget);
+       if (gcnum >= 0)
                gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0013);
-       else {
+                               cpu_to_le16(GS_VERSION_NUM | gcnum);
+       else {
                printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
                        gadget->name);
                /* unrecognized, but safe unless bulk is REALLY quirky */
index bb9b2d94eed5a5ccd4b604b95491a081bbed7f12..6890e773b2a2a38f6ddf8469e0e141b47e8fb1ef 100644 (file)
@@ -1139,6 +1139,13 @@ zero_bind (struct usb_gadget *gadget)
 {
        struct zero_dev         *dev;
        struct usb_ep           *ep;
+       int                     gcnum;
+
+       /* FIXME this can't yet work right with SH ... it has only
+        * one configuration, numbered one.
+        */
+       if (gadget_is_sh(gadget))
+               return -ENODEV;
 
        /* Bulk-only drivers like this one SHOULD be able to
         * autoconfigure on any sane usb controller driver,
@@ -1161,43 +1168,10 @@ autoconf_fail:
        EP_OUT_NAME = ep->name;
        ep->driver_data = ep;   /* claim */
 
-
-       /*
-        * DRIVER POLICY CHOICE:  you may want to do this differently.
-        * One thing to avoid is reusing a bcdDevice revision code
-        * with different host-visible configurations or behavior
-        * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc
-        */
-       if (gadget_is_net2280 (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
-       } else if (gadget_is_pxa (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
-#if 0
-       } else if (gadget_is_sh(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
-               /* SH has only one configuration; see "loopdefault" */
-               device_desc.bNumConfigurations = 1;
-               /* FIXME make 1 == default.bConfigurationValue */
-#endif
-       } else if (gadget_is_sa1100 (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
-       } else if (gadget_is_goku (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206);
-       } else if (gadget_is_mq11xx (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
-       } else if (gadget_is_omap (gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
-       } else if (gadget_is_lh7a40x(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
-       } else if (gadget_is_n9604(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
-       } else if (gadget_is_pxa27x(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
-       } else if (gadget_is_s3c2410(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
-       } else if (gadget_is_at91(gadget)) {
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213);
-       } else {
+       gcnum = usb_gadget_controller_number (gadget);
+       if (gcnum >= 0)
+               device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
+       else {
                /* gadget zero is so simple (for now, no altsettings) that
                 * it SHOULD NOT have problems with bulk-capable hardware.
                 * so warn about unrcognized controllers, don't panic.
index 149b13fc0a716a576ab0af0cbc856c8e14f1e67b..2507e898af09b3cc591826d95fb562e32d1af6de 100644 (file)
@@ -549,7 +549,9 @@ static int ehci_start (struct usb_hcd *hcd)
                hcd->can_wakeup = (port_wake & 1) != 0;
 
                /* help hc dma work well with cachelines */
-               pci_set_mwi (pdev);
+               retval = pci_set_mwi(pdev);
+               if (retval)
+                       ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
        }
 #endif
 
index 20df01a79b2e89e61192c69be9efc141bd8b9ab3..940d38ca7d91785534bffe0f8da2f5e015c563a2 100644 (file)
@@ -677,6 +677,9 @@ qh_make (
                                goto done;
                        }
                } else {
+                       struct usb_tt   *tt = urb->dev->tt;
+                       int             think_time;
+
                        /* gap is f(FS/LS transfer times) */
                        qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
                                        is_input, 0, maxp) / (125 * 1000);
@@ -690,6 +693,10 @@ qh_make (
                                qh->c_usecs = HS_USECS (0);
                        }
 
+                       think_time = tt ? tt->think_time : 0;
+                       qh->tt_usecs = NS_TO_US (think_time +
+                                       usb_calc_bus_time (urb->dev->speed,
+                                       is_input, 0, max_packet (maxp)));
                        qh->period = urb->interval;
                }
        }
index 4c972b57c7c3a5ac1fd026269698f83375f4de1a..ccc7300baa6d717a2bb1dab4140ba8d84337eb6d 100644 (file)
@@ -700,6 +700,7 @@ iso_stream_init (
 
        } else {
                u32             addr;
+               int             think_time;
 
                addr = dev->ttport << 24;
                if (!ehci_is_TDI(ehci)
@@ -709,6 +710,9 @@ iso_stream_init (
                addr |= epnum << 8;
                addr |= dev->devnum;
                stream->usecs = HS_USECS_ISO (maxp);
+               think_time = dev->tt ? dev->tt->think_time : 0;
+               stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
+                               dev->speed, is_input, 1, maxp));
                if (is_input) {
                        u32     tmp;
 
index a7542157534c13c159a2220e02b8d1c44cd16632..20c9b550097dc70e0bb3b326f144aa9628059b79 100644 (file)
@@ -421,6 +421,7 @@ struct ehci_qh {
        u8                      usecs;          /* intr bandwidth */
        u8                      gap_uf;         /* uframes split/csplit gap */
        u8                      c_usecs;        /* ... split completion bw */
+       u16                     tt_usecs;       /* tt downstream bandwidth */
        unsigned short          period;         /* polling interval */
        unsigned short          start;          /* where polling starts */
 #define NO_FRAME ((unsigned short)~0)                  /* pick new start */
@@ -479,6 +480,7 @@ struct ehci_iso_stream {
         */
        u8                      interval;
        u8                      usecs, c_usecs;
+       u16                     tt_usecs;
        u16                     maxp;
        u16                     raw_mask;
        unsigned                bandwidth;
index 75128c3718008a698cb0695c3eba0a0589bb2928..41bbae83fc713f3c686dc2ad4ec2c9399beee1fe 100644 (file)
@@ -83,7 +83,7 @@
 #include "../core/hcd.h"
 #include "isp116x.h"
 
-#define DRIVER_VERSION "08 Apr 2005"
+#define DRIVER_VERSION "05 Aug 2005"
 #define DRIVER_DESC    "ISP116x USB Host Controller Driver"
 
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -629,14 +629,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
                        ERR("Unrecoverable error\n");
                        /* What should we do here? Reset?  */
                }
-               if (intstat & HCINT_RHSC) {
-                       isp116x->rhstatus =
-                           isp116x_read_reg32(isp116x, HCRHSTATUS);
-                       isp116x->rhport[0] =
-                           isp116x_read_reg32(isp116x, HCRHPORT1);
-                       isp116x->rhport[1] =
-                           isp116x_read_reg32(isp116x, HCRHPORT2);
-               }
+               if (intstat & HCINT_RHSC)
+                       /* When root hub or any of its ports is going
+                          to come out of suspend, it may take more
+                          than 10ms for status bits to stabilize. */
+                       mod_timer(&hcd->rh_timer, jiffies
+                                 + msecs_to_jiffies(20) + 1);
                if (intstat & HCINT_RD) {
                        DBG("---- remote wakeup\n");
                        schedule_work(&isp116x->rh_resume);
@@ -925,20 +923,27 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
        struct isp116x *isp116x = hcd_to_isp116x(hcd);
        int ports, i, changed = 0;
+       unsigned long flags;
 
        if (!HC_IS_RUNNING(hcd->state))
                return -ESHUTDOWN;
 
-       ports = isp116x->rhdesca & RH_A_NDP;
+       /* Report no status change now, if we are scheduled to be
+          called later */
+       if (timer_pending(&hcd->rh_timer))
+               return 0;
 
-       /* init status */
+       ports = isp116x->rhdesca & RH_A_NDP;
+       spin_lock_irqsave(&isp116x->lock, flags);
+       isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
        if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC))
                buf[0] = changed = 1;
        else
                buf[0] = 0;
 
        for (i = 0; i < ports; i++) {
-               u32 status = isp116x->rhport[i];
+               u32 status = isp116x->rhport[i] =
+                   isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
 
                if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
                              | RH_PS_OCIC | RH_PS_PRSC)) {
@@ -947,6 +952,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
                        continue;
                }
        }
+       spin_unlock_irqrestore(&isp116x->lock, flags);
        return changed;
 }
 
@@ -1463,10 +1469,6 @@ static int isp116x_sw_reset(struct isp116x *isp116x)
        return ret;
 }
 
-/*
-  Reset. Tries to perform platform-specific hardware
-  reset first; falls back to software reset.
-*/
 static int isp116x_reset(struct usb_hcd *hcd)
 {
        struct isp116x *isp116x = hcd_to_isp116x(hcd);
@@ -1474,17 +1476,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
        u16 clkrdy = 0;
        int ret = 0, timeout = 15 /* ms */ ;
 
-       if (isp116x->board && isp116x->board->reset) {
-               /* Hardware reset */
-               isp116x->board->reset(hcd->self.controller, 1);
-               msleep(10);
-               if (isp116x->board->clock)
-                       isp116x->board->clock(hcd->self.controller, 1);
-               msleep(1);
-               isp116x->board->reset(hcd->self.controller, 0);
-       } else
-               ret = isp116x_sw_reset(isp116x);
-
+       ret = isp116x_sw_reset(isp116x);
        if (ret)
                return ret;
 
@@ -1501,10 +1493,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
                ERR("Clock not ready after 20ms\n");
                /* After sw_reset the clock won't report to be ready, if
                   H_WAKEUP pin is high. */
-               if (!isp116x->board || !isp116x->board->reset)
-                       ERR("The driver does not support hardware wakeup.\n");
-                       ERR("Please make sure that the H_WAKEUP pin "
-                               "is pulled low!\n");
+               ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");
                ret = -ENODEV;
        }
        return ret;
@@ -1527,15 +1516,7 @@ static void isp116x_stop(struct usb_hcd *hcd)
        isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
        spin_unlock_irqrestore(&isp116x->lock, flags);
 
-       /* Put the chip into reset state */
-       if (isp116x->board && isp116x->board->reset)
-               isp116x->board->reset(hcd->self.controller, 0);
-       else
-               isp116x_sw_reset(isp116x);
-
-       /* Stop the clock */
-       if (isp116x->board && isp116x->board->clock)
-               isp116x->board->clock(hcd->self.controller, 0);
+       isp116x_sw_reset(isp116x);
 }
 
 /*
@@ -1561,6 +1542,9 @@ static int isp116x_start(struct usb_hcd *hcd)
                return -ENODEV;
        }
 
+       /* To be removed in future */
+       hcd->uses_new_polling = 1;
+
        isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
        isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
 
@@ -1569,7 +1553,7 @@ static int isp116x_start(struct usb_hcd *hcd)
        if (board->sel15Kres)
                val |= HCHWCFG_15KRSEL;
        /* Remote wakeup won't work without working clock */
-       if (board->clknotstop || board->remote_wakeup_enable)
+       if (board->remote_wakeup_enable)
                val |= HCHWCFG_CLKNOTSTOP;
        if (board->oc_enable)
                val |= HCHWCFG_ANALOG_OC;
@@ -1580,16 +1564,13 @@ static int isp116x_start(struct usb_hcd *hcd)
        isp116x_write_reg16(isp116x, HCHWCFG, val);
 
        /* ----- Root hub conf */
-       val = 0;
-       /* AN10003_1.pdf recommends NPS to be always 1 */
-       if (board->no_power_switching)
-               val |= RH_A_NPS;
-       if (board->power_switching_mode)
-               val |= RH_A_PSM;
-       if (board->potpg)
-               val |= (board->potpg << 24) & RH_A_POTPGT;
-       else
-               val |= (25 << 24) & RH_A_POTPGT;
+       val = (25 << 24) & RH_A_POTPGT;
+       /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
+          be always set. Yet, instead, we request individual port
+          power switching. */
+       val |= RH_A_PSM;
+       /* Report overcurrent per port */
+       val |= RH_A_OCPM;
        isp116x_write_reg32(isp116x, HCRHDESCA, val);
        isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
 
@@ -1619,9 +1600,6 @@ static int isp116x_start(struct usb_hcd *hcd)
 
        /* Go operational */
        val = HCCONTROL_USB_OPER;
-       /* Remote wakeup connected - NOT SUPPORTED */
-       /*  if (board->remote_wakeup_connected)
-          val |= HCCONTROL_RWC;  */
        if (board->remote_wakeup_enable)
                val |= HCCONTROL_RWE;
        isp116x_write_reg32(isp116x, HCCONTROL, val);
@@ -1670,7 +1648,7 @@ static int __init_or_module isp116x_remove(struct device *dev)
        struct platform_device *pdev;
        struct resource *res;
 
-       if(!hcd)
+       if (!hcd)
                return 0;
        isp116x = hcd_to_isp116x(hcd);
        pdev = container_of(dev, struct platform_device, dev);
index 17964c39d06a0b3e88192a128017cea3038d1d97..2515333630283fee0aeb83ccb84cadfbc84422a4 100644 (file)
@@ -14,8 +14,6 @@
  * This file is licenced under the GPL.
  */
 
-#include <asm/usb.h>
-
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
 
@@ -23,9 +21,7 @@
  * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
  * Context: !in_interrupt()
  *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
+ * Allocates basic resources for this USB host controller.
  *
  * Store this function in the HCD's struct pci_driver as probe().
  */
@@ -37,7 +33,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
        struct ohci_hcd *ohci;
        struct resource *res;
        int irq;
-       struct usb_hcd_platform_data *pd = pdev->dev.platform_data;
 
        pr_debug("initializing PPC-SOC USB Controller\n");
 
@@ -73,9 +68,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
                goto err2;
        }
 
-       if (pd->start && (retval = pd->start(pdev)))
-               goto err3;
-
        ohci = hcd_to_ohci(hcd);
        ohci->flags |= OHCI_BIG_ENDIAN;
        ohci_hcd_init(ohci);
@@ -85,9 +77,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
                return retval;
 
        pr_debug("Removing PPC-SOC USB Controller\n");
-       if (pd && pd->stop)
-               pd->stop(pdev);
- err3:
+
        iounmap(hcd->regs);
  err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -105,25 +95,21 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
  * @pdev: USB Host Controller being removed
  * Context: !in_interrupt()
  *
- * Reverses the effect of usb_hcd_ppc_soc_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
+ * Reverses the effect of usb_hcd_ppc_soc_probe().
+ * It is always called from a thread
  * context, normally "rmmod", "apmd", or something similar.
  *
  */
 static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd,
                struct platform_device *pdev)
 {
-       struct usb_hcd_platform_data *pd = pdev->dev.platform_data;
-
        usb_remove_hcd(hcd);
 
        pr_debug("stopping PPC-SOC USB Controller\n");
-       if (pd && pd->stop)
-               pd->stop(pdev);
 
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-       usb_hcd_put(hcd);
+       usb_put_hcd(hcd);
 }
 
 static int __devinit
index e9401662503cd62156be6885c42960ce5b46996f..3d9bcf78a9a4f6ed0b9084ac220779342f009c40 100644 (file)
@@ -129,7 +129,7 @@ static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info,
 
        if (info->power_control != NULL) {
                info->port[port-1].power = to;
-               (info->power_control)(port, to);
+               (info->power_control)(port-1, to);
        }
 }
 
@@ -339,8 +339,8 @@ int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
        struct usb_hcd *hcd = NULL;
        int retval;
 
-       s3c2410_usb_set_power(dev->dev.platform_data, 0, 1);
        s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
+       s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);
 
        hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
        if (hcd == NULL)
index 298e4a25e3d38e5d2187d7087212bba2c7d88c63..482c4be521f55424a68efe4cc328e93cd595c1cd 100644 (file)
@@ -230,6 +230,20 @@ config USB_EGALAX
          To compile this driver as a module, choose M here: the
          module will be called touchkitusb.
 
+config USB_YEALINK
+       tristate "Yealink usb-p1k voip phone"
+       depends on USB && INPUT && EXPERIMENTAL
+       ---help---
+         Say Y here if you want to enable keyboard and LCD functions of the
+         Yealink usb-p1k usb phones. The audio part is enabled by the generic
+         usb sound driver, so you might want to enable that as well.
+
+         For information about how to use these additional functions, see
+         <file:Documentation/input/yealink.txt>.
+
+         To compile this driver as a module, choose M here: the module will be
+         called yealink.
+
 config USB_XPAD
        tristate "X-Box gamepad support"
        depends on USB && INPUT
index f1547be632d41f10f5a71f486f71ce917e90a943..43b2f999edfeb448bccb7bf5f73962b1e3ad66da 100644 (file)
@@ -39,4 +39,5 @@ obj-$(CONFIG_USB_EGALAX)      += touchkitusb.o
 obj-$(CONFIG_USB_POWERMATE)    += powermate.o
 obj-$(CONFIG_USB_WACOM)                += wacom.o
 obj-$(CONFIG_USB_ACECAD)       += acecad.o
+obj-$(CONFIG_USB_YEALINK)      += yealink.o
 obj-$(CONFIG_USB_XPAD)         += xpad.o
index b2cb2b35892e51eb57ebd80f7071f556831f5949..1ab95d24c5e25c8715078538ff6176b2b4f01883 100644 (file)
@@ -1444,6 +1444,8 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_DEVICE_ID_NETWORKANALYSER  0x2020
 #define USB_DEVICE_ID_POWERCONTROL     0x2030
 
+#define USB_VENDOR_ID_APPLE            0x05ac
+#define USB_DEVICE_ID_APPLE_BLUETOOTH          0x1000
 
 /*
  * Alphabetically sorted blacklist by quirk type.
@@ -1462,6 +1464,7 @@ static struct hid_blacklist {
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_BLUETOOTH, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
@@ -1685,7 +1688,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
                        usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
                                         hid_irq_in, hid, interval);
                        hid->urbin->transfer_dma = hid->inbuf_dma;
-                       hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
+                       hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                } else {
                        if (hid->urbout)
                                continue;
@@ -1695,7 +1698,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
                        usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
                                         hid_irq_out, hid, interval);
                        hid->urbout->transfer_dma = hid->outbuf_dma;
-                       hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
+                       hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                }
        }
 
@@ -1747,7 +1750,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
                             hid->ctrlbuf, 1, hid_ctrl, hid);
        hid->urbctrl->setup_dma = hid->cr_dma;
        hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
-       hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK);
+       hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
        return hid;
 
index 67dc93685203897a063679efbae0f0a55b3d5bda..99de1b33c07df3a754072f326f5efbfba816b8c4 100644 (file)
@@ -431,11 +431,6 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
        struct usb_endpoint_descriptor *endpoint;
        struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
 
-       /* See if the offered device matches what we can accept */
-       if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) ||
-           (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) )
-               return -ENODEV;
-
        /* allocate memory for our device state and initialize it */
        remote = kmalloc(sizeof(*remote), GFP_KERNEL);
        if (remote == NULL) {
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h
new file mode 100644 (file)
index 0000000..52ff27f
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * drivers/usb/input/map_to_7segment.h
+ *
+ * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * 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-1307 USA
+ */
+
+#ifndef MAP_TO_7SEGMENT_H
+#define MAP_TO_7SEGMENT_H
+
+/* This file provides translation primitives and tables for the conversion
+ * of (ASCII) characters to a 7-segments notation.
+ *
+ * The 7 segment's wikipedia notation below is used as standard.
+ * See: http://en.wikipedia.org/wiki/Seven_segment_display
+ *
+ * Notation:   +-a-+
+ *             f   b
+ *             +-g-+
+ *             e   c
+ *             +-d-+
+ *
+ * Usage:
+ *
+ *   Register a map variable, and fill it with a character set:
+ *     static SEG7_DEFAULT_MAP(map_seg7);
+ *
+ *
+ *   Then use for conversion:
+ *     seg7 = map_to_seg7(&map_seg7, some_char);
+ *     ...
+ *
+ * In device drivers it is recommended, if required, to make the char map
+ * accessible via the sysfs interface using the following scheme:
+ *
+ * static ssize_t show_map(struct device *dev, char *buf) {
+ *     memcpy(buf, &map_seg7, sizeof(map_seg7));
+ *     return sizeof(map_seg7);
+ * }
+ * static ssize_t store_map(struct device *dev, const char *buf, size_t cnt) {
+ *     if(cnt != sizeof(map_seg7))
+ *             return -EINVAL;
+ *     memcpy(&map_seg7, buf, cnt);
+ *     return cnt;
+ * }
+ * static DEVICE_ATTR(map_seg7, PERMS_RW, show_map, store_map);
+ *
+ * History:
+ * 2005-05-31  RFC linux-kernel@vger.kernel.org
+ */
+#include <linux/errno.h>
+
+
+#define BIT_SEG7_A             0
+#define BIT_SEG7_B             1
+#define BIT_SEG7_C             2
+#define BIT_SEG7_D             3
+#define BIT_SEG7_E             4
+#define BIT_SEG7_F             5
+#define BIT_SEG7_G             6
+#define BIT_SEG7_RESERVED      7
+
+struct seg7_conversion_map {
+       unsigned char   table[128];
+};
+
+static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
+{
+       return c & 0x7f ? map->table[c] : -EINVAL;
+}
+
+#define SEG7_CONVERSION_MAP(_name, _map)       \
+       struct seg7_conversion_map _name = { .table = { _map } }
+
+/*
+ * It is recommended to use a facility that allows user space to redefine
+ * custom character sets for LCD devices. Please use a sysfs interface
+ * as described above.
+ */
+#define MAP_TO_SEG7_SYSFS_FILE "map_seg7"
+
+/*******************************************************************************
+ * ASCII conversion table
+ ******************************************************************************/
+
+#define _SEG7(l,a,b,c,d,e,f,g) \
+      (        a<<BIT_SEG7_A | b<<BIT_SEG7_B | c<<BIT_SEG7_C | d<<BIT_SEG7_D | \
+       e<<BIT_SEG7_E | f<<BIT_SEG7_F | g<<BIT_SEG7_G )
+
+#define _MAP_0_32_ASCII_SEG7_NON_PRINTABLE     \
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+
+#define _MAP_33_47_ASCII_SEG7_SYMBOL           \
+ _SEG7('!',0,0,0,0,1,1,0), _SEG7('"',0,1,0,0,0,1,0), _SEG7('#',0,1,1,0,1,1,0),\
+ _SEG7('$',1,0,1,1,0,1,1), _SEG7('%',0,0,1,0,0,1,0), _SEG7('&',1,0,1,1,1,1,1),\
+ _SEG7('\'',0,0,0,0,0,1,0),_SEG7('(',1,0,0,1,1,1,0), _SEG7(')',1,1,1,1,0,0,0),\
+ _SEG7('*',0,1,1,0,1,1,1), _SEG7('+',0,1,1,0,0,0,1), _SEG7(',',0,0,0,0,1,0,0),\
+ _SEG7('-',0,0,0,0,0,0,1), _SEG7('.',0,0,0,0,1,0,0), _SEG7('/',0,1,0,0,1,0,1),
+
+#define _MAP_48_57_ASCII_SEG7_NUMERIC          \
+ _SEG7('0',1,1,1,1,1,1,0), _SEG7('1',0,1,1,0,0,0,0), _SEG7('2',1,1,0,1,1,0,1),\
+ _SEG7('3',1,1,1,1,0,0,1), _SEG7('4',0,1,1,0,0,1,1), _SEG7('5',1,0,1,1,0,1,1),\
+ _SEG7('6',1,0,1,1,1,1,1), _SEG7('7',1,1,1,0,0,0,0), _SEG7('8',1,1,1,1,1,1,1),\
+ _SEG7('9',1,1,1,1,0,1,1),
+
+#define _MAP_58_64_ASCII_SEG7_SYMBOL           \
+ _SEG7(':',0,0,0,1,0,0,1), _SEG7(';',0,0,0,1,0,0,1), _SEG7('<',1,0,0,0,0,1,1),\
+ _SEG7('=',0,0,0,1,0,0,1), _SEG7('>',1,1,0,0,0,0,1), _SEG7('?',1,1,1,0,0,1,0),\
+ _SEG7('@',1,1,0,1,1,1,1),
+
+#define _MAP_65_90_ASCII_SEG7_ALPHA_UPPR       \
+ _SEG7('A',1,1,1,0,1,1,1), _SEG7('B',1,1,1,1,1,1,1), _SEG7('C',1,0,0,1,1,1,0),\
+ _SEG7('D',1,1,1,1,1,1,0), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
+ _SEG7('G',1,1,1,1,0,1,1), _SEG7('H',0,1,1,0,1,1,1), _SEG7('I',0,1,1,0,0,0,0),\
+ _SEG7('J',0,1,1,1,0,0,0), _SEG7('K',0,1,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
+ _SEG7('M',1,1,1,0,1,1,0), _SEG7('N',1,1,1,0,1,1,0), _SEG7('O',1,1,1,1,1,1,0),\
+ _SEG7('P',1,1,0,0,1,1,1), _SEG7('Q',1,1,1,1,1,1,0), _SEG7('R',1,1,1,0,1,1,1),\
+ _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('U',0,1,1,1,1,1,0),\
+ _SEG7('V',0,1,1,1,1,1,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
+ _SEG7('Y',0,1,1,0,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
+
+#define _MAP_91_96_ASCII_SEG7_SYMBOL           \
+ _SEG7('[',1,0,0,1,1,1,0), _SEG7('\\',0,0,1,0,0,1,1),_SEG7(']',1,1,1,1,0,0,0),\
+ _SEG7('^',1,1,0,0,0,1,0), _SEG7('_',0,0,0,1,0,0,0), _SEG7('`',0,1,0,0,0,0,0),
+
+#define _MAP_97_122_ASCII_SEG7_ALPHA_LOWER     \
+ _SEG7('A',1,1,1,0,1,1,1), _SEG7('b',0,0,1,1,1,1,1), _SEG7('c',0,0,0,1,1,0,1),\
+ _SEG7('d',0,1,1,1,1,0,1), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
+ _SEG7('G',1,1,1,1,0,1,1), _SEG7('h',0,0,1,0,1,1,1), _SEG7('i',0,0,1,0,0,0,0),\
+ _SEG7('j',0,0,1,1,0,0,0), _SEG7('k',0,0,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
+ _SEG7('M',1,1,1,0,1,1,0), _SEG7('n',0,0,1,0,1,0,1), _SEG7('o',0,0,1,1,1,0,1),\
+ _SEG7('P',1,1,0,0,1,1,1), _SEG7('q',1,1,1,0,0,1,1), _SEG7('r',0,0,0,0,1,0,1),\
+ _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('u',0,0,1,1,1,0,0),\
+ _SEG7('v',0,0,1,1,1,0,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
+ _SEG7('y',0,1,1,1,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
+
+#define _MAP_123_126_ASCII_SEG7_SYMBOL         \
+ _SEG7('{',1,0,0,1,1,1,0), _SEG7('|',0,0,0,0,1,1,0), _SEG7('}',1,1,1,1,0,0,0),\
+ _SEG7('~',1,0,0,0,0,0,0),
+
+/* Maps */
+
+/* This set tries to map as close as possible to the visible characteristics
+ * of the ASCII symbol, lowercase and uppercase letters may differ in
+ * presentation on the display.
+ */
+#define MAP_ASCII7SEG_ALPHANUM                 \
+       _MAP_0_32_ASCII_SEG7_NON_PRINTABLE      \
+       _MAP_33_47_ASCII_SEG7_SYMBOL            \
+       _MAP_48_57_ASCII_SEG7_NUMERIC           \
+       _MAP_58_64_ASCII_SEG7_SYMBOL            \
+       _MAP_65_90_ASCII_SEG7_ALPHA_UPPR        \
+       _MAP_91_96_ASCII_SEG7_SYMBOL            \
+       _MAP_97_122_ASCII_SEG7_ALPHA_LOWER      \
+       _MAP_123_126_ASCII_SEG7_SYMBOL
+
+/* This set tries to map as close as possible to the symbolic characteristics
+ * of the ASCII character for maximum discrimination.
+ * For now this means all alpha chars are in lower case representations.
+ * (This for example facilitates the use of hex numbers with uppercase input.)
+ */
+#define MAP_ASCII7SEG_ALPHANUM_LC                      \
+       _MAP_0_32_ASCII_SEG7_NON_PRINTABLE      \
+       _MAP_33_47_ASCII_SEG7_SYMBOL            \
+       _MAP_48_57_ASCII_SEG7_NUMERIC           \
+       _MAP_58_64_ASCII_SEG7_SYMBOL            \
+       _MAP_97_122_ASCII_SEG7_ALPHA_LOWER      \
+       _MAP_91_96_ASCII_SEG7_SYMBOL            \
+       _MAP_97_122_ASCII_SEG7_ALPHA_LOWER      \
+       _MAP_123_126_ASCII_SEG7_SYMBOL
+
+#define SEG7_DEFAULT_MAP(_name)                \
+       SEG7_CONVERSION_MAP(_name,MAP_ASCII7SEG_ALPHANUM)
+
+#endif /* MAP_TO_7SEGMENT_H */
+
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
new file mode 100644 (file)
index 0000000..58a176e
--- /dev/null
@@ -0,0 +1,1013 @@
+/*
+ * drivers/usb/input/yealink.c
+ *
+ * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * 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-1307 USA
+ */
+/*
+ * Description:
+ *   Driver for the USB-P1K voip usb phone.
+ *   This device is produced by Yealink Network Technology Co Ltd
+ *   but may be branded under several names:
+ *     - Yealink usb-p1k
+ *     - Tiptel 115
+ *     - ...
+ *
+ * This driver is based on:
+ *   - the usbb2k-api  http://savannah.nongnu.org/projects/usbb2k-api/
+ *   - information from        http://memeteau.free.fr/usbb2k
+ *   - the xpad-driver drivers/usb/input/xpad.c
+ *
+ * Thanks to:
+ *   - Olivier Vandorpe, for providing the usbb2k-api.
+ *   - Martin Diehl, for spotting my memory allocation bug.
+ *
+ * History:
+ *   20050527 henk     First version, functional keyboard. Keyboard events
+ *                     will pop-up on the ../input/eventX bus.
+ *   20050531 henk     Added led, LCD, dialtone and sysfs interface.
+ *   20050610 henk     Cleanups, make it ready for public consumption.
+ *   20050630 henk     Cleanups, fixes in response to comments.
+ *   20050701 henk     sysfs write serialisation, fix potential unload races
+ *   20050801 henk     Added ringtone, restructure USB
+ *   20050816 henk     Merge 2.6.13-rc6
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/rwsem.h>
+#include <linux/usb.h>
+
+#include "map_to_7segment.h"
+#include "yealink.h"
+
+#define DRIVER_VERSION "yld-20050816"
+#define DRIVER_AUTHOR "Henk Vergonet"
+#define DRIVER_DESC "Yealink phone driver"
+
+#define YEALINK_POLLING_FREQUENCY      10      /* in [Hz] */
+
+struct yld_status {
+       u8      lcd[24];
+       u8      led;
+       u8      dialtone;
+       u8      ringtone;
+       u8      keynum;
+} __attribute__ ((packed));
+
+/*
+ * Register the LCD segment and icon map
+ */
+#define _LOC(k,l)      { .a = (k), .m = (l) }
+#define _SEG(t, a, am, b, bm, c, cm, d, dm, e, em, f, fm, g, gm)       \
+       { .type = (t),                                                  \
+         .u = { .s = { _LOC(a, am), _LOC(b, bm), _LOC(c, cm),          \
+                       _LOC(d, dm), _LOC(e, em), _LOC(g, gm),          \
+                       _LOC(f, fm) } } }
+#define _PIC(t, h, hm, n)                                              \
+       { .type = (t),                                                  \
+         .u = { .p = { .name = (n), .a = (h), .m = (hm) } } }
+
+static const struct lcd_segment_map {
+       char    type;
+       union {
+               struct pictogram_map {
+                       u8      a,m;
+                       char    name[10];
+               }       p;
+               struct segment_map {
+                       u8      a,m;
+               } s[7];
+       } u;
+} lcdMap[] = {
+#include "yealink.h"
+};
+
+struct yealink_dev {
+       struct input_dev idev;          /* input device */
+       struct usb_device *udev;        /* usb device */
+
+       /* irq input channel */
+       struct yld_ctl_packet   *irq_data;
+       dma_addr_t              irq_dma;
+       struct urb              *urb_irq;
+
+       /* control output channel */
+       struct yld_ctl_packet   *ctl_data;
+       dma_addr_t              ctl_dma;
+       struct usb_ctrlrequest  *ctl_req;
+       dma_addr_t              ctl_req_dma;
+       struct urb              *urb_ctl;
+
+       char phys[64];                  /* physical device path */
+
+       u8 lcdMap[ARRAY_SIZE(lcdMap)];  /* state of LCD, LED ... */
+       int key_code;                   /* last reported key     */
+
+       int     stat_ix;
+       union {
+               struct yld_status s;
+               u8                b[sizeof(struct yld_status)];
+       } master, copy;
+};
+
+
+/*******************************************************************************
+ * Yealink lcd interface
+ ******************************************************************************/
+
+/*
+ * Register a default 7 segment character set
+ */
+static SEG7_DEFAULT_MAP(map_seg7);
+
+ /* Display a char,
+  * char '\9' and '\n' are placeholders and do not overwrite the original text.
+  * A space will always hide an icon.
+  */
+static int setChar(struct yealink_dev *yld, int el, int chr)
+{
+       int i, a, m, val;
+
+       if (el >= ARRAY_SIZE(lcdMap))
+               return -EINVAL;
+
+       if (chr == '\t' || chr == '\n')
+           return 0;
+
+       yld->lcdMap[el] = chr;
+
+       if (lcdMap[el].type == '.') {
+               a = lcdMap[el].u.p.a;
+               m = lcdMap[el].u.p.m;
+               if (chr != ' ')
+                       yld->master.b[a] |= m;
+               else
+                       yld->master.b[a] &= ~m;
+               return 0;
+       }
+
+       val = map_to_seg7(&map_seg7, chr);
+       for (i = 0; i < ARRAY_SIZE(lcdMap[0].u.s); i++) {
+               m = lcdMap[el].u.s[i].m;
+
+               if (m == 0)
+                       continue;
+
+               a = lcdMap[el].u.s[i].a;
+               if (val & 1)
+                       yld->master.b[a] |= m;
+               else
+                       yld->master.b[a] &= ~m;
+               val = val >> 1;
+       }
+       return 0;
+};
+
+/*******************************************************************************
+ * Yealink key interface
+ ******************************************************************************/
+
+/* Map device buttons to internal key events.
+ *
+ * USB-P1K button layout:
+ *
+ *             up
+ *       IN           OUT
+ *            down
+ *
+ *     pickup   C    hangup
+ *       1      2      3
+ *       4      5      6
+ *       7      8      9
+ *       *      0      #
+ *
+ * The "up" and "down" keys, are symbolised by arrows on the button.
+ * The "pickup" and "hangup" keys are symbolised by a green and red phone
+ * on the button.
+ */
+static int map_p1k_to_key(int scancode)
+{
+       switch(scancode) {              /* phone key:   */
+       case 0x23: return KEY_LEFT;     /*   IN         */
+       case 0x33: return KEY_UP;       /*   up         */
+       case 0x04: return KEY_RIGHT;    /*   OUT        */
+       case 0x24: return KEY_DOWN;     /*   down       */
+       case 0x03: return KEY_ENTER;    /*   pickup     */
+       case 0x14: return KEY_BACKSPACE; /*  C          */
+       case 0x13: return KEY_ESC;      /*   hangup     */
+       case 0x00: return KEY_1;        /*   1          */
+       case 0x01: return KEY_2;        /*   2          */
+       case 0x02: return KEY_3;        /*   3          */
+       case 0x10: return KEY_4;        /*   4          */
+       case 0x11: return KEY_5;        /*   5          */
+       case 0x12: return KEY_6;        /*   6          */
+       case 0x20: return KEY_7;        /*   7          */
+       case 0x21: return KEY_8;        /*   8          */
+       case 0x22: return KEY_9;        /*   9          */
+       case 0x30: return KEY_KPASTERISK; /* *          */
+       case 0x31: return KEY_0;        /*   0          */
+       case 0x32: return KEY_LEFTSHIFT |
+                         KEY_3 << 8;   /*   #          */
+       }
+       return -EINVAL;
+}
+
+/* Completes a request by converting the data into events for the
+ * input subsystem.
+ *
+ * The key parameter can be cascaded: key2 << 8 | key1
+ */
+static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
+{
+       struct input_dev *idev = &yld->idev;
+
+       input_regs(idev, regs);
+       if (yld->key_code >= 0) {
+               /* old key up */
+               input_report_key(idev, yld->key_code & 0xff, 0);
+               if (yld->key_code >> 8)
+                       input_report_key(idev, yld->key_code >> 8, 0);
+       }
+
+       yld->key_code = key;
+       if (key >= 0) {
+               /* new valid key */
+               input_report_key(idev, key & 0xff, 1);
+               if (key >> 8)
+                       input_report_key(idev, key >> 8, 1);
+       }
+       input_sync(idev);
+}
+
+/*******************************************************************************
+ * Yealink usb communication interface
+ ******************************************************************************/
+
+static int yealink_cmd(struct yealink_dev *yld, struct yld_ctl_packet *p)
+{
+       u8      *buf = (u8 *)p;
+       int     i;
+       u8      sum = 0;
+
+       for(i=0; i<USB_PKT_LEN-1; i++)
+               sum -= buf[i];
+       p->sum = sum;
+       return usb_control_msg(yld->udev,
+                       usb_sndctrlpipe(yld->udev, 0),
+                       USB_REQ_SET_CONFIGURATION,
+                       USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                       0x200, 3,
+                       p, sizeof(*p),
+                       USB_CTRL_SET_TIMEOUT);
+}
+
+static u8 default_ringtone[] = {
+       0xEF,                   /* volume [0-255] */
+       0xFB, 0x1E, 0x00, 0x0C, /* 1250 [hz], 12/100 [s] */
+       0xFC, 0x18, 0x00, 0x0C, /* 1000 [hz], 12/100 [s] */
+       0xFB, 0x1E, 0x00, 0x0C,
+       0xFC, 0x18, 0x00, 0x0C,
+       0xFB, 0x1E, 0x00, 0x0C,
+       0xFC, 0x18, 0x00, 0x0C,
+       0xFB, 0x1E, 0x00, 0x0C,
+       0xFC, 0x18, 0x00, 0x0C,
+       0xFF, 0xFF, 0x01, 0x90, /* silent, 400/100 [s] */
+       0x00, 0x00              /* end of sequence */
+};
+
+static int yealink_set_ringtone(struct yealink_dev *yld, u8 *buf, size_t size)
+{
+       struct yld_ctl_packet *p = yld->ctl_data;
+       int     ix, len;
+
+       if (size <= 0)
+               return -EINVAL;
+
+       /* Set the ringtone volume */
+       memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
+       yld->ctl_data->cmd      = CMD_RING_VOLUME;
+       yld->ctl_data->size     = 1;
+       yld->ctl_data->data[0]  = buf[0];
+       yealink_cmd(yld, p);
+
+       buf++;
+       size--;
+
+       p->cmd = CMD_RING_NOTE;
+       ix = 0;
+       while (size != ix) {
+               len = size - ix;
+               if (len > sizeof(p->data))
+                       len = sizeof(p->data);
+               p->size   = len;
+               p->offset = cpu_to_be16(ix);
+               memcpy(p->data, &buf[ix], len);
+               yealink_cmd(yld, p);
+               ix += len;
+       }
+       return 0;
+}
+
+/* keep stat_master & stat_copy in sync.
+ */
+static int yealink_do_idle_tasks(struct yealink_dev *yld)
+{
+       u8 val;
+       int i, ix, len;
+
+       ix = yld->stat_ix;
+
+       memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
+       yld->ctl_data->cmd  = CMD_KEYPRESS;
+       yld->ctl_data->size = 1;
+       yld->ctl_data->sum  = 0xff - CMD_KEYPRESS;
+
+       /* If state update pointer wraps do a KEYPRESS first. */
+       if (ix >= sizeof(yld->master)) {
+               yld->stat_ix = 0;
+               return 0;
+       }
+
+       /* find update candidates: copy != master */
+       do {
+               val = yld->master.b[ix];
+               if (val != yld->copy.b[ix])
+                       goto send_update;
+       } while (++ix < sizeof(yld->master));
+
+       /* nothing todo, wait a bit and poll for a KEYPRESS */
+       yld->stat_ix = 0;
+       /* TODO how can we wait abit. ??
+        * msleep_interruptible(1000 / YEALINK_POLLING_FREQUENCY);
+        */
+       return 0;
+
+send_update:
+
+       /* Setup an appropriate update request */
+       yld->copy.b[ix] = val;
+       yld->ctl_data->data[0] = val;
+
+       switch(ix) {
+       case offsetof(struct yld_status, led):
+               yld->ctl_data->cmd      = CMD_LED;
+               yld->ctl_data->sum      = -1 - CMD_LED - val;
+               break;
+       case offsetof(struct yld_status, dialtone):
+               yld->ctl_data->cmd      = CMD_DIALTONE;
+               yld->ctl_data->sum      = -1 - CMD_DIALTONE - val;
+               break;
+       case offsetof(struct yld_status, ringtone):
+               yld->ctl_data->cmd      = CMD_RINGTONE;
+               yld->ctl_data->sum      = -1 - CMD_RINGTONE - val;
+               break;
+       case offsetof(struct yld_status, keynum):
+               val--;
+               val &= 0x1f;
+               yld->ctl_data->cmd      = CMD_SCANCODE;
+               yld->ctl_data->offset   = cpu_to_be16(val);
+               yld->ctl_data->data[0]  = 0;
+               yld->ctl_data->sum      = -1 - CMD_SCANCODE - val;
+               break;
+       default:
+               len = sizeof(yld->master.s.lcd) - ix;
+               if (len > sizeof(yld->ctl_data->data))
+                       len = sizeof(yld->ctl_data->data);
+
+               /* Combine up to <len> consecutive LCD bytes in a singe request
+                */
+               yld->ctl_data->cmd      = CMD_LCD;
+               yld->ctl_data->offset   = cpu_to_be16(ix);
+               yld->ctl_data->size     = len;
+               yld->ctl_data->sum      = -CMD_LCD - ix - val - len;
+               for(i=1; i<len; i++) {
+                       ix++;
+                       val = yld->master.b[ix];
+                       yld->copy.b[ix]         = val;
+                       yld->ctl_data->data[i]  = val;
+                       yld->ctl_data->sum     -= val;
+               }
+       }
+       yld->stat_ix = ix + 1;
+       return 1;
+}
+
+/* Decide on how to handle responses
+ *
+ * The state transition diagram is somethhing like:
+ *
+ *          syncState<--+
+ *               |      |
+ *               |    idle
+ *              \|/     |
+ * init --ok--> waitForKey --ok--> getKey
+ *  ^               ^                |
+ *  |               +-------ok-------+
+ * error,start
+ *
+ */
+static void urb_irq_callback(struct urb *urb, struct pt_regs *regs)
+{
+       struct yealink_dev *yld = urb->context;
+       int ret;
+
+       if (urb->status)
+               err("%s - urb status %d", __FUNCTION__, urb->status);
+
+       switch (yld->irq_data->cmd) {
+       case CMD_KEYPRESS:
+
+               yld->master.s.keynum = yld->irq_data->data[0];
+               break;
+
+       case CMD_SCANCODE:
+               dbg("get scancode %x", yld->irq_data->data[0]);
+
+               report_key(yld, map_p1k_to_key(yld->irq_data->data[0]), regs);
+               break;
+
+       default:
+               err("unexpected response %x", yld->irq_data->cmd);
+       }
+
+       yealink_do_idle_tasks(yld);
+
+       ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+       if (ret)
+               err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+}
+
+static void urb_ctl_callback(struct urb *urb, struct pt_regs *regs)
+{
+       struct yealink_dev *yld = urb->context;
+       int ret;
+
+       if (urb->status)
+               err("%s - urb status %d", __FUNCTION__, urb->status);
+
+       switch (yld->ctl_data->cmd) {
+       case CMD_KEYPRESS:
+       case CMD_SCANCODE:
+               /* ask for a response */
+               ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
+               break;
+       default:
+               /* send new command */
+               yealink_do_idle_tasks(yld);
+               ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+       }
+
+       if (ret)
+               err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+}
+
+/*******************************************************************************
+ * input event interface
+ ******************************************************************************/
+
+/* TODO should we issue a ringtone on a SND_BELL event?
+static int input_ev(struct input_dev *dev, unsigned int type,
+               unsigned int code, int value)
+{
+
+       if (type != EV_SND)
+               return -EINVAL;
+
+       switch (code) {
+       case SND_BELL:
+       case SND_TONE:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+*/
+
+static int input_open(struct input_dev *dev)
+{
+       struct yealink_dev *yld = dev->private;
+       int i, ret;
+
+       dbg("%s", __FUNCTION__);
+
+       /* force updates to device */
+       for (i = 0; i<sizeof(yld->master); i++)
+               yld->copy.b[i] = ~yld->master.b[i];
+       yld->key_code = -1;     /* no keys pressed */
+
+        yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
+
+       /* issue INIT */
+       memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
+       yld->ctl_data->cmd      = CMD_INIT;
+       yld->ctl_data->size     = 10;
+       yld->ctl_data->sum      = 0x100-CMD_INIT-10;
+       if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
+               dbg("%s - usb_submit_urb failed with result %d",
+                    __FUNCTION__, ret);
+               return ret;
+       }
+       return 0;
+}
+
+static void input_close(struct input_dev *dev)
+{
+       struct yealink_dev *yld = dev->private;
+
+       usb_kill_urb(yld->urb_ctl);
+       usb_kill_urb(yld->urb_irq);
+}
+
+/*******************************************************************************
+ * sysfs interface
+ ******************************************************************************/
+
+static DECLARE_RWSEM(sysfs_rwsema);
+
+/* Interface to the 7-segments translation table aka. char set.
+ */
+static ssize_t show_map(struct device *dev, struct device_attribute *attr,
+                               char *buf)
+{
+       memcpy(buf, &map_seg7, sizeof(map_seg7));
+       return sizeof(map_seg7);
+}
+
+static ssize_t store_map(struct device *dev, struct device_attribute *attr,
+                               const char *buf, size_t cnt)
+{
+       if (cnt != sizeof(map_seg7))
+               return -EINVAL;
+       memcpy(&map_seg7, buf, sizeof(map_seg7));
+       return sizeof(map_seg7);
+}
+
+/* Interface to the LCD.
+ */
+
+/* Reading /sys/../lineX will return the format string with its settings:
+ *
+ * Example:
+ * cat ./line3
+ * 888888888888
+ * Linux Rocks!
+ */
+static ssize_t show_line(struct device *dev, char *buf, int a, int b)
+{
+       struct yealink_dev *yld;
+       int i;
+
+       down_read(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld == NULL) {
+               up_read(&sysfs_rwsema);
+               return -ENODEV;
+       }
+
+       for (i = a; i < b; i++)
+               *buf++ = lcdMap[i].type;
+       *buf++ = '\n';
+       for (i = a; i < b; i++)
+               *buf++ = yld->lcdMap[i];
+       *buf++ = '\n';
+       *buf = 0;
+
+       up_read(&sysfs_rwsema);
+       return 3 + ((b - a) << 1);
+}
+
+static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
+}
+
+static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
+}
+
+static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
+}
+
+/* Writing to /sys/../lineX will set the coresponding LCD line.
+ * - Excess characters are ignored.
+ * - If less characters are written than allowed, the remaining digits are
+ *   unchanged.
+ * - The '\n' or '\t' char is a placeholder, it does not overwrite the
+ *   original content.
+ */
+static ssize_t store_line(struct device *dev, const char *buf, size_t count,
+               int el, size_t len)
+{
+       struct yealink_dev *yld;
+       int i;
+
+       down_write(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld == NULL) {
+               up_write(&sysfs_rwsema);
+               return -ENODEV;
+       }
+
+       if (len > count)
+               len = count;
+       for (i = 0; i < len; i++)
+               setChar(yld, el++, buf[i]);
+
+       up_write(&sysfs_rwsema);
+       return count;
+}
+
+static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
+}
+
+static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
+}
+
+static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
+}
+
+/* Interface to visible and audible "icons", these include:
+ * pictures on the LCD, the LED, and the dialtone signal.
+ */
+
+/* Get a list of "switchable elements" with their current state. */
+static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct yealink_dev *yld;
+       int i, ret = 1;
+
+       down_read(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld == NULL) {
+               up_read(&sysfs_rwsema);
+               return -ENODEV;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
+               if (lcdMap[i].type != '.')
+                       continue;
+               ret += sprintf(&buf[ret], "%s %s\n",
+                               yld->lcdMap[i] == ' ' ? "  " : "on",
+                               lcdMap[i].u.p.name);
+       }
+       up_read(&sysfs_rwsema);
+       return ret;
+}
+
+/* Change the visibility of a particular element. */
+static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
+                       int chr)
+{
+       struct yealink_dev *yld;
+       int i;
+
+       down_write(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld == NULL) {
+               up_write(&sysfs_rwsema);
+               return -ENODEV;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
+               if (lcdMap[i].type != '.')
+                       continue;
+               if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
+                       setChar(yld, i, chr);
+                       break;
+               }
+       }
+
+       up_write(&sysfs_rwsema);
+       return count;
+}
+
+static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       return set_icon(dev, buf, count, buf[0]);
+}
+
+static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       return set_icon(dev, buf, count, ' ');
+}
+
+/* Upload a ringtone to the device.
+ */
+
+/* Stores raw ringtone data in the phone */
+static ssize_t store_ringtone(struct device *dev,
+               struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct yealink_dev *yld;
+
+       down_write(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld == NULL) {
+               up_write(&sysfs_rwsema);
+               return -ENODEV;
+       }
+
+       /* TODO locking with async usb control interface??? */
+       yealink_set_ringtone(yld, (char *)buf, count);
+       up_write(&sysfs_rwsema);
+       return count;
+}
+
+#define _M444  S_IRUGO
+#define _M664  S_IRUGO|S_IWUSR|S_IWGRP
+#define _M220  S_IWUSR|S_IWGRP
+
+static DEVICE_ATTR(map_seg7    , _M664, show_map       , store_map     );
+static DEVICE_ATTR(line1       , _M664, show_line1     , store_line1   );
+static DEVICE_ATTR(line2       , _M664, show_line2     , store_line2   );
+static DEVICE_ATTR(line3       , _M664, show_line3     , store_line3   );
+static DEVICE_ATTR(get_icons   , _M444, get_icons      , NULL          );
+static DEVICE_ATTR(show_icon   , _M220, NULL           , show_icon     );
+static DEVICE_ATTR(hide_icon   , _M220, NULL           , hide_icon     );
+static DEVICE_ATTR(ringtone    , _M220, NULL           , store_ringtone);
+
+static struct attribute *yld_attributes[] = {
+       &dev_attr_line1.attr,
+       &dev_attr_line2.attr,
+       &dev_attr_line3.attr,
+       &dev_attr_get_icons.attr,
+       &dev_attr_show_icon.attr,
+       &dev_attr_hide_icon.attr,
+       &dev_attr_map_seg7.attr,
+       &dev_attr_ringtone.attr,
+       NULL
+};
+
+static struct attribute_group yld_attr_group = {
+       .attrs = yld_attributes
+};
+
+/*******************************************************************************
+ * Linux interface and usb initialisation
+ ******************************************************************************/
+
+static const struct yld_device {
+       u16 idVendor;
+       u16 idProduct;
+       char *name;
+} yld_device[] = {
+       { 0x6993, 0xb001, "Yealink usb-p1k" },
+};
+
+static struct usb_device_id usb_table [] = {
+       { USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) },
+       { }
+};
+
+static int usb_cleanup(struct yealink_dev *yld, int err)
+{
+       if (yld == NULL)
+               return err;
+
+        if (yld->urb_irq) {
+               usb_kill_urb(yld->urb_irq);
+               usb_free_urb(yld->urb_irq);
+       }
+        if (yld->urb_ctl)
+               usb_free_urb(yld->urb_ctl);
+        if (yld->idev.dev)
+               input_unregister_device(&yld->idev);
+       if (yld->ctl_req)
+               usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
+                               yld->ctl_req, yld->ctl_req_dma);
+       if (yld->ctl_data)
+               usb_buffer_free(yld->udev, USB_PKT_LEN,
+                               yld->ctl_data, yld->ctl_dma);
+       if (yld->irq_data)
+               usb_buffer_free(yld->udev, USB_PKT_LEN,
+                               yld->irq_data, yld->irq_dma);
+       kfree(yld);
+       return err;
+}
+
+static void usb_disconnect(struct usb_interface *intf)
+{
+       struct yealink_dev *yld;
+
+       down_write(&sysfs_rwsema);
+       yld = usb_get_intfdata(intf);
+       sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
+       usb_set_intfdata(intf, NULL);
+       up_write(&sysfs_rwsema);
+
+       usb_cleanup(yld, 0);
+}
+
+static int usb_match(struct usb_device *udev)
+{
+       int i;
+       u16 idVendor = le16_to_cpu(udev->descriptor.idVendor);
+       u16 idProduct = le16_to_cpu(udev->descriptor.idProduct);
+
+       for (i = 0; i < ARRAY_SIZE(yld_device); i++) {
+               if ((idVendor == yld_device[i].idVendor) &&
+                   (idProduct == yld_device[i].idProduct))
+                       return i;
+       }
+       return -ENODEV;
+}
+
+static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev (intf);
+       struct usb_host_interface *interface;
+       struct usb_endpoint_descriptor *endpoint;
+       struct yealink_dev *yld;
+       char path[64];
+       int ret, pipe, i;
+
+       i = usb_match(udev);
+       if (i < 0)
+               return -ENODEV;
+
+       interface = intf->cur_altsetting;
+       endpoint = &interface->endpoint[0].desc;
+       if (!(endpoint->bEndpointAddress & 0x80))
+               return -EIO;
+       if ((endpoint->bmAttributes & 3) != 3)
+               return -EIO;
+
+       if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL)
+               return -ENOMEM;
+
+       memset(yld, 0, sizeof(*yld));
+       yld->udev = udev;
+
+       /* allocate usb buffers */
+       yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+                                       SLAB_ATOMIC, &yld->irq_dma);
+       if (yld->irq_data == NULL)
+               return usb_cleanup(yld, -ENOMEM);
+
+       yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+                                       SLAB_ATOMIC, &yld->ctl_dma);
+       if (!yld->ctl_data)
+               return usb_cleanup(yld, -ENOMEM);
+
+       yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
+                                       SLAB_ATOMIC, &yld->ctl_req_dma);
+       if (yld->ctl_req == NULL)
+               return usb_cleanup(yld, -ENOMEM);
+
+       /* allocate urb structures */
+       yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
+        if (yld->urb_irq == NULL)
+               return usb_cleanup(yld, -ENOMEM);
+
+       yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
+        if (yld->urb_ctl == NULL)
+               return usb_cleanup(yld, -ENOMEM);
+
+       /* get a handle to the interrupt data pipe */
+       pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+       ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+       if (ret != USB_PKT_LEN)
+               err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
+
+       /* initialise irq urb */
+       usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
+                       USB_PKT_LEN,
+                       urb_irq_callback,
+                       yld, endpoint->bInterval);
+       yld->urb_irq->transfer_dma = yld->irq_dma;
+       yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       yld->urb_irq->dev = udev;
+
+       /* initialise ctl urb */
+       yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
+                                     USB_DIR_OUT;
+       yld->ctl_req->bRequest  = USB_REQ_SET_CONFIGURATION;
+       yld->ctl_req->wValue    = cpu_to_le16(0x200);
+       yld->ctl_req->wIndex    = cpu_to_le16(interface->desc.bInterfaceNumber);
+       yld->ctl_req->wLength   = cpu_to_le16(USB_PKT_LEN);
+
+       usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
+                       (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
+                       urb_ctl_callback, yld);
+       yld->urb_ctl->setup_dma = yld->ctl_req_dma;
+       yld->urb_ctl->transfer_dma      = yld->ctl_dma;
+       yld->urb_ctl->transfer_flags    |= URB_NO_SETUP_DMA_MAP |
+                                       URB_NO_TRANSFER_DMA_MAP;
+       yld->urb_ctl->dev = udev;
+
+       /* find out the physical bus location */
+       if (usb_make_path(udev, path, sizeof(path)) > 0)
+               snprintf(yld->phys, sizeof(yld->phys)-1,  "%s/input0", path);
+
+       /* register settings for the input device */
+       init_input_dev(&yld->idev);
+       yld->idev.private       = yld;
+       yld->idev.id.bustype    = BUS_USB;
+       yld->idev.id.vendor     = le16_to_cpu(udev->descriptor.idVendor);
+       yld->idev.id.product    = le16_to_cpu(udev->descriptor.idProduct);
+       yld->idev.id.version    = le16_to_cpu(udev->descriptor.bcdDevice);
+       yld->idev.dev           = &intf->dev;
+       yld->idev.name          = yld_device[i].name;
+       yld->idev.phys          = yld->phys;
+       /* yld->idev.event              = input_ev;     TODO */
+       yld->idev.open          = input_open;
+       yld->idev.close         = input_close;
+
+       /* register available key events */
+       yld->idev.evbit[0] = BIT(EV_KEY);
+       for (i = 0; i < 256; i++) {
+               int k = map_p1k_to_key(i);
+               if (k >= 0) {
+                       set_bit(k & 0xff, yld->idev.keybit);
+                       if (k >> 8)
+                               set_bit(k >> 8, yld->idev.keybit);
+               }
+       }
+
+       printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path);
+
+       input_register_device(&yld->idev);
+
+       usb_set_intfdata(intf, yld);
+
+       /* clear visible elements */
+       for (i=0; i<ARRAY_SIZE(lcdMap); i++)
+               setChar(yld, i, ' ');
+
+       /* display driver version on LCD line 3 */
+       store_line3(&intf->dev, NULL,
+                       DRIVER_VERSION, sizeof(DRIVER_VERSION));
+
+       /* Register sysfs hooks (don't care about failure) */
+       sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
+       return 0;
+}
+
+static struct usb_driver yealink_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "yealink",
+       .probe          = usb_probe,
+       .disconnect     = usb_disconnect,
+       .id_table       = usb_table,
+};
+
+static int __init yealink_dev_init(void)
+{
+       int ret = usb_register(&yealink_driver);
+       if (ret == 0)
+               info(DRIVER_DESC ":" DRIVER_VERSION);
+       return ret;
+}
+
+static void __exit yealink_dev_exit(void)
+{
+       usb_deregister(&yealink_driver);
+}
+
+module_init(yealink_dev_init);
+module_exit(yealink_dev_exit);
+
+MODULE_DEVICE_TABLE (usb, usb_table);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/yealink.h b/drivers/usb/input/yealink.h
new file mode 100644 (file)
index 0000000..48af0be
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * drivers/usb/input/yealink.h
+ *
+ * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ *
+ * 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-1307 USA
+ */
+#ifndef INPUT_YEALINK_H
+#define INPUT_YEALINK_H
+
+/* Using the control channel on interface 3 various aspects of the phone
+ * can be controlled like LCD, LED, dialtone and the ringtone.
+ */
+
+struct yld_ctl_packet {
+       u8      cmd;            /* command code, see below */
+       u8      size;           /* 1-11, size of used data bytes. */
+       u16     offset;         /* internal packet offset */
+       u8      data[11];
+       s8      sum;            /* negative sum of 15 preceding bytes */
+} __attribute__ ((packed));
+
+#define USB_PKT_LEN    sizeof(struct yld_ctl_packet)
+
+/* The following yld_ctl_packet's are available: */
+
+/* Init registers
+ *
+ * cmd         0x8e
+ * size                10
+ * offset      0
+ * data                0,0,0,0....
+ */
+#define CMD_INIT               0x8e
+
+/* Request key scan
+ *
+ * cmd         0x80
+ * size                1
+ * offset      0
+ * data[0]     on return returns the key number, if it changes there's a new
+ *             key pressed.
+ */
+#define CMD_KEYPRESS           0x80
+
+/* Request scancode
+ *
+ * cmd         0x81
+ * size                1
+ * offset      key number [0-1f]
+ * data[0]     on return returns the scancode
+ */
+#define CMD_SCANCODE           0x81
+
+/* Set LCD
+ *
+ * cmd         0x04
+ * size                1-11
+ * offset      0-23
+ * data                segment bits
+ */
+#define CMD_LCD                        0x04
+
+/* Set led
+ *
+ * cmd         0x05
+ * size                1
+ * offset      0
+ * data[0]     0 OFF / 1 ON
+ */
+#define CMD_LED                        0x05
+
+/* Set ringtone volume
+ *
+ * cmd         0x11
+ * size                1
+ * offset      0
+ * data[0]     0-0xff  volume
+ */
+#define CMD_RING_VOLUME                0x11
+
+/* Set ringtone notes
+ *
+ * cmd         0x02
+ * size                1-11
+ * offset      0->
+ * data                binary representation LE16(-freq), LE16(duration) ....
+ */
+#define CMD_RING_NOTE          0x02
+
+/* Sound ringtone via the speaker on the back
+ *
+ * cmd         0x03
+ * size                1
+ * offset      0
+ * data[0]     0 OFF / 0x24 ON
+ */
+#define CMD_RINGTONE           0x03
+
+/* Sound dial tone via the ear speaker
+ *
+ * cmd         0x09
+ * size                1
+ * offset      0
+ * data[0]     0 OFF / 1 ON
+ */
+#define CMD_DIALTONE           0x09
+
+#endif /* INPUT_YEALINK_H */
+
+
+#if defined(_SEG) && defined(_PIC)
+/* This table maps the LCD segments onto individual bit positions in the
+ * yld_status struct.
+ */
+
+/* LCD, each segment must be driven seperately.
+ *
+ * Layout:
+ *
+ *   |[]   [][]   [][]   [][]   in   |[][]
+ *   |[] M [][] D [][] : [][]   out  |[][]
+ *                             store
+ *
+ *    NEW REP         SU MO TU WE TH FR SA
+ *
+ *    [] [] [] [] [] [] [] [] [] [] [] []
+ *    [] [] [] [] [] [] [] [] [] [] [] []
+ */
+
+/* Line 1
+ *     Format          : 18.e8.M8.88...188
+ *     Icon names      : M D : IN OUT STORE
+ */
+#define LCD_LINE1_OFFSET       0
+#define LCD_LINE1_SIZE         17
+
+/* Note: first g then f =>                            !      !      */
+/* _SEG(    type    a      b      c      d      e      g      f   )  */
+       _SEG('1',  0,0 , 22,2 , 22,2 ,  0,0 ,  0,0 ,  0,0 ,  0,0        ),
+       _SEG('8', 20,1 , 20,2 , 20,4 , 20,8 , 21,4 , 21,2 , 21,1        ),
+       _PIC('.', 22,1 , "M"                                            ),
+       _SEG('e', 18,1 , 18,2 , 18,4 , 18,1 , 19,2 , 18,1 , 19,1        ),
+       _SEG('8', 16,1 , 16,2 , 16,4 , 16,8 , 17,4 , 17,2 , 17,1        ),
+       _PIC('.', 15,8 , "D"                                            ),
+       _SEG('M', 14,1 , 14,2 , 14,4 , 14,1 , 15,4 , 15,2 , 15,1        ),
+       _SEG('8', 12,1 , 12,2 , 12,4 , 12,8 , 13,4 , 13,2 , 13,1        ),
+       _PIC('.', 11,8 , ":"                                            ),
+       _SEG('8', 10,1 , 10,2 , 10,4 , 10,8 , 11,4 , 11,2 , 11,1        ),
+       _SEG('8',  8,1 ,  8,2 ,  8,4 ,  8,8 ,  9,4 ,  9,2 ,  9,1        ),
+       _PIC('.',  7,1 , "IN"                                           ),
+       _PIC('.',  7,2 , "OUT"                                          ),
+       _PIC('.',  7,4 , "STORE"                                        ),
+       _SEG('1',  0,0 ,  5,1 ,  5,1 ,  0,0 ,  0,0 ,  0,0 ,  0,0        ),
+       _SEG('8',  4,1 ,  4,2 ,  4,4 ,  4,8 ,  5,8 ,  5,4 ,  5,2        ),
+       _SEG('8',  2,1 ,  2,2 ,  2,4 ,  2,8 ,  3,4 ,  3,2 ,  3,1        ),
+
+/* Line 2
+ *     Format          : .........
+ *     Pict. name      : NEW REP SU MO TU WE TH FR SA
+ */
+#define LCD_LINE2_OFFSET       LCD_LINE1_OFFSET + LCD_LINE1_SIZE
+#define LCD_LINE2_SIZE         9
+
+       _PIC('.', 23,2 , "NEW"  ),
+       _PIC('.', 23,4 , "REP"  ),
+       _PIC('.',  1,8 , "SU"   ),
+       _PIC('.',  1,4 , "MO"   ),
+       _PIC('.',  1,2 , "TU"   ),
+       _PIC('.',  1,1 , "WE"   ),
+       _PIC('.',  0,1 , "TH"   ),
+       _PIC('.',  0,2 , "FR"   ),
+       _PIC('.',  0,4 , "SA"   ),
+
+/* Line 3
+ *     Format          : 888888888888
+ */
+#define LCD_LINE3_OFFSET       LCD_LINE2_OFFSET + LCD_LINE2_SIZE
+#define LCD_LINE3_SIZE         12
+
+       _SEG('8', 22,16, 22,32, 22,64, 22,128, 23,128, 23,64, 23,32  ),
+       _SEG('8', 20,16, 20,32, 20,64, 20,128, 21,128, 21,64, 21,32  ),
+       _SEG('8', 18,16, 18,32, 18,64, 18,128, 19,128, 19,64, 19,32  ),
+       _SEG('8', 16,16, 16,32, 16,64, 16,128, 17,128, 17,64, 17,32  ),
+       _SEG('8', 14,16, 14,32, 14,64, 14,128, 15,128, 15,64, 15,32  ),
+       _SEG('8', 12,16, 12,32, 12,64, 12,128, 13,128, 13,64, 13,32  ),
+       _SEG('8', 10,16, 10,32, 10,64, 10,128, 11,128, 11,64, 11,32  ),
+       _SEG('8',  8,16,  8,32,  8,64,  8,128,  9,128,  9,64,  9,32  ),
+       _SEG('8',  6,16,  6,32,  6,64,  6,128,  7,128,  7,64,  7,32  ),
+       _SEG('8',  4,16,  4,32,  4,64,  4,128,  5,128,  5,64,  5,32  ),
+       _SEG('8',  2,16,  2,32,  2,64,  2,128,  3,128,  3,64,  3,32  ),
+       _SEG('8',  0,16,  0,32,  0,64,  0,128,  1,128,  1,64,  1,32  ),
+
+/* Line 4
+ *
+ * The LED, DIALTONE and RINGTONE are implemented as icons and use the same
+ * sysfs interface.
+ */
+#define LCD_LINE4_OFFSET       LCD_LINE3_OFFSET + LCD_LINE3_SIZE
+
+       _PIC('.', offsetof(struct yld_status, led)      , 0x01, "LED" ),
+       _PIC('.', offsetof(struct yld_status, dialtone) , 0x01, "DIALTONE" ),
+       _PIC('.', offsetof(struct yld_status, ringtone) , 0x24, "RINGTONE" ),
+
+#undef _SEG
+#undef _PIC
+#endif /* _SEG && _PIC */
index 6f7994f5a714b19e1552aa485ebb6240cac93e67..ae4681f9f0ea155381024a49937af598cb5d8c6a 100644 (file)
@@ -426,7 +426,7 @@ static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb)
 
 /* cancel an urb which is submitted to the chain
    the result is 0 if the urb is cancelled, or -EINPROGRESS if
-   URB_ASYNC_UNLINK is set and the function is successfully started.
+   the function is successfully started.
 */
 static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb)
 {
@@ -515,7 +515,6 @@ static void auerchain_unlink_all (pauerchain_t acp)
         acep = acp->active;
         if (acep) {
                 urbp = acep->urbp;
-                urbp->transfer_flags &= ~URB_ASYNC_UNLINK;
                 dbg ("unlink active urb");
                 usb_kill_urb (urbp);
         }
index ad17892aac9e829b8ad8dd509203a11f425f2a24..7e93ac96490f6176bfb143b99f7f15a9431fd00e 100644 (file)
@@ -464,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
        actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
        bytes_to_read = min(count, *actual_buffer);
        if (bytes_to_read < *actual_buffer)
-               dev_warn(&dev->intf->dev, "Read buffer overflow, %d bytes dropped\n",
+               dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n",
                         *actual_buffer-bytes_to_read);
 
        /* copy one interrupt_in_buffer from ring_buffer into userspace */
@@ -528,8 +528,8 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
        /* write the data into interrupt_out_buffer from userspace */
        bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
        if (bytes_to_write < count)
-               dev_warn(&dev->intf->dev, "Write buffer overflow, %d bytes dropped\n",count-bytes_to_write);
-       dbg_info(&dev->intf->dev, "%s: count = %d, bytes_to_write = %d\n", __FUNCTION__, count, bytes_to_write);
+               dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+       dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __FUNCTION__, count, bytes_to_write);
 
        if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
                retval = -EFAULT;
index 2fd12264fd53f24e0ec6912c02ce1c9a895fd964..d63ce6c030f39d442d98bb16e04b6569ca19457e 100644 (file)
@@ -229,7 +229,7 @@ sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe,
        usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
                sisusb_bulk_completeout, &sisusb->urbout_context[index]);
 
-       urb->transfer_flags |= (tflags | URB_ASYNC_UNLINK);
+       urb->transfer_flags |= tflags;
        urb->actual_length = 0;
 
        if ((urb->transfer_dma = transfer_dma))
@@ -295,7 +295,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data,
        usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
                        sisusb_bulk_completein, sisusb);
 
-       urb->transfer_flags |= (tflags | URB_ASYNC_UNLINK);
+       urb->transfer_flags |= tflags;
        urb->actual_length = 0;
 
        if ((urb->transfer_dma = transfer_dma))
index fd7fb98e4b2029c752fa94d86f8b8d26e775779e..54799eb0bc600750dca99cc8b39224c2c28e62db 100644 (file)
@@ -986,7 +986,6 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
 
                u->context = &context;
                u->complete = ctrl_complete;
-               u->transfer_flags |= URB_ASYNC_UNLINK;
        }
 
        /* queue the urbs */
@@ -1052,7 +1051,6 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
        urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size);
        if (!urb)
                return -ENOMEM;
-       urb->transfer_flags |= URB_ASYNC_UNLINK;
        urb->context = &completion;
        urb->complete = unlink1_callback;
 
index b0015b8a1d1f96e372e3d0037b45807112aab3d0..3cf3ea3a88edaa5f256e5946846bd0c7a20fd3bc 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for USB Core files and filesystem
 #
 
-usbmon-objs    := mon_main.o mon_stat.o mon_text.o
+usbmon-objs    := mon_main.o mon_stat.o mon_text.o mon_dma.o
 
 # This does not use CONFIG_USB_MON because we want this to use a tristate.
 obj-$(CONFIG_USB)      += usbmon.o
diff --git a/drivers/usb/mon/mon_dma.c b/drivers/usb/mon/mon_dma.c
new file mode 100644 (file)
index 0000000..0a1367b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * The USB Monitor, inspired by Dave Harding's USBMon.
+ *
+ * mon_dma.c: Library which snoops on DMA areas.
+ *
+ * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com)
+ */
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <asm/page.h>
+
+#include <linux/usb.h> /* Only needed for declarations in usb_mon.h */
+#include "usb_mon.h"
+
+#ifdef __i386__                /* CONFIG_ARCH_I386 does not exit */
+#define MON_HAS_UNMAP 1
+
+#define phys_to_page(phys)     pfn_to_page((phys) >> PAGE_SHIFT)
+
+char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len)
+{
+       struct page *pg;
+       unsigned long flags;
+       unsigned char *map;
+       unsigned char *ptr;
+
+       /*
+        * On i386, a DMA handle is the "physical" address of a page.
+        * In other words, the bus address is equal to physical address.
+        * There is no IOMMU.
+        */
+       pg = phys_to_page(dma_addr);
+
+       /*
+        * We are called from hardware IRQs in case of callbacks.
+        * But we can be called from softirq or process context in case
+        * of submissions. In such case, we need to protect KM_IRQ0.
+        */
+       local_irq_save(flags);
+       map = kmap_atomic(pg, KM_IRQ0);
+       ptr = map + (dma_addr & (PAGE_SIZE-1));
+       memcpy(dst, ptr, len);
+       kunmap_atomic(map, KM_IRQ0);
+       local_irq_restore(flags);
+       return 0;
+}
+#endif /* __i386__ */
+
+#ifndef MON_HAS_UNMAP
+char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len)
+{
+       return 'D';
+}
+#endif
index 26266b30028eaacbd3d6a20d08c162e2a92c4794..417464dea9f6457948a3caba9f82a4170c81e30a 100644 (file)
@@ -91,25 +91,11 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
     int len, char ev_type)
 {
        int pipe = urb->pipe;
-       unsigned char *data;
-
-       /*
-        * The check to see if it's safe to poke at data has an enormous
-        * number of corner cases, but it seems that the following is
-        * more or less safe.
-        *
-        * We do not even try to look transfer_buffer, because it can
-        * contain non-NULL garbage in case the upper level promised to
-        * set DMA for the HCD.
-        */
-       if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
-               return 'D';
 
        if (len <= 0)
                return 'L';
-
-       if ((data = urb->transfer_buffer) == NULL)
-               return 'Z';     /* '0' would be not as pretty. */
+       if (len >= DATA_MAX)
+               len = DATA_MAX;
 
        /*
         * Bulk is easy to shortcut reliably. 
@@ -126,8 +112,21 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
                }
        }
 
-       if (len >= DATA_MAX)
-               len = DATA_MAX;
+       /*
+        * The check to see if it's safe to poke at data has an enormous
+        * number of corner cases, but it seems that the following is
+        * more or less safe.
+        *
+        * We do not even try to look transfer_buffer, because it can
+        * contain non-NULL garbage in case the upper level promised to
+        * set DMA for the HCD.
+        */
+       if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
+               return mon_dmapeek(ep->data, urb->transfer_dma, len);
+
+       if (urb->transfer_buffer == NULL)
+               return 'Z';     /* '0' would be not as pretty. */
+
        memcpy(ep->data, urb->transfer_buffer, len);
        return 0;
 }
index 9b06784d2c481055368bdd92f171d68801886d3f..4be0f93460717779739c5ab8cd65899b73a274de 100644 (file)
@@ -45,6 +45,10 @@ struct mon_reader {
 void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r);
 void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r);
 
+/*
+ */
+extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len);
+
 extern struct semaphore mon_lock;
 
 extern struct file_operations mon_fops_text;
index b104430e2c6a696f808a6bae9160f15eb86db085..8c010bb44eb81aeac40fa2427dd9b52e063a1f03 100644 (file)
@@ -99,7 +99,7 @@ config USB_USBNET
          with "minidrivers" built around a common network driver core
          that supports deep queues for efficient transfers.  (This gives
          better performance with small packets and at high speeds).
-         
+
          The USB host runs "usbnet", and the other end of the link might be:
 
          - Another USB host, when using USB "network" or "data transfer"
@@ -125,38 +125,63 @@ config USB_USBNET
          To compile this driver as a module, choose M here: the
          module will be called usbnet.
 
-comment "USB Host-to-Host Cables"
-       depends on USB_USBNET
-
-config USB_ALI_M5632
-       boolean "ALi M5632 based 'USB 2.0 Data Link' cables"
-       depends on USB_USBNET
+config USB_NET_AX8817X
+       tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
+       depends on USB_USBNET && NET_ETHERNET
+       select CRC32
+       select MII
        default y
        help
-         Choose this option if you're using a host-to-host cable
-         based on this design, which supports USB 2.0 high speed.
+         This option adds support for ASIX AX88xxx based USB 2.0
+         10/100 Ethernet adapters.
 
-config USB_AN2720
-       boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
-       depends on USB_USBNET
-       default y
-       help
-         Choose this option if you're using a host-to-host cable
-         based on this design.  Note that AnchorChips is now a
-         Cypress brand.
+         This driver should work with at least the following devices:
+           * Aten UC210T
+           * ASIX AX88172
+           * Billionton Systems, USB2AR
+           * Buffalo LUA-U2-KTX
+           * Corega FEther USB2-TX
+           * D-Link DUB-E100
+           * Hawking UF200
+           * Linksys USB200M
+           * Netgear FA120
+           * Sitecom LN-029
+           * Intellinet USB 2.0 Ethernet
+           * ST Lab USB 2.0 Ethernet
+           * TrendNet TU2-ET100
 
-config USB_BELKIN
-       boolean "eTEK based host-to-host cables (Advance, Belkin, ...)"
+         This driver creates an interface named "ethX", where X depends on
+         what other networking devices you have in use.
+
+
+config USB_NET_CDCETHER
+       tristate "CDC Ethernet support (smart devices such as cable modems)"
        depends on USB_USBNET
        default y
        help
-         Choose this option if you're using a host-to-host cable
-         based on this design:  two NetChip 2890 chips and an Atmel
-         microcontroller, with LEDs that indicate traffic.
+         This option supports devices conforming to the Communication Device
+         Class (CDC) Ethernet Control Model, a specification that's easy to
+         implement in device firmware.  The CDC specifications are available
+         from <http://www.usb.org/>.
 
-config USB_GENESYS
-       boolean "GeneSys GL620USB-A based cables"
-       default y
+         CDC Ethernet is an implementation option for DOCSIS cable modems
+         that support USB connectivity, used for non-Microsoft USB hosts.
+         The Linux-USB CDC Ethernet Gadget driver is an open implementation.
+         This driver should work with at least the following devices:
+
+           * Ericsson PipeRider (all variants)
+           * Motorola (DM100 and SB4100)
+           * Broadcom Cable Modem (reference design)
+           * Toshiba PCX1100U
+           * ...
+
+         This driver creates an interface named "ethX", where X depends on
+         what other networking devices you have in use.  However, if the
+         IEEE 802 "local assignment" bit is set in the address, a "usbX"
+         name is used instead.
+
+config USB_NET_GL620A
+       tristate "GeneSys GL620USB-A based cables"
        depends on USB_USBNET
        help
          Choose this option if you're using a host-to-host cable,
@@ -164,38 +189,78 @@ config USB_GENESYS
 
          Note that the half-duplex "GL620USB" is not supported.
 
-config USB_NET1080
-       boolean "NetChip 1080 based cables (Laplink, ...)"
+config USB_NET_NET1080
+       tristate "NetChip 1080 based cables (Laplink, ...)"
        default y
        depends on USB_USBNET
        help
          Choose this option if you're using a host-to-host cable based
-         on this design:  one NetChip 1080 chips and supporting logic,
-         supporting LEDs that indicate traffic
+         on this design:  one NetChip 1080 chip and supporting logic,
+         optionally with LEDs that indicate traffic
 
-config USB_PL2301
-       boolean "Prolific PL-2301/2302 based cables"
-       default y
-       # handshake/init/reset problems, from original 'plusb' driver
+config USB_NET_PLUSB
+       tristate "Prolific PL-2301/2302 based cables"
+       # if the handshake/init/reset problems, from original 'plusb',
+       # are ever resolved ... then remove "experimental"
        depends on USB_USBNET && EXPERIMENTAL
        help
          Choose this option if you're using a host-to-host cable
          with one of these chips.
 
-config USB_KC2190
-       boolean "KT Technology KC2190 based cables (InstaNet)"
-       default y
+config USB_NET_RNDIS_HOST
+       tristate "Host for RNDIS devices (EXPERIMENTAL)"
        depends on USB_USBNET && EXPERIMENTAL
+       select USB_NET_CDCETHER
        help
-         Choose this option if you're using a host-to-host cable
-         with one of these chips.
+         This option enables hosting "Remote NDIS" USB networking links,
+         as encouraged by Microsoft (instead of CDC Ethernet!) for use in
+         various devices that may only support this protocol.
 
-comment "Intelligent USB Devices/Gadgets"
+         Avoid using this protocol unless you have no better options.
+         The protocol specification is incomplete, and is controlled by
+         (and for) Microsoft; it isn't an "Open" ecosystem or market.
+
+config USB_NET_CDC_SUBSET
+       tristate "Simple USB Network Links (CDC Ethernet subset)"
        depends on USB_USBNET
+       help
+         This driver module supports USB network devices that can work
+         without any device-specific information.  Select it if you have
+         one of these drivers.
+
+         Note that while many USB host-to-host cables can work in this mode,
+         that may mean not being able to talk to Win32 systems or more
+         commonly not being able to handle certain events (like replugging
+         the host on the other end) very well.  Also, these devices will
+         not generally have permanently assigned Ethernet addresses.
+
+config USB_ALI_M5632
+       boolean "ALi M5632 based 'USB 2.0 Data Link' cables"
+       depends on USB_NET_CDC_SUBSET
+       help
+         Choose this option if you're using a host-to-host cable
+         based on this design, which supports USB 2.0 high speed.
+
+config USB_AN2720
+       boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
+       depends on USB_NET_CDC_SUBSET
+       help
+         Choose this option if you're using a host-to-host cable
+         based on this design.  Note that AnchorChips is now a
+         Cypress brand.
+
+config USB_BELKIN
+       boolean "eTEK based host-to-host cables (Advance, Belkin, ...)"
+       depends on USB_NET_CDC_SUBSET
+       default y
+       help
+         Choose this option if you're using a host-to-host cable
+         based on this design:  two NetChip 2890 chips and an Atmel
+         microcontroller, with LEDs that indicate traffic.
 
 config USB_ARMLINUX
        boolean "Embedded ARM Linux links (iPaq, ...)"
-       depends on USB_USBNET
+       depends on USB_NET_CDC_SUBSET
        default y
        help
          Choose this option to support the "usb-eth" networking driver
@@ -212,15 +277,15 @@ config USB_ARMLINUX
 
 config USB_EPSON2888
        boolean "Epson 2888 based firmware (DEVELOPMENT)"
-       depends on USB_USBNET
-       default y
+       depends on USB_NET_CDC_SUBSET
        help
          Choose this option to support the usb networking links used
          by some sample firmware from Epson.
 
-config USB_ZAURUS
-       boolean "Sharp Zaurus (stock ROMs) and compatible"
+config USB_NET_ZAURUS
+       tristate "Sharp Zaurus (stock ROMs) and compatible"
        depends on USB_USBNET
+       select USB_NET_CDCETHER
        select CRC32
        default y
        help
@@ -235,61 +300,6 @@ config USB_ZAURUS
          really need this non-conformant variant of CDC Ethernet (or in
          some cases CDC MDLM) protocol, not "g_ether".
 
-config USB_CDCETHER
-       boolean "CDC Ethernet support (smart devices such as cable modems)"
-       depends on USB_USBNET
-       default y
-       help
-         This option supports devices conforming to the Communication Device
-         Class (CDC) Ethernet Control Model, a specification that's easy to
-         implement in device firmware.  The CDC specifications are available
-         from <http://www.usb.org/>.
-         
-         CDC Ethernet is an implementation option for DOCSIS cable modems
-         that support USB connectivity, used for non-Microsoft USB hosts.
-         This driver should work with at least the following devices:
-
-           * Ericsson PipeRider (all variants)
-           * Motorola (DM100 and SB4100)
-           * Broadcom Cable Modem (reference design)
-           * Toshiba PCX1100U
-           * ...
-
-         This driver creates an interface named "ethX", where X depends on
-         what other networking devices you have in use.  However, if the
-         IEEE 802 "local assignment" bit is set in the address, a "usbX"
-         name is used instead.
-
-comment "USB Network Adapters"
-       depends on USB_USBNET
-
-config USB_AX8817X
-       boolean "ASIX AX88xxx Based USB 2.0 Ethernet Devices"
-       depends on USB_USBNET && NET_ETHERNET
-       select CRC32
-       select MII
-       default y
-       help
-         This option adds support for ASIX AX88xxx based USB 2.0
-         10/100 Ethernet devices.
-
-         This driver should work with at least the following devices:
-           * Aten UC210T
-           * ASIX AX88172
-           * Billionton Systems, USB2AR 
-           * Buffalo LUA-U2-KTX
-           * Corega FEther USB2-TX
-           * D-Link DUB-E100
-           * Hawking UF200
-           * Linksys USB200M
-           * Netgear FA120
-           * Sitecom LN-029
-           * Intellinet USB 2.0 Ethernet
-           * ST Lab USB 2.0 Ethernet
-           * TrendNet TU2-ET100
-
-         This driver creates an interface named "ethX", where X depends on
-         what other networking devices you have in use.  
 
 config USB_ZD1201
        tristate "USB ZD1201 based Wireless device support"
index fe3fd4115e1e31608745a070aded61063eaba818..222c0495f791113970616f1dc514b8bda046cab0 100644 (file)
@@ -6,5 +6,13 @@ obj-$(CONFIG_USB_CATC)         += catc.o
 obj-$(CONFIG_USB_KAWETH)       += kaweth.o
 obj-$(CONFIG_USB_PEGASUS)      += pegasus.o
 obj-$(CONFIG_USB_RTL8150)      += rtl8150.o
+obj-$(CONFIG_USB_NET_AX8817X)  += asix.o
+obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
+obj-$(CONFIG_USB_NET_GL620A)   += gl620a.o
+obj-$(CONFIG_USB_NET_NET1080)  += net1080.o
+obj-$(CONFIG_USB_NET_PLUSB)    += plusb.o
+obj-$(CONFIG_USB_NET_RNDIS_HOST)       += rndis_host.o
+obj-$(CONFIG_USB_NET_CDC_SUBSET)       += cdc_subset.o
+obj-$(CONFIG_USB_NET_ZAURUS)   += zaurus.o
 obj-$(CONFIG_USB_USBNET)       += usbnet.o
 obj-$(CONFIG_USB_ZD1201)       += zd1201.o
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
new file mode 100644 (file)
index 0000000..861f00a
--- /dev/null
@@ -0,0 +1,948 @@
+/*
+ * ASIX AX8817X based USB 2.0 Ethernet Devices
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
+ * Copyright (c) 2002-2003 TiVo Inc.
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+
+#include "usbnet.h"
+
+
+/* ASIX AX8817X based USB 2.0 Ethernet Devices */
+
+#define AX_CMD_SET_SW_MII              0x06
+#define AX_CMD_READ_MII_REG            0x07
+#define AX_CMD_WRITE_MII_REG           0x08
+#define AX_CMD_SET_HW_MII              0x0a
+#define AX_CMD_READ_EEPROM             0x0b
+#define AX_CMD_WRITE_EEPROM            0x0c
+#define AX_CMD_WRITE_ENABLE            0x0d
+#define AX_CMD_WRITE_DISABLE           0x0e
+#define AX_CMD_WRITE_RX_CTL            0x10
+#define AX_CMD_READ_IPG012             0x11
+#define AX_CMD_WRITE_IPG0              0x12
+#define AX_CMD_WRITE_IPG1              0x13
+#define AX_CMD_WRITE_IPG2              0x14
+#define AX_CMD_WRITE_MULTI_FILTER      0x16
+#define AX_CMD_READ_NODE_ID            0x17
+#define AX_CMD_READ_PHY_ID             0x19
+#define AX_CMD_READ_MEDIUM_STATUS      0x1a
+#define AX_CMD_WRITE_MEDIUM_MODE       0x1b
+#define AX_CMD_READ_MONITOR_MODE       0x1c
+#define AX_CMD_WRITE_MONITOR_MODE      0x1d
+#define AX_CMD_WRITE_GPIOS             0x1f
+#define AX_CMD_SW_RESET                        0x20
+#define AX_CMD_SW_PHY_STATUS           0x21
+#define AX_CMD_SW_PHY_SELECT           0x22
+#define AX88772_CMD_READ_NODE_ID       0x13
+
+#define AX_MONITOR_MODE                        0x01
+#define AX_MONITOR_LINK                        0x02
+#define AX_MONITOR_MAGIC               0x04
+#define AX_MONITOR_HSFS                        0x10
+
+/* AX88172 Medium Status Register values */
+#define AX_MEDIUM_FULL_DUPLEX          0x02
+#define AX_MEDIUM_TX_ABORT_ALLOW       0x04
+#define AX_MEDIUM_FLOW_CONTROL_EN      0x10
+
+#define AX_MCAST_FILTER_SIZE           8
+#define AX_MAX_MCAST                   64
+
+#define AX_EEPROM_LEN                  0x40
+
+#define AX_SWRESET_CLEAR               0x00
+#define AX_SWRESET_RR                  0x01
+#define AX_SWRESET_RT                  0x02
+#define AX_SWRESET_PRTE                        0x04
+#define AX_SWRESET_PRL                 0x08
+#define AX_SWRESET_BZ                  0x10
+#define AX_SWRESET_IPRL                        0x20
+#define AX_SWRESET_IPPD                        0x40
+
+#define AX88772_IPG0_DEFAULT           0x15
+#define AX88772_IPG1_DEFAULT           0x0c
+#define AX88772_IPG2_DEFAULT           0x12
+
+#define AX88772_MEDIUM_FULL_DUPLEX     0x0002
+#define AX88772_MEDIUM_RESERVED                0x0004
+#define AX88772_MEDIUM_RX_FC_ENABLE    0x0010
+#define AX88772_MEDIUM_TX_FC_ENABLE    0x0020
+#define AX88772_MEDIUM_PAUSE_FORMAT    0x0080
+#define AX88772_MEDIUM_RX_ENABLE       0x0100
+#define AX88772_MEDIUM_100MB           0x0200
+#define AX88772_MEDIUM_DEFAULT \
+       (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
+        AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
+        AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
+
+#define AX_EEPROM_MAGIC                        0xdeadbeef
+
+/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
+struct ax8817x_data {
+       u8 multi_filter[AX_MCAST_FILTER_SIZE];
+};
+
+struct ax88172_int_data {
+       u16 res1;
+       u8 link;
+       u16 res2;
+       u8 status;
+       u16 res3;
+} __attribute__ ((packed));
+
+static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                           u16 size, void *data)
+{
+       return usb_control_msg(
+               dev->udev,
+               usb_rcvctrlpipe(dev->udev, 0),
+               cmd,
+               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               value,
+               index,
+               data,
+               size,
+               USB_CTRL_GET_TIMEOUT);
+}
+
+static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                            u16 size, void *data)
+{
+       return usb_control_msg(
+               dev->udev,
+               usb_sndctrlpipe(dev->udev, 0),
+               cmd,
+               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               value,
+               index,
+               data,
+               size,
+               USB_CTRL_SET_TIMEOUT);
+}
+
+static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+{
+       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+       if (urb->status < 0)
+               printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
+                       urb->status);
+
+       kfree(req);
+       usb_free_urb(urb);
+}
+
+static void ax8817x_status(struct usbnet *dev, struct urb *urb)
+{
+       struct ax88172_int_data *event;
+       int link;
+
+       if (urb->actual_length < 8)
+               return;
+
+       event = urb->transfer_buffer;
+       link = event->link & 0x01;
+       if (netif_carrier_ok(dev->net) != link) {
+               if (link) {
+                       netif_carrier_on(dev->net);
+                       usbnet_defer_kevent (dev, EVENT_LINK_RESET );
+               } else
+                       netif_carrier_off(dev->net);
+               devdbg(dev, "ax8817x - Link Status is: %d", link);
+       }
+}
+
+static void
+ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                                   u16 size, void *data)
+{
+       struct usb_ctrlrequest *req;
+       int status;
+       struct urb *urb;
+
+       if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
+               devdbg(dev, "Error allocating URB in write_cmd_async!");
+               return;
+       }
+
+       if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
+               deverr(dev, "Failed to allocate memory for control request");
+               usb_free_urb(urb);
+               return;
+       }
+
+       req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+       req->bRequest = cmd;
+       req->wValue = cpu_to_le16(value);
+       req->wIndex = cpu_to_le16(index);
+       req->wLength = cpu_to_le16(size);
+
+       usb_fill_control_urb(urb, dev->udev,
+                            usb_sndctrlpipe(dev->udev, 0),
+                            (void *)req, data, size,
+                            ax8817x_async_cmd_callback, req);
+
+       if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+               deverr(dev, "Error submitting the control message: status=%d",
+                               status);
+               kfree(req);
+               usb_free_urb(urb);
+       }
+}
+
+static void ax8817x_set_multicast(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
+       u8 rx_ctl = 0x8c;
+
+       if (net->flags & IFF_PROMISC) {
+               rx_ctl |= 0x01;
+       } else if (net->flags & IFF_ALLMULTI
+                  || net->mc_count > AX_MAX_MCAST) {
+               rx_ctl |= 0x02;
+       } else if (net->mc_count == 0) {
+               /* just broadcast and directed */
+       } else {
+               /* We use the 20 byte dev->data
+                * for our 8 byte filter buffer
+                * to avoid allocating memory that
+                * is tricky to free later */
+               struct dev_mc_list *mc_list = net->mc_list;
+               u32 crc_bits;
+               int i;
+
+               memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
+
+               /* Build the multicast hash filter. */
+               for (i = 0; i < net->mc_count; i++) {
+                       crc_bits =
+                           ether_crc(ETH_ALEN,
+                                     mc_list->dmi_addr) >> 26;
+                       data->multi_filter[crc_bits >> 3] |=
+                           1 << (crc_bits & 7);
+                       mc_list = mc_list->next;
+               }
+
+               ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
+                                  AX_MCAST_FILTER_SIZE, data->multi_filter);
+
+               rx_ctl |= 0x10;
+       }
+
+       ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
+}
+
+static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res;
+       u8 buf[1];
+
+       ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+       ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
+                               (__u16)loc, 2, (u16 *)&res);
+       ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+
+       return res & 0xffff;
+}
+
+/* same as above, but converts resulting value to cpu byte order */
+static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc)
+{
+       return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc));
+}
+
+static void
+ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res = val;
+       u8 buf[1];
+
+       ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+       ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
+                               (__u16)loc, 2, (u16 *)&res);
+       ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+}
+
+/* same as above, but converts new value to le16 byte order before writing */
+static void
+ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val)
+{
+       ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) );
+}
+
+static int ax88172_link_reset(struct usbnet *dev)
+{
+       u16 lpa;
+       u16 adv;
+       u16 res;
+       u8 mode;
+
+       mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
+       lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);
+       adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);
+       res = mii_nway_result(lpa|adv);
+       if (res & LPA_DUPLEX)
+               mode |= AX_MEDIUM_FULL_DUPLEX;
+       ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+       return 0;
+}
+
+static void
+ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u8 opt;
+
+       if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
+               wolinfo->supported = 0;
+               wolinfo->wolopts = 0;
+               return;
+       }
+       wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
+       wolinfo->wolopts = 0;
+       if (opt & AX_MONITOR_MODE) {
+               if (opt & AX_MONITOR_LINK)
+                       wolinfo->wolopts |= WAKE_PHY;
+               if (opt & AX_MONITOR_MAGIC)
+                       wolinfo->wolopts |= WAKE_MAGIC;
+       }
+}
+
+static int
+ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u8 opt = 0;
+       u8 buf[1];
+
+       if (wolinfo->wolopts & WAKE_PHY)
+               opt |= AX_MONITOR_LINK;
+       if (wolinfo->wolopts & WAKE_MAGIC)
+               opt |= AX_MONITOR_MAGIC;
+       if (opt != 0)
+               opt |= AX_MONITOR_MODE;
+
+       if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
+                             opt, 0, 0, &buf) < 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ax8817x_get_eeprom_len(struct net_device *net)
+{
+       return AX_EEPROM_LEN;
+}
+
+static int ax8817x_get_eeprom(struct net_device *net,
+                             struct ethtool_eeprom *eeprom, u8 *data)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u16 *ebuf = (u16 *)data;
+       int i;
+
+       /* Crude hack to ensure that we don't overwrite memory
+        * if an odd length is supplied
+        */
+       if (eeprom->len % 2)
+               return -EINVAL;
+
+       eeprom->magic = AX_EEPROM_MAGIC;
+
+       /* ax8817x returns 2 bytes from eeprom on read */
+       for (i=0; i < eeprom->len / 2; i++) {
+               if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
+                       eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static void ax8817x_get_drvinfo (struct net_device *net,
+                                struct ethtool_drvinfo *info)
+{
+       /* Inherit standard device info */
+       usbnet_get_drvinfo(net, info);
+       info->eedump_len = 0x3e;
+}
+
+static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       return mii_ethtool_gset(&dev->mii,cmd);
+}
+
+static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       return mii_ethtool_sset(&dev->mii,cmd);
+}
+
+/* We need to override some ethtool_ops so we require our
+   own structure so we don't interfere with other usbnet
+   devices that may be connected at the same time. */
+static struct ethtool_ops ax8817x_ethtool_ops = {
+       .get_drvinfo            = ax8817x_get_drvinfo,
+       .get_link               = ethtool_op_get_link,
+       .get_msglevel           = usbnet_get_msglevel,
+       .set_msglevel           = usbnet_set_msglevel,
+       .get_wol                = ax8817x_get_wol,
+       .set_wol                = ax8817x_set_wol,
+       .get_eeprom_len         = ax8817x_get_eeprom_len,
+       .get_eeprom             = ax8817x_get_eeprom,
+       .get_settings           = ax8817x_get_settings,
+       .set_settings           = ax8817x_set_settings,
+};
+
+static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int ret = 0;
+       void *buf;
+       int i;
+       unsigned long gpio_bits = dev->driver_info->data;
+
+       usbnet_get_endpoints(dev,intf);
+
+       buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+       if(!buf) {
+               ret = -ENOMEM;
+               goto out1;
+       }
+
+       /* Toggle the GPIOs in a manufacturer/model specific way */
+       for (i = 2; i >= 0; i--) {
+               if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
+                                       (gpio_bits >> (i * 8)) & 0xff, 0, 0,
+                                       buf)) < 0)
+                       goto out2;
+               msleep(5);
+       }
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
+                               0x80, 0, 0, buf)) < 0) {
+               dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
+               goto out2;
+       }
+
+       /* Get the MAC address */
+       memset(buf, 0, ETH_ALEN);
+       if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID,
+                               0, 0, 6, buf)) < 0) {
+               dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
+               goto out2;
+       }
+       memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+
+       /* Get the PHY id */
+       if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,
+                               0, 0, 2, buf)) < 0) {
+               dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
+               goto out2;
+       } else if (ret < 2) {
+               /* this should always return 2 bytes */
+               dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
+                               ret);
+               ret = -EIO;
+               goto out2;
+       }
+
+       /* Initialize MII structure */
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = ax8817x_mdio_read;
+       dev->mii.mdio_write = ax8817x_mdio_write;
+       dev->mii.phy_id_mask = 0x3f;
+       dev->mii.reg_num_mask = 0x1f;
+       dev->mii.phy_id = *((u8 *)buf + 1);
+       dev->net->do_ioctl = ax8817x_ioctl;
+
+       dev->net->set_multicast_list = ax8817x_set_multicast;
+       dev->net->ethtool_ops = &ax8817x_ethtool_ops;
+
+       ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+       ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+               ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+       mii_nway_restart(&dev->mii);
+
+       return 0;
+out2:
+       kfree(buf);
+out1:
+       return ret;
+}
+
+static struct ethtool_ops ax88772_ethtool_ops = {
+       .get_drvinfo            = ax8817x_get_drvinfo,
+       .get_link               = ethtool_op_get_link,
+       .get_msglevel           = usbnet_get_msglevel,
+       .set_msglevel           = usbnet_set_msglevel,
+       .get_wol                = ax8817x_get_wol,
+       .set_wol                = ax8817x_set_wol,
+       .get_eeprom_len         = ax8817x_get_eeprom_len,
+       .get_eeprom             = ax8817x_get_eeprom,
+       .get_settings           = ax8817x_get_settings,
+       .set_settings           = ax8817x_set_settings,
+};
+
+static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int ret;
+       void *buf;
+
+       usbnet_get_endpoints(dev,intf);
+
+       buf = kmalloc(6, GFP_KERNEL);
+       if(!buf) {
+               dbg ("Cannot allocate memory for buffer");
+               ret = -ENOMEM;
+               goto out1;
+       }
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
+                                    0x00B0, 0, 0, buf)) < 0)
+               goto out2;
+
+       msleep(5);
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
+                               0x0001, 0, 0, buf)) < 0) {
+               dbg("Select PHY #1 failed: %d", ret);
+               goto out2;
+       }
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD,
+                               0, 0, buf)) < 0) {
+               dbg("Failed to power down internal PHY: %d", ret);
+               goto out2;
+       }
+
+       msleep(150);
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR,
+                               0, 0, buf)) < 0) {
+               dbg("Failed to perform software reset: %d", ret);
+               goto out2;
+       }
+
+       msleep(150);
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
+                               AX_SWRESET_IPRL | AX_SWRESET_PRL,
+                               0, 0, buf)) < 0) {
+               dbg("Failed to set Internal/External PHY reset control: %d",
+                                       ret);
+               goto out2;
+       }
+
+       msleep(150);
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
+                               0x0000, 0, 0, buf)) < 0) {
+               dbg("Failed to reset RX_CTL: %d", ret);
+               goto out2;
+       }
+
+       /* Get the MAC address */
+       memset(buf, 0, ETH_ALEN);
+       if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID,
+                               0, 0, ETH_ALEN, buf)) < 0) {
+               dbg("Failed to read MAC address: %d", ret);
+               goto out2;
+       }
+       memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII,
+                               0, 0, 0, buf)) < 0) {
+               dbg("Enabling software MII failed: %d", ret);
+               goto out2;
+       }
+
+       if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG,
+                               0x0010, 2, 2, buf)) < 0)
+                       || (*((u16 *)buf) != 0x003b)) {
+               dbg("Read PHY register 2 must be 0x3b00: %d", ret);
+               goto out2;
+       }
+
+       /* Initialize MII structure */
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = ax8817x_mdio_read;
+       dev->mii.mdio_write = ax8817x_mdio_write;
+       dev->mii.phy_id_mask = 0xff;
+       dev->mii.reg_num_mask = 0xff;
+       dev->net->do_ioctl = ax8817x_ioctl;
+
+       /* Get the PHY id */
+       if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,
+                       0, 0, 2, buf)) < 0) {
+               dbg("Error reading PHY ID: %02x", ret);
+               goto out2;
+       } else if (ret < 2) {
+               /* this should always return 2 bytes */
+               dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
+                   ret);
+               ret = -EIO;
+               goto out2;
+       }
+       dev->mii.phy_id = *((u8 *)buf + 1);
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL,
+                               0, 0, buf)) < 0) {
+               dbg("Set external PHY reset pin level: %d", ret);
+               goto out2;
+       }
+       msleep(150);
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
+                               AX_SWRESET_IPRL | AX_SWRESET_PRL,
+                               0, 0, buf)) < 0) {
+               dbg("Set Internal/External PHY reset control: %d", ret);
+               goto out2;
+       }
+       msleep(150);
+
+
+       dev->net->set_multicast_list = ax8817x_set_multicast;
+       dev->net->ethtool_ops = &ax88772_ethtool_ops;
+
+       ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+       ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+                       ADVERTISE_ALL | ADVERTISE_CSMA);
+       mii_nway_restart(&dev->mii);
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,
+                               AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
+               dbg("Write medium mode register: %d", ret);
+               goto out2;
+       }
+
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0,
+                               AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
+                               AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
+               dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
+               goto out2;
+       }
+       if ((ret =
+            ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
+               dbg("Failed to set hardware MII: %02x", ret);
+               goto out2;
+       }
+
+       /* Set RX_CTL to default values with 2k buffer, and enable cactus */
+       if ((ret =
+            ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
+                              buf)) < 0) {
+               dbg("Reset RX_CTL failed: %d", ret);
+               goto out2;
+       }
+
+       kfree(buf);
+
+       /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
+       if (dev->driver_info->flags & FLAG_FRAMING_AX) {
+               /* hard_mtu  is still the default - the device does not support
+                  jumbo eth frames */
+               dev->rx_urb_size = 2048;
+       }
+
+       return 0;
+
+out2:
+       kfree(buf);
+out1:
+       return ret;
+}
+
+static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       u8  *head;
+       u32  header;
+       char *packet;
+       struct sk_buff *ax_skb;
+       u16 size;
+
+       head = (u8 *) skb->data;
+       memcpy(&header, head, sizeof(header));
+       le32_to_cpus(&header);
+       packet = head + sizeof(header);
+
+       skb_pull(skb, 4);
+
+       while (skb->len > 0) {
+               if ((short)(header & 0x0000ffff) !=
+                   ~((short)((header & 0xffff0000) >> 16))) {
+                       devdbg(dev,"header length data is error");
+               }
+               /* get the packet length */
+               size = (u16) (header & 0x0000ffff);
+
+               if ((skb->len) - ((size + 1) & 0xfffe) == 0)
+                       return 2;
+               if (size > ETH_FRAME_LEN) {
+                       devdbg(dev,"invalid rx length %d", size);
+                       return 0;
+               }
+               ax_skb = skb_clone(skb, GFP_ATOMIC);
+               if (ax_skb) {
+                       ax_skb->len = size;
+                       ax_skb->data = packet;
+                       ax_skb->tail = packet + size;
+                       usbnet_skb_return(dev, ax_skb);
+               } else {
+                       return 0;
+               }
+
+               skb_pull(skb, (size + 1) & 0xfffe);
+
+               if (skb->len == 0)
+                       break;
+
+               head = (u8 *) skb->data;
+               memcpy(&header, head, sizeof(header));
+               le32_to_cpus(&header);
+               packet = head + sizeof(header);
+               skb_pull(skb, 4);
+       }
+
+       if (skb->len < 0) {
+               devdbg(dev,"invalid rx length %d", skb->len);
+               return 0;
+       }
+       return 1;
+}
+
+static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+                                       unsigned flags)
+{
+       int padlen;
+       int headroom = skb_headroom(skb);
+       int tailroom = skb_tailroom(skb);
+       u32 packet_len;
+       u32 padbytes = 0xffff0000;
+
+       padlen = ((skb->len + 4) % 512) ? 0 : 4;
+
+       if ((!skb_cloned(skb))
+           && ((headroom + tailroom) >= (4 + padlen))) {
+               if ((headroom < 4) || (tailroom < padlen)) {
+                       skb->data = memmove(skb->head + 4, skb->data, skb->len);
+                       skb->tail = skb->data + skb->len;
+               }
+       } else {
+               struct sk_buff *skb2;
+               skb2 = skb_copy_expand(skb, 4, padlen, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       skb_push(skb, 4);
+       packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
+       memcpy(skb->data, &packet_len, sizeof(packet_len));
+
+       if ((skb->len % 512) == 0) {
+               memcpy( skb->tail, &padbytes, sizeof(padbytes));
+               skb_put(skb, sizeof(padbytes));
+       }
+       return skb;
+}
+
+static int ax88772_link_reset(struct usbnet *dev)
+{
+       u16 lpa;
+       u16 adv;
+       u16 res;
+       u16 mode;
+
+       mode = AX88772_MEDIUM_DEFAULT;
+       lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);
+       adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);
+       res = mii_nway_result(lpa|adv);
+
+       if ((res & LPA_DUPLEX) == 0)
+               mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
+       if ((res & LPA_100) == 0)
+               mode &= ~AX88772_MEDIUM_100MB;
+       ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+       return 0;
+}
+
+static const struct driver_info ax8817x_info = {
+       .description = "ASIX AX8817x USB 2.0 Ethernet",
+       .bind = ax8817x_bind,
+       .status = ax8817x_status,
+       .link_reset = ax88172_link_reset,
+       .reset = ax88172_link_reset,
+       .flags =  FLAG_ETHER,
+       .data = 0x00130103,
+};
+
+static const struct driver_info dlink_dub_e100_info = {
+       .description = "DLink DUB-E100 USB Ethernet",
+       .bind = ax8817x_bind,
+       .status = ax8817x_status,
+       .link_reset = ax88172_link_reset,
+       .reset = ax88172_link_reset,
+       .flags =  FLAG_ETHER,
+       .data = 0x009f9d9f,
+};
+
+static const struct driver_info netgear_fa120_info = {
+       .description = "Netgear FA-120 USB Ethernet",
+       .bind = ax8817x_bind,
+       .status = ax8817x_status,
+       .link_reset = ax88172_link_reset,
+       .reset = ax88172_link_reset,
+       .flags =  FLAG_ETHER,
+       .data = 0x00130103,
+};
+
+static const struct driver_info hawking_uf200_info = {
+       .description = "Hawking UF200 USB Ethernet",
+       .bind = ax8817x_bind,
+       .status = ax8817x_status,
+       .link_reset = ax88172_link_reset,
+       .reset = ax88172_link_reset,
+       .flags =  FLAG_ETHER,
+       .data = 0x001f1d1f,
+};
+
+static const struct driver_info ax88772_info = {
+       .description = "ASIX AX88772 USB 2.0 Ethernet",
+       .bind = ax88772_bind,
+       .status = ax8817x_status,
+       .link_reset = ax88772_link_reset,
+       .reset = ax88772_link_reset,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88772_rx_fixup,
+       .tx_fixup = ax88772_tx_fixup,
+       .data = 0x00130103,
+};
+
+static const struct usb_device_id      products [] = {
+{
+       // Linksys USB200M
+       USB_DEVICE (0x077b, 0x2226),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Netgear FA120
+       USB_DEVICE (0x0846, 0x1040),
+       .driver_info =  (unsigned long) &netgear_fa120_info,
+}, {
+       // DLink DUB-E100
+       USB_DEVICE (0x2001, 0x1a00),
+       .driver_info =  (unsigned long) &dlink_dub_e100_info,
+}, {
+       // Intellinet, ST Lab USB Ethernet
+       USB_DEVICE (0x0b95, 0x1720),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Hawking UF200, TrendNet TU2-ET100
+       USB_DEVICE (0x07b8, 0x420a),
+       .driver_info =  (unsigned long) &hawking_uf200_info,
+}, {
+        // Billionton Systems, USB2AR
+        USB_DEVICE (0x08dd, 0x90ff),
+        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // ATEN UC210T
+       USB_DEVICE (0x0557, 0x2009),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Buffalo LUA-U2-KTX
+       USB_DEVICE (0x0411, 0x003d),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
+       USB_DEVICE (0x6189, 0x182d),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // corega FEther USB2-TX
+       USB_DEVICE (0x07aa, 0x0017),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Surecom EP-1427X-2
+       USB_DEVICE (0x1189, 0x0893),
+       .driver_info = (unsigned long) &ax8817x_info,
+}, {
+       // goodway corp usb gwusb2e
+       USB_DEVICE (0x1631, 0x6200),
+       .driver_info = (unsigned long) &ax8817x_info,
+}, {
+       // ASIX AX88772 10/100
+        USB_DEVICE (0x0b95, 0x7720),
+        .driver_info = (unsigned long) &ax88772_info,
+},
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver asix_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "asix",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+       .disconnect =   usbnet_disconnect,
+};
+
+static int __init asix_init(void)
+{
+       return usb_register(&asix_driver);
+}
+module_init(asix_init);
+
+static void __exit asix_exit(void)
+{
+       usb_deregister(&asix_driver);
+}
+module_exit(asix_exit);
+
+MODULE_AUTHOR("David Hollis");
+MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
+MODULE_LICENSE("GPL");
+
index c8be912f24e1a08c6b5f55d97b4201ee3751a3e6..37ef365a2472323a190dc6e4d692558889418cae 100644 (file)
@@ -383,7 +383,6 @@ static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
 
        if (urb->status == -ECONNRESET) {
                dbg("Tx Reset.");
-               urb->transfer_flags &= ~URB_ASYNC_UNLINK;
                urb->status = 0;
                catc->netdev->trans_start = jiffies;
                catc->stats.tx_errors++;
@@ -445,7 +444,6 @@ static void catc_tx_timeout(struct net_device *netdev)
        struct catc *catc = netdev_priv(netdev);
 
        warn("Transmit timed out.");
-       catc->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
        usb_unlink_urb(catc->tx_urb);
 }
 
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
new file mode 100644 (file)
index 0000000..652b04b
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * CDC Ethernet based networking peripherals
+ * Copyright (C) 2003-2005 by David Brownell
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ctype.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb_cdc.h>
+
+#include "usbnet.h"
+
+
+/*
+ * probes control interface, claims data interface, collects the bulk
+ * endpoints, activates data interface (if needed), maybe sets MTU.
+ * all pure cdc, except for certain firmware workarounds, and knowing
+ * that rndis uses one different rule.
+ */
+int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u8                              *buf = intf->cur_altsetting->extra;
+       int                             len = intf->cur_altsetting->extralen;
+       struct usb_interface_descriptor *d;
+       struct cdc_state                *info = (void *) &dev->data;
+       int                             status;
+       int                             rndis;
+       struct usb_driver               *driver = driver_of(intf);
+
+       if (sizeof dev->data < sizeof *info)
+               return -EDOM;
+
+       /* expect strict spec conformance for the descriptors, but
+        * cope with firmware which stores them in the wrong place
+        */
+       if (len == 0 && dev->udev->actconfig->extralen) {
+               /* Motorola SB4100 (and others: Brad Hards says it's
+                * from a Broadcom design) put CDC descriptors here
+                */
+               buf = dev->udev->actconfig->extra;
+               len = dev->udev->actconfig->extralen;
+               if (len)
+                       dev_dbg(&intf->dev,
+                               "CDC descriptors on config\n");
+       }
+
+       /* this assumes that if there's a non-RNDIS vendor variant
+        * of cdc-acm, it'll fail RNDIS requests cleanly.
+        */
+       rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
+
+       memset(info, 0, sizeof *info);
+       info->control = intf;
+       while (len > 3) {
+               if (buf [1] != USB_DT_CS_INTERFACE)
+                       goto next_desc;
+
+               /* use bDescriptorSubType to identify the CDC descriptors.
+                * We expect devices with CDC header and union descriptors.
+                * For CDC Ethernet we need the ethernet descriptor.
+                * For RNDIS, ignore two (pointless) CDC modem descriptors
+                * in favor of a complicated OID-based RPC scheme doing what
+                * CDC Ethernet achieves with a simple descriptor.
+                */
+               switch (buf [2]) {
+               case USB_CDC_HEADER_TYPE:
+                       if (info->header) {
+                               dev_dbg(&intf->dev, "extra CDC header\n");
+                               goto bad_desc;
+                       }
+                       info->header = (void *) buf;
+                       if (info->header->bLength != sizeof *info->header) {
+                               dev_dbg(&intf->dev, "CDC header len %u\n",
+                                       info->header->bLength);
+                               goto bad_desc;
+                       }
+                       break;
+               case USB_CDC_UNION_TYPE:
+                       if (info->u) {
+                               dev_dbg(&intf->dev, "extra CDC union\n");
+                               goto bad_desc;
+                       }
+                       info->u = (void *) buf;
+                       if (info->u->bLength != sizeof *info->u) {
+                               dev_dbg(&intf->dev, "CDC union len %u\n",
+                                       info->u->bLength);
+                               goto bad_desc;
+                       }
+
+                       /* we need a master/control interface (what we're
+                        * probed with) and a slave/data interface; union
+                        * descriptors sort this all out.
+                        */
+                       info->control = usb_ifnum_to_if(dev->udev,
+                                               info->u->bMasterInterface0);
+                       info->data = usb_ifnum_to_if(dev->udev,
+                                               info->u->bSlaveInterface0);
+                       if (!info->control || !info->data) {
+                               dev_dbg(&intf->dev,
+                                       "master #%u/%p slave #%u/%p\n",
+                                       info->u->bMasterInterface0,
+                                       info->control,
+                                       info->u->bSlaveInterface0,
+                                       info->data);
+                               goto bad_desc;
+                       }
+                       if (info->control != intf) {
+                               dev_dbg(&intf->dev, "bogus CDC Union\n");
+                               /* Ambit USB Cable Modem (and maybe others)
+                                * interchanges master and slave interface.
+                                */
+                               if (info->data == intf) {
+                                       info->data = info->control;
+                                       info->control = intf;
+                               } else
+                                       goto bad_desc;
+                       }
+
+                       /* a data interface altsetting does the real i/o */
+                       d = &info->data->cur_altsetting->desc;
+                       if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
+                               dev_dbg(&intf->dev, "slave class %u\n",
+                                       d->bInterfaceClass);
+                               goto bad_desc;
+                       }
+                       break;
+               case USB_CDC_ETHERNET_TYPE:
+                       if (info->ether) {
+                               dev_dbg(&intf->dev, "extra CDC ether\n");
+                               goto bad_desc;
+                       }
+                       info->ether = (void *) buf;
+                       if (info->ether->bLength != sizeof *info->ether) {
+                               dev_dbg(&intf->dev, "CDC ether len %u\n",
+                                       info->ether->bLength);
+                               goto bad_desc;
+                       }
+                       dev->hard_mtu = le16_to_cpu(
+                                               info->ether->wMaxSegmentSize);
+                       /* because of Zaurus, we may be ignoring the host
+                        * side link address we were given.
+                        */
+                       break;
+               }
+next_desc:
+               len -= buf [0]; /* bLength */
+               buf += buf [0];
+       }
+
+       if (!info->header || !info->u || (!rndis && !info->ether)) {
+               dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
+                       info->header ? "" : "header ",
+                       info->u ? "" : "union ",
+                       info->ether ? "" : "ether ");
+               goto bad_desc;
+       }
+
+       /* claim data interface and set it up ... with side effects.
+        * network traffic can't flow until an altsetting is enabled.
+        */
+       status = usb_driver_claim_interface(driver, info->data, dev);
+       if (status < 0)
+               return status;
+       status = usbnet_get_endpoints(dev, info->data);
+       if (status < 0) {
+               /* ensure immediate exit from usbnet_disconnect */
+               usb_set_intfdata(info->data, NULL);
+               usb_driver_release_interface(driver, info->data);
+               return status;
+       }
+
+       /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
+       dev->status = NULL;
+       if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
+               struct usb_endpoint_descriptor  *desc;
+
+               dev->status = &info->control->cur_altsetting->endpoint [0];
+               desc = &dev->status->desc;
+               if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
+                               || !(desc->bEndpointAddress & USB_DIR_IN)
+                               || (le16_to_cpu(desc->wMaxPacketSize)
+                                       < sizeof(struct usb_cdc_notification))
+                               || !desc->bInterval) {
+                       dev_dbg(&intf->dev, "bad notification endpoint\n");
+                       dev->status = NULL;
+               }
+       }
+       if (rndis && !dev->status) {
+               dev_dbg(&intf->dev, "missing RNDIS status endpoint\n");
+               usb_set_intfdata(info->data, NULL);
+               usb_driver_release_interface(driver, info->data);
+               return -ENODEV;
+       }
+       return 0;
+
+bad_desc:
+       dev_info(&dev->udev->dev, "bad CDC descriptors\n");
+       return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind);
+
+void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct cdc_state                *info = (void *) &dev->data;
+       struct usb_driver               *driver = driver_of(intf);
+
+       /* disconnect master --> disconnect slave */
+       if (intf == info->control && info->data) {
+               /* ensure immediate exit from usbnet_disconnect */
+               usb_set_intfdata(info->data, NULL);
+               usb_driver_release_interface(driver, info->data);
+               info->data = NULL;
+       }
+
+       /* and vice versa (just in case) */
+       else if (intf == info->data && info->control) {
+               /* ensure immediate exit from usbnet_disconnect */
+               usb_set_intfdata(info->control, NULL);
+               usb_driver_release_interface(driver, info->control);
+               info->control = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
+
+\f
+/*-------------------------------------------------------------------------
+ *
+ * Communications Device Class, Ethernet Control model
+ *
+ * Takes two interfaces.  The DATA interface is inactive till an altsetting
+ * is selected.  Configuration data includes class descriptors.  There's
+ * an optional status endpoint on the control interface.
+ *
+ * This should interop with whatever the 2.4 "CDCEther.c" driver
+ * (by Brad Hards) talked with, with more functionality.
+ *
+ *-------------------------------------------------------------------------*/
+
+static void dumpspeed(struct usbnet *dev, __le32 *speeds)
+{
+       if (netif_msg_timer(dev))
+               devinfo(dev, "link speeds: %u kbps up, %u kbps down",
+                       __le32_to_cpu(speeds[0]) / 1000,
+               __le32_to_cpu(speeds[1]) / 1000);
+}
+
+static void cdc_status(struct usbnet *dev, struct urb *urb)
+{
+       struct usb_cdc_notification     *event;
+
+       if (urb->actual_length < sizeof *event)
+               return;
+
+       /* SPEED_CHANGE can get split into two 8-byte packets */
+       if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
+               dumpspeed(dev, (__le32 *) urb->transfer_buffer);
+               return;
+       }
+
+       event = urb->transfer_buffer;
+       switch (event->bNotificationType) {
+       case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+               if (netif_msg_timer(dev))
+                       devdbg(dev, "CDC: carrier %s",
+                                       event->wValue ? "on" : "off");
+               if (event->wValue)
+                       netif_carrier_on(dev->net);
+               else
+                       netif_carrier_off(dev->net);
+               break;
+       case USB_CDC_NOTIFY_SPEED_CHANGE:       /* tx/rx rates */
+               if (netif_msg_timer(dev))
+                       devdbg(dev, "CDC: speed change (len %d)",
+                                       urb->actual_length);
+               if (urb->actual_length != (sizeof *event + 8))
+                       set_bit(EVENT_STS_SPLIT, &dev->flags);
+               else
+                       dumpspeed(dev, (__le32 *) &event[1]);
+               break;
+       /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
+        * but there are no standard formats for the response data.
+        */
+       default:
+               deverr(dev, "CDC: unexpected notification %02x!",
+                                event->bNotificationType);
+               break;
+       }
+}
+
+static u8 nibble(unsigned char c)
+{
+       if (likely(isdigit(c)))
+               return c - '0';
+       c = toupper(c);
+       if (likely(isxdigit(c)))
+               return 10 + c - 'A';
+       return 0;
+}
+
+static inline int
+get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
+{
+       int             tmp, i;
+       unsigned char   buf [13];
+
+       tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
+       if (tmp != 12) {
+               dev_dbg(&dev->udev->dev,
+                       "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
+               if (tmp >= 0)
+                       tmp = -EINVAL;
+               return tmp;
+       }
+       for (i = tmp = 0; i < 6; i++, tmp += 2)
+               dev->net->dev_addr [i] =
+                       (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
+       return 0;
+}
+
+static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int                             status;
+       struct cdc_state                *info = (void *) &dev->data;
+
+       status = usbnet_generic_cdc_bind(dev, intf);
+       if (status < 0)
+               return status;
+
+       status = get_ethernet_addr(dev, info->ether);
+       if (status < 0) {
+               usb_set_intfdata(info->data, NULL);
+               usb_driver_release_interface(driver_of(intf), info->data);
+               return status;
+       }
+
+       /* FIXME cdc-ether has some multicast code too, though it complains
+        * in routine cases.  info->ether describes the multicast support.
+        * Implement that here, manipulating the cdc filter as needed.
+        */
+       return 0;
+}
+
+static const struct driver_info        cdc_info = {
+       .description =  "CDC Ethernet Device",
+       .flags =        FLAG_ETHER,
+       // .check_connect = cdc_check_connect,
+       .bind =         cdc_bind,
+       .unbind =       usbnet_cdc_unbind,
+       .status =       cdc_status,
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+static const struct usb_device_id      products [] = {
+/*
+ * BLACKLIST !!
+ *
+ * First blacklist any products that are egregiously nonconformant
+ * with the CDC Ethernet specs.  Minor braindamage we cope with; when
+ * they're not even trying, needing a separate driver is only the first
+ * of the differences to show up.
+ */
+
+#define        ZAURUS_MASTER_INTERFACE \
+       .bInterfaceClass        = USB_CLASS_COMM, \
+       .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET, \
+       .bInterfaceProtocol     = USB_CDC_PROTO_NONE
+
+/* SA-1100 based Sharp Zaurus ("collie"), or compatible;
+ * wire-incompatible with true CDC Ethernet implementations.
+ * (And, it seems, needlessly so...)
+ */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8004,
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+},
+
+/* PXA-25x based Sharp Zaurii.  Note that it seems some of these
+ * (later models especially) may have shipped only with firmware
+ * advertising false "CDC MDLM" compatibility ... but we're not
+ * clear which models did that, so for now let's assume the worst.
+ */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8005,       /* A-300 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8006,       /* B-500/SL-5600 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                 | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8007,       /* C-700 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x9031,       /* C-750 C-760 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x9032,       /* SL-6000 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       /* reported with some C860 units */
+       .idProduct              = 0x9050,       /* C-860 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info            = 0,
+},
+
+/*
+ * WHITELIST!!!
+ *
+ * CDC Ether uses two interfaces, not necessarily consecutive.
+ * We match the main interface, ignoring the optional device
+ * class so we could handle devices that aren't exclusively
+ * CDC ether.
+ *
+ * NOTE:  this match must come AFTER entries blacklisting devices
+ * because of bugs/quirks in a given product (like Zaurus, above).
+ */
+{
+       USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
+                       USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+},
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver cdc_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "cdc_ether",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+
+static int __init cdc_init(void)
+{
+       BUG_ON((sizeof(((struct usbnet *)0)->data)
+                       < sizeof(struct cdc_state)));
+
+       return usb_register(&cdc_driver);
+}
+module_init(cdc_init);
+
+static void __exit cdc_exit(void)
+{
+       usb_deregister(&cdc_driver);
+}
+module_exit(cdc_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("USB CDC Ethernet devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
new file mode 100644 (file)
index 0000000..f1730b6
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * Simple "CDC Subset" USB Networking Links
+ * Copyright (C) 2000-2005 by David Brownell
+ *
+ * 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-1307  USA
+ */
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+
+/*
+ * This supports simple USB network links that don't require any special
+ * framing or hardware control operations.  The protocol used here is a
+ * strict subset of CDC Ethernet, with three basic differences reflecting
+ * the goal that almost any hardware should run it:
+ *
+ *  - Minimal runtime control:  one interface, no altsettings, and
+ *    no vendor or class specific control requests.  If a device is
+ *    configured, it is allowed to exchange packets with the host.
+ *    Fancier models would mean not working on some hardware.
+ *
+ *  - Minimal manufacturing control:  no IEEE "Organizationally
+ *    Unique ID" required, or an EEPROMs to store one.  Each host uses
+ *    one random "locally assigned" Ethernet address instead, which can
+ *    of course be overridden using standard tools like "ifconfig".
+ *    (With 2^46 such addresses, same-net collisions are quite rare.)
+ *
+ *  - There is no additional framing data for USB.  Packets are written
+ *    exactly as in CDC Ethernet, starting with an Ethernet header and
+ *    terminated by a short packet.  However, the host will never send a
+ *    zero length packet; some systems can't handle those robustly.
+ *
+ * Anything that can transmit and receive USB bulk packets can implement
+ * this protocol.  That includes both smart peripherals and quite a lot
+ * of "host-to-host" USB cables (which embed two devices back-to-back).
+ *
+ * Note that although Linux may use many of those host-to-host links
+ * with this "cdc_subset" framing, that doesn't mean there may not be a
+ * better approach.  Handling the "other end unplugs/replugs" scenario
+ * well tends to require chip-specific vendor requests.  Also, Windows
+ * peers at the other end of host-to-host cables may expect their own
+ * framing to be used rather than this "cdc_subset" model.
+ */
+
+#if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX)
+/* PDA style devices are always connected if present */
+static int always_connected (struct usbnet *dev)
+{
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_USB_ALI_M5632
+#define        HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * ALi M5632 driver ... does high speed
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info        ali_m5632_info = {
+       .description =  "ALi M5632",
+};
+
+
+#endif
+
+\f
+#ifdef CONFIG_USB_AN2720
+#define        HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * AnchorChips 2720 driver ... http://www.cypress.com
+ *
+ * This doesn't seem to have a way to detect whether the peer is
+ * connected, or need any reset handshaking.  It's got pretty big
+ * internal buffers (handles most of a frame's worth of data).
+ * Chip data sheets don't describe any vendor control messages.
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info        an2720_info = {
+       .description =  "AnchorChips/Cypress 2720",
+       // no reset available!
+       // no check_connect available!
+
+       .in = 2, .out = 2,              // direction distinguishes these
+};
+
+#endif /* CONFIG_USB_AN2720 */
+
+\f
+#ifdef CONFIG_USB_BELKIN
+#define        HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller
+ *
+ * ... also two eTEK designs, including one sold as "Advance USBNET"
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info        belkin_info = {
+       .description =  "Belkin, eTEK, or compatible",
+};
+
+#endif /* CONFIG_USB_BELKIN */
+
+
+\f
+#ifdef CONFIG_USB_EPSON2888
+#define        HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * EPSON USB clients
+ *
+ * This is the same idea as Linux PDAs (below) except the firmware in the
+ * device might not be Tux-powered.  Epson provides reference firmware that
+ * implements this interface.  Product developers can reuse or modify that
+ * code, such as by using their own product and vendor codes.
+ *
+ * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info        epson2888_info = {
+       .description =  "Epson USB Device",
+       .check_connect = always_connected,
+
+       .in = 4, .out = 3,
+};
+
+#endif /* CONFIG_USB_EPSON2888 */
+
+\f
+#ifdef CONFIG_USB_KC2190
+#define HAVE_HARDWARE
+static const struct driver_info kc2190_info = {
+       .description =  "KC Technology KC-190",
+};
+#endif /* CONFIG_USB_KC2190 */
+
+\f
+#ifdef CONFIG_USB_ARMLINUX
+#define        HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * Intel's SA-1100 chip integrates basic USB support, and is used
+ * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
+ * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
+ * network using minimal USB framing data.
+ *
+ * This describes the driver currently in standard ARM Linux kernels.
+ * The Zaurus uses a different driver (see later).
+ *
+ * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
+ * and different USB endpoint numbering than the SA1100 devices.  The
+ * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
+ * so we rely on the endpoint descriptors.
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info        linuxdev_info = {
+       .description =  "Linux Device",
+       .check_connect = always_connected,
+};
+
+static const struct driver_info        yopy_info = {
+       .description =  "Yopy",
+       .check_connect = always_connected,
+};
+
+static const struct driver_info        blob_info = {
+       .description =  "Boot Loader OBject",
+       .check_connect = always_connected,
+};
+
+#endif /* CONFIG_USB_ARMLINUX */
+
+\f
+/*-------------------------------------------------------------------------*/
+
+#ifndef        HAVE_HARDWARE
+#error You need to configure some hardware for this driver
+#endif
+
+/*
+ * chip vendor names won't normally be on the cables, and
+ * may not be on the device.
+ */
+
+static const struct usb_device_id      products [] = {
+
+#ifdef CONFIG_USB_ALI_M5632
+{
+       USB_DEVICE (0x0402, 0x5632),    // ALi defaults
+       .driver_info =  (unsigned long) &ali_m5632_info,
+},
+#endif
+
+#ifdef CONFIG_USB_AN2720
+{
+       USB_DEVICE (0x0547, 0x2720),    // AnchorChips defaults
+       .driver_info =  (unsigned long) &an2720_info,
+}, {
+       USB_DEVICE (0x0547, 0x2727),    // Xircom PGUNET
+       .driver_info =  (unsigned long) &an2720_info,
+},
+#endif
+
+#ifdef CONFIG_USB_BELKIN
+{
+       USB_DEVICE (0x050d, 0x0004),    // Belkin
+       .driver_info =  (unsigned long) &belkin_info,
+}, {
+       USB_DEVICE (0x056c, 0x8100),    // eTEK
+       .driver_info =  (unsigned long) &belkin_info,
+}, {
+       USB_DEVICE (0x0525, 0x9901),    // Advance USBNET (eTEK)
+       .driver_info =  (unsigned long) &belkin_info,
+},
+#endif
+
+#ifdef CONFIG_USB_EPSON2888
+{
+       USB_DEVICE (0x0525, 0x2888),    // EPSON USB client
+       .driver_info    = (unsigned long) &epson2888_info,
+},
+#endif
+
+#ifdef CONFIG_USB_KC2190
+{
+       USB_DEVICE (0x050f, 0x0190),    // KC-190
+       .driver_info =  (unsigned long) &kc2190_info,
+},
+#endif
+
+#ifdef CONFIG_USB_ARMLINUX
+/*
+ * SA-1100 using standard ARM Linux kernels, or compatible.
+ * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
+ * The sa-1100 "usb-eth" driver handles the basic framing.
+ *
+ * PXA25x or PXA210 ...  these use a "usb-eth" driver much like
+ * the sa1100 one, but hardware uses different endpoint numbers.
+ *
+ * Or the Linux "Ethernet" gadget on hardware that can't talk
+ * CDC Ethernet (e.g., no altsettings), in either of two modes:
+ *  - acting just like the old "usb-eth" firmware, though
+ *    the implementation is different
+ *  - supporting RNDIS as the first/default configuration for
+ *    MS-Windows interop; Linux needs to use the other config
+ */
+{
+       // 1183 = 0x049F, both used as hex values?
+       // Compaq "Itsy" vendor/product id
+       USB_DEVICE (0x049F, 0x505A),    // usb-eth, or compatible
+       .driver_info =  (unsigned long) &linuxdev_info,
+}, {
+       USB_DEVICE (0x0E7E, 0x1001),    // G.Mate "Yopy"
+       .driver_info =  (unsigned long) &yopy_info,
+}, {
+       USB_DEVICE (0x8086, 0x07d3),    // "blob" bootloader
+       .driver_info =  (unsigned long) &blob_info,
+}, {
+       // Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config
+       // e.g. Gumstix, current OpenZaurus, ...
+       USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
+       .driver_info =  (unsigned long) &linuxdev_info,
+},
+#endif
+
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_driver cdc_subset_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "cdc_subset",
+       .probe =        usbnet_probe,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+       .disconnect =   usbnet_disconnect,
+       .id_table =     products,
+};
+
+static int __init cdc_subset_init(void)
+{
+       return usb_register(&cdc_subset_driver);
+}
+module_init(cdc_subset_init);
+
+static void __exit cdc_subset_exit(void)
+{
+       usb_deregister(&cdc_subset_driver);
+}
+module_exit(cdc_subset_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
new file mode 100644 (file)
index 0000000..c8763ae
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * GeneSys GL620USB-A based links
+ * Copyright (C) 2001 by Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
+ * Copyright (C) 2001 by Stanislav Brabec <utx@penguin.cz>
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+
+/*
+ * GeneSys GL620USB-A (www.genesyslogic.com.tw)
+ *
+ * ... should partially interop with the Win32 driver for this hardware.
+ * The GeneSys docs imply there's some NDIS issue motivating this framing.
+ *
+ * Some info from GeneSys:
+ *  - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
+ *    (Some cables, like the BAFO-100c, use the half duplex version.)
+ *  - For the full duplex model, the low bit of the version code says
+ *    which side is which ("left/right").
+ *  - For the half duplex type, a control/interrupt handshake settles
+ *    the transfer direction.  (That's disabled here, partially coded.)
+ *    A control URB would block until other side writes an interrupt.
+ *
+ * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
+ * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
+ */
+
+// control msg write command
+#define GENELINK_CONNECT_WRITE                 0xF0
+// interrupt pipe index
+#define GENELINK_INTERRUPT_PIPE                        0x03
+// interrupt read buffer size
+#define INTERRUPT_BUFSIZE                      0x08
+// interrupt pipe interval value
+#define GENELINK_INTERRUPT_INTERVAL            0x10
+// max transmit packet number per transmit
+#define GL_MAX_TRANSMIT_PACKETS                        32
+// max packet length
+#define GL_MAX_PACKET_LEN                      1514
+// max receive buffer size
+#define GL_RCV_BUF_SIZE                \
+       (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
+
+struct gl_packet {
+       u32             packet_length;
+       char            packet_data [1];
+};
+
+struct gl_header {
+       u32                     packet_count;
+       struct gl_packet        packets;
+};
+
+#ifdef GENELINK_ACK
+
+// FIXME:  this code is incomplete, not debugged; it doesn't
+// handle interrupts correctly; it should use the generic
+// status IRQ code (which didn't exist back in 2001).
+
+struct gl_priv {
+       struct urb      *irq_urb;
+       char            irq_buf [INTERRUPT_BUFSIZE];
+};
+
+static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value)
+{
+       int retval;
+
+       retval = usb_control_msg(dev->udev,
+                     usb_sndctrlpipe(dev->udev, 0),
+                     request,
+                     USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                     value,
+                     0,                        // index
+                     0,                        // data buffer
+                     0,                        // size
+                     USB_CTRL_SET_TIMEOUT);
+       return retval;
+}
+
+static void gl_interrupt_complete(struct urb *urb, struct pt_regs *regs)
+{
+       int status = urb->status;
+
+       switch (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__, status);
+               return;
+       default:
+               dbg("%s - nonzero urb status received: %d",
+                               __FUNCTION__, urb->status);
+       }
+
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status)
+               err("%s - usb_submit_urb failed with result %d",
+                    __FUNCTION__, status);
+}
+
+static int gl_interrupt_read(struct usbnet *dev)
+{
+       struct gl_priv  *priv = dev->priv_data;
+       int             retval;
+
+       // issue usb interrupt read
+       if (priv && priv->irq_urb) {
+               // submit urb
+               if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0)
+                       dbg("gl_interrupt_read: submit fail - %X...", retval);
+               else
+                       dbg("gl_interrupt_read: submit success...");
+       }
+
+       return 0;
+}
+
+// check whether another side is connected
+static int genelink_check_connect(struct usbnet *dev)
+{
+       int                     retval;
+
+       dbg("genelink_check_connect...");
+
+       // detect whether another side is connected
+       if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
+               dbg("%s: genelink_check_connect write fail - %X",
+                       dev->net->name, retval);
+               return retval;
+       }
+
+       // usb interrupt read to ack another side
+       if ((retval = gl_interrupt_read(dev)) != 0) {
+               dbg("%s: genelink_check_connect read fail - %X",
+                       dev->net->name, retval);
+               return retval;
+       }
+
+       dbg("%s: genelink_check_connect read success", dev->net->name);
+       return 0;
+}
+
+// allocate and initialize the private data for genelink
+static int genelink_init(struct usbnet *dev)
+{
+       struct gl_priv *priv;
+
+       // allocate the private data structure
+       if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) {
+               dbg("%s: cannot allocate private data per device",
+                       dev->net->name);
+               return -ENOMEM;
+       }
+
+       // allocate irq urb
+       if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) {
+               dbg("%s: cannot allocate private irq urb per device",
+                       dev->net->name);
+               kfree(priv);
+               return -ENOMEM;
+       }
+
+       // fill irq urb
+       usb_fill_int_urb(priv->irq_urb, dev->udev,
+               usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE),
+               priv->irq_buf, INTERRUPT_BUFSIZE,
+               gl_interrupt_complete, 0,
+               GENELINK_INTERRUPT_INTERVAL);
+
+       // set private data pointer
+       dev->priv_data = priv;
+
+       return 0;
+}
+
+// release the private data
+static int genelink_free(struct usbnet *dev)
+{
+       struct gl_priv  *priv = dev->priv_data;
+
+       if (!priv)
+               return 0;
+
+// FIXME:  can't cancel here; it's synchronous, and
+// should have happened earlier in any case (interrupt
+// handling needs to be generic)
+
+       // cancel irq urb first
+       usb_kill_urb(priv->irq_urb);
+
+       // free irq urb
+       usb_free_urb(priv->irq_urb);
+
+       // free the private data structure
+       kfree(priv);
+
+       return 0;
+}
+
+#endif
+
+static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct gl_header        *header;
+       struct gl_packet        *packet;
+       struct sk_buff          *gl_skb;
+       u32                     size;
+
+       header = (struct gl_header *) skb->data;
+
+       // get the packet count of the received skb
+       le32_to_cpus(&header->packet_count);
+       if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS)
+                       || (header->packet_count < 0)) {
+               dbg("genelink: invalid received packet count %d",
+                       header->packet_count);
+               return 0;
+       }
+
+       // set the current packet pointer to the first packet
+       packet = &header->packets;
+
+       // decrement the length for the packet count size 4 bytes
+       skb_pull(skb, 4);
+
+       while (header->packet_count > 1) {
+               // get the packet length
+               size = le32_to_cpu(packet->packet_length);
+
+               // this may be a broken packet
+               if (size > GL_MAX_PACKET_LEN) {
+                       dbg("genelink: invalid rx length %d", size);
+                       return 0;
+               }
+
+               // allocate the skb for the individual packet
+               gl_skb = alloc_skb(size, GFP_ATOMIC);
+               if (gl_skb) {
+
+                       // copy the packet data to the new skb
+                       memcpy(skb_put(gl_skb, size),
+                                       packet->packet_data, size);
+                       usbnet_skb_return(dev, gl_skb);
+               }
+
+               // advance to the next packet
+               packet = (struct gl_packet *)
+                       &packet->packet_data [size];
+               header->packet_count--;
+
+               // shift the data pointer to the next gl_packet
+               skb_pull(skb, size + 4);
+       }
+
+       // skip the packet length field 4 bytes
+       skb_pull(skb, 4);
+
+       if (skb->len > GL_MAX_PACKET_LEN) {
+               dbg("genelink: invalid rx length %d", skb->len);
+               return 0;
+       }
+       return 1;
+}
+
+static struct sk_buff *
+genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+       int     padlen;
+       int     length = skb->len;
+       int     headroom = skb_headroom(skb);
+       int     tailroom = skb_tailroom(skb);
+       u32     *packet_count;
+       u32     *packet_len;
+
+       // FIXME:  magic numbers, bleech
+       padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
+
+       if ((!skb_cloned(skb))
+                       && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
+               if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
+                       skb->data = memmove(skb->head + (4 + 4*1),
+                                            skb->data, skb->len);
+                       skb->tail = skb->data + skb->len;
+               }
+       } else {
+               struct sk_buff  *skb2;
+               skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       // attach the packet count to the header
+       packet_count = (u32 *) skb_push(skb, (4 + 4*1));
+       packet_len = packet_count + 1;
+
+       *packet_count = cpu_to_le32(1);
+       *packet_len = cpu_to_le32(length);
+
+       // add padding byte
+       if ((skb->len % dev->maxpacket) == 0)
+               skb_put(skb, 1);
+
+       return skb;
+}
+
+static int genelink_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       dev->hard_mtu = GL_RCV_BUF_SIZE;
+       dev->net->hard_header_len += 4;
+       dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in);
+       dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out);
+       return 0;
+}
+
+static const struct driver_info        genelink_info = {
+       .description =  "Genesys GeneLink",
+       .flags =        FLAG_FRAMING_GL | FLAG_NO_SETINT,
+       .bind =         genelink_bind,
+       .rx_fixup =     genelink_rx_fixup,
+       .tx_fixup =     genelink_tx_fixup,
+
+       .in = 1, .out = 2,
+
+#ifdef GENELINK_ACK
+       .check_connect =genelink_check_connect,
+#endif
+};
+
+static const struct usb_device_id      products [] = {
+
+{
+       USB_DEVICE(0x05e3, 0x0502),     // GL620USB-A
+       .driver_info =  (unsigned long) &genelink_info,
+},
+       /* NOT: USB_DEVICE(0x05e3, 0x0501),     // GL620USB
+        * that's half duplex, not currently supported
+        */
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver gl620a_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "gl620a",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+static int __init usbnet_init(void)
+{
+       return usb_register(&gl620a_driver);
+}
+module_init(usbnet_init);
+
+static void __exit usbnet_exit(void)
+{
+       usb_deregister(&gl620a_driver);
+}
+module_exit(usbnet_exit);
+
+MODULE_AUTHOR("Jiun-Jie Huang");
+MODULE_DESCRIPTION("GL620-USB-A Host-to-Host Link cables");
+MODULE_LICENSE("GPL");
+
index 7ffa99b9760f70b0cde4ca33ba67e432fe5e2ba4..e04b0ce3611a3e0b9999bdf6ecc8bacedf032fa9 100644 (file)
@@ -787,7 +787,6 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
                      kaweth_usb_transmit_complete,
                      kaweth);
        kaweth->end = 0;
-       kaweth->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
 
        if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
        {
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
new file mode 100644 (file)
index 0000000..a4309c4
--- /dev/null
@@ -0,0 +1,622 @@
+/*
+ * Net1080 based USB host-to-host cables
+ * Copyright (C) 2000-2005 by David Brownell
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include <asm/unaligned.h>
+
+#include "usbnet.h"
+
+
+/*
+ * Netchip 1080 driver ... http://www.netchip.com
+ * (Sept 2004:  End-of-life announcement has been sent.)
+ * Used in (some) LapLink cables
+ */
+
+#define frame_errors   data[1]
+
+/*
+ * NetChip framing of ethernet packets, supporting additional error
+ * checks for links that may drop bulk packets from inside messages.
+ * Odd USB length == always short read for last usb packet.
+ *     - nc_header
+ *     - Ethernet header (14 bytes)
+ *     - payload
+ *     - (optional padding byte, if needed so length becomes odd)
+ *     - nc_trailer
+ *
+ * This framing is to be avoided for non-NetChip devices.
+ */
+
+struct nc_header {             // packed:
+       __le16  hdr_len;                // sizeof nc_header (LE, all)
+       __le16  packet_len;             // payload size (including ethhdr)
+       __le16  packet_id;              // detects dropped packets
+#define MIN_HEADER     6
+
+       // all else is optional, and must start with:
+       // __le16       vendorId;       // from usb-if
+       // __le16       productId;
+} __attribute__((__packed__));
+
+#define        PAD_BYTE        ((unsigned char)0xAC)
+
+struct nc_trailer {
+       __le16  packet_id;
+} __attribute__((__packed__));
+
+// packets may use FLAG_FRAMING_NC and optional pad
+#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
+                               + sizeof (struct ethhdr) \
+                               + (mtu) \
+                               + 1 \
+                               + sizeof (struct nc_trailer))
+
+#define MIN_FRAMED     FRAMED_SIZE(0)
+
+/* packets _could_ be up to 64KB... */
+#define NC_MAX_PACKET  32767
+
+
+/*
+ * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
+ * before the hardware drops it.  If that's done, the driver will need to
+ * frame network packets to guard against the dropped USB packets.  The win32
+ * driver sets this for both sides of the link.
+ */
+#define        NC_READ_TTL_MS  ((u8)255)       // ms
+
+/*
+ * We ignore most registers and EEPROM contents.
+ */
+#define        REG_USBCTL      ((u8)0x04)
+#define REG_TTL                ((u8)0x10)
+#define REG_STATUS     ((u8)0x11)
+
+/*
+ * Vendor specific requests to read/write data
+ */
+#define        REQUEST_REGISTER        ((u8)0x10)
+#define        REQUEST_EEPROM          ((u8)0x11)
+
+static int
+nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
+{
+       int status = usb_control_msg(dev->udev,
+               usb_rcvctrlpipe(dev->udev, 0),
+               req,
+               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               0, regnum,
+               retval_ptr, sizeof *retval_ptr,
+               USB_CTRL_GET_TIMEOUT);
+       if (status > 0)
+               status = 0;
+       if (!status)
+               le16_to_cpus(retval_ptr);
+       return status;
+}
+
+static inline int
+nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr)
+{
+       return nc_vendor_read(dev, REQUEST_REGISTER, regnum, retval_ptr);
+}
+
+// no retval ... can become async, usable in_interrupt()
+static void
+nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value)
+{
+       usb_control_msg(dev->udev,
+               usb_sndctrlpipe(dev->udev, 0),
+               req,
+               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               value, regnum,
+               NULL, 0,                        // data is in setup packet
+               USB_CTRL_SET_TIMEOUT);
+}
+
+static inline void
+nc_register_write(struct usbnet *dev, u8 regnum, u16 value)
+{
+       nc_vendor_write(dev, REQUEST_REGISTER, regnum, value);
+}
+
+
+#if 0
+static void nc_dump_registers(struct usbnet *dev)
+{
+       u8      reg;
+       u16     *vp = kmalloc(sizeof (u16));
+
+       if (!vp) {
+               dbg("no memory?");
+               return;
+       }
+
+       dbg("%s registers:", dev->net->name);
+       for (reg = 0; reg < 0x20; reg++) {
+               int retval;
+
+               // reading some registers is trouble
+               if (reg >= 0x08 && reg <= 0xf)
+                       continue;
+               if (reg >= 0x12 && reg <= 0x1e)
+                       continue;
+
+               retval = nc_register_read(dev, reg, vp);
+               if (retval < 0)
+                       dbg("%s reg [0x%x] ==> error %d",
+                               dev->net->name, reg, retval);
+               else
+                       dbg("%s reg [0x%x] = 0x%x",
+                               dev->net->name, reg, *vp);
+       }
+       kfree(vp);
+}
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Control register
+ */
+
+#define        USBCTL_WRITABLE_MASK    0x1f0f
+// bits 15-13 reserved, r/o
+#define        USBCTL_ENABLE_LANG      (1 << 12)
+#define        USBCTL_ENABLE_MFGR      (1 << 11)
+#define        USBCTL_ENABLE_PROD      (1 << 10)
+#define        USBCTL_ENABLE_SERIAL    (1 << 9)
+#define        USBCTL_ENABLE_DEFAULTS  (1 << 8)
+// bits 7-4 reserved, r/o
+#define        USBCTL_FLUSH_OTHER      (1 << 3)
+#define        USBCTL_FLUSH_THIS       (1 << 2)
+#define        USBCTL_DISCONN_OTHER    (1 << 1)
+#define        USBCTL_DISCONN_THIS     (1 << 0)
+
+static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
+{
+       if (!netif_msg_link(dev))
+               return;
+       devdbg(dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
+                       " this%s%s;"
+                       " other%s%s; r/o 0x%x",
+               dev->udev->bus->bus_name, dev->udev->devpath,
+               usbctl,
+               (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
+               (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
+               (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
+               (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
+               (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
+
+               (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
+               (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
+               (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
+               (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
+               usbctl & ~USBCTL_WRITABLE_MASK
+               );
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Status register
+ */
+
+#define        STATUS_PORT_A           (1 << 15)
+
+#define        STATUS_CONN_OTHER       (1 << 14)
+#define        STATUS_SUSPEND_OTHER    (1 << 13)
+#define        STATUS_MAILBOX_OTHER    (1 << 12)
+#define        STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
+
+#define        STATUS_CONN_THIS        (1 << 6)
+#define        STATUS_SUSPEND_THIS     (1 << 5)
+#define        STATUS_MAILBOX_THIS     (1 << 4)
+#define        STATUS_PACKETS_THIS(n)  (((n) >> 0) && 0x03)
+
+#define        STATUS_UNSPEC_MASK      0x0c8c
+#define        STATUS_NOISE_MASK       ((u16)~(0x0303|STATUS_UNSPEC_MASK))
+
+
+static inline void nc_dump_status(struct usbnet *dev, u16 status)
+{
+       if (!netif_msg_link(dev))
+               return;
+       devdbg(dev, "net1080 %s-%s status 0x%x:"
+                       " this (%c) PKT=%d%s%s%s;"
+                       " other PKT=%d%s%s%s; unspec 0x%x",
+               dev->udev->bus->bus_name, dev->udev->devpath,
+               status,
+
+               // XXX the packet counts don't seem right
+               // (1 at reset, not 0); maybe UNSPEC too
+
+               (status & STATUS_PORT_A) ? 'A' : 'B',
+               STATUS_PACKETS_THIS(status),
+               (status & STATUS_CONN_THIS) ? " CON" : "",
+               (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
+               (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
+
+               STATUS_PACKETS_OTHER(status),
+               (status & STATUS_CONN_OTHER) ? " CON" : "",
+               (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
+               (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
+
+               status & STATUS_UNSPEC_MASK
+               );
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * TTL register
+ */
+
+#define        TTL_THIS(ttl)   (0x00ff & ttl)
+#define        TTL_OTHER(ttl)  (0x00ff & (ttl >> 8))
+#define MK_TTL(this,other)     ((u16)(((other)<<8)|(0x00ff&(this))))
+
+static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl)
+{
+       if (netif_msg_link(dev))
+               devdbg(dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
+                       dev->udev->bus->bus_name, dev->udev->devpath,
+                       ttl, TTL_THIS(ttl), TTL_OTHER(ttl));
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int net1080_reset(struct usbnet *dev)
+{
+       u16             usbctl, status, ttl;
+       u16             *vp = kmalloc(sizeof (u16), GFP_KERNEL);
+       int             retval;
+
+       if (!vp)
+               return -ENOMEM;
+
+       // nc_dump_registers(dev);
+
+       if ((retval = nc_register_read(dev, REG_STATUS, vp)) < 0) {
+               dbg("can't read %s-%s status: %d",
+                       dev->udev->bus->bus_name, dev->udev->devpath, retval);
+               goto done;
+       }
+       status = *vp;
+       nc_dump_status(dev, status);
+
+       if ((retval = nc_register_read(dev, REG_USBCTL, vp)) < 0) {
+               dbg("can't read USBCTL, %d", retval);
+               goto done;
+       }
+       usbctl = *vp;
+       nc_dump_usbctl(dev, usbctl);
+
+       nc_register_write(dev, REG_USBCTL,
+                       USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
+
+       if ((retval = nc_register_read(dev, REG_TTL, vp)) < 0) {
+               dbg("can't read TTL, %d", retval);
+               goto done;
+       }
+       ttl = *vp;
+       // nc_dump_ttl(dev, ttl);
+
+       nc_register_write(dev, REG_TTL,
+                       MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) );
+       dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
+
+       if (netif_msg_link(dev))
+               devinfo(dev, "port %c, peer %sconnected",
+                       (status & STATUS_PORT_A) ? 'A' : 'B',
+                       (status & STATUS_CONN_OTHER) ? "" : "dis"
+                       );
+       retval = 0;
+
+done:
+       kfree(vp);
+       return retval;
+}
+
+static int net1080_check_connect(struct usbnet *dev)
+{
+       int                     retval;
+       u16                     status;
+       u16                     *vp = kmalloc(sizeof (u16), GFP_KERNEL);
+
+       if (!vp)
+               return -ENOMEM;
+       retval = nc_register_read(dev, REG_STATUS, vp);
+       status = *vp;
+       kfree(vp);
+       if (retval != 0) {
+               dbg("%s net1080_check_conn read - %d", dev->net->name, retval);
+               return retval;
+       }
+       if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
+               return -ENOLINK;
+       return 0;
+}
+
+static void nc_flush_complete(struct urb *urb, struct pt_regs *regs)
+{
+       kfree(urb->context);
+       usb_free_urb(urb);
+}
+
+static void nc_ensure_sync(struct usbnet *dev)
+{
+       dev->frame_errors++;
+       if (dev->frame_errors > 5) {
+               struct urb              *urb;
+               struct usb_ctrlrequest  *req;
+               int                     status;
+
+               /* Send a flush */
+               urb = usb_alloc_urb(0, SLAB_ATOMIC);
+               if (!urb)
+                       return;
+
+               req = kmalloc(sizeof *req, GFP_ATOMIC);
+               if (!req) {
+                       usb_free_urb(urb);
+                       return;
+               }
+
+               req->bRequestType = USB_DIR_OUT
+                       | USB_TYPE_VENDOR
+                       | USB_RECIP_DEVICE;
+               req->bRequest = REQUEST_REGISTER;
+               req->wValue = cpu_to_le16(USBCTL_FLUSH_THIS
+                               | USBCTL_FLUSH_OTHER);
+               req->wIndex = cpu_to_le16(REG_USBCTL);
+               req->wLength = cpu_to_le16(0);
+
+               /* queue an async control request, we don't need
+                * to do anything when it finishes except clean up.
+                */
+               usb_fill_control_urb(urb, dev->udev,
+                       usb_sndctrlpipe(dev->udev, 0),
+                       (unsigned char *) req,
+                       NULL, 0,
+                       nc_flush_complete, req);
+               status = usb_submit_urb(urb, GFP_ATOMIC);
+               if (status) {
+                       kfree(req);
+                       usb_free_urb(urb);
+                       return;
+               }
+
+               if (netif_msg_rx_err(dev))
+                       devdbg(dev, "flush net1080; too many framing errors");
+               dev->frame_errors = 0;
+       }
+}
+
+static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct nc_header        *header;
+       struct nc_trailer       *trailer;
+       u16                     hdr_len, packet_len;
+
+       if (!(skb->len & 0x01)) {
+#ifdef DEBUG
+               struct net_device       *net = dev->net;
+               dbg("rx framesize %d range %d..%d mtu %d", skb->len,
+                       net->hard_header_len, dev->hard_mtu, net->mtu);
+#endif
+               dev->stats.rx_frame_errors++;
+               nc_ensure_sync(dev);
+               return 0;
+       }
+
+       header = (struct nc_header *) skb->data;
+       hdr_len = le16_to_cpup(&header->hdr_len);
+       packet_len = le16_to_cpup(&header->packet_len);
+       if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) {
+               dev->stats.rx_frame_errors++;
+               dbg("packet too big, %d", packet_len);
+               nc_ensure_sync(dev);
+               return 0;
+       } else if (hdr_len < MIN_HEADER) {
+               dev->stats.rx_frame_errors++;
+               dbg("header too short, %d", hdr_len);
+               nc_ensure_sync(dev);
+               return 0;
+       } else if (hdr_len > MIN_HEADER) {
+               // out of band data for us?
+               dbg("header OOB, %d bytes", hdr_len - MIN_HEADER);
+               nc_ensure_sync(dev);
+               // switch (vendor/product ids) { ... }
+       }
+       skb_pull(skb, hdr_len);
+
+       trailer = (struct nc_trailer *)
+               (skb->data + skb->len - sizeof *trailer);
+       skb_trim(skb, skb->len - sizeof *trailer);
+
+       if ((packet_len & 0x01) == 0) {
+               if (skb->data [packet_len] != PAD_BYTE) {
+                       dev->stats.rx_frame_errors++;
+                       dbg("bad pad");
+                       return 0;
+               }
+               skb_trim(skb, skb->len - 1);
+       }
+       if (skb->len != packet_len) {
+               dev->stats.rx_frame_errors++;
+               dbg("bad packet len %d (expected %d)",
+                       skb->len, packet_len);
+               nc_ensure_sync(dev);
+               return 0;
+       }
+       if (header->packet_id != get_unaligned(&trailer->packet_id)) {
+               dev->stats.rx_fifo_errors++;
+               dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
+                       le16_to_cpu(header->packet_id),
+                       le16_to_cpu(trailer->packet_id));
+               return 0;
+       }
+#if 0
+       devdbg(dev, "frame <rx h %d p %d id %d", header->hdr_len,
+               header->packet_len, header->packet_id);
+#endif
+       dev->frame_errors = 0;
+       return 1;
+}
+
+static struct sk_buff *
+net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+       int                     padlen;
+       struct sk_buff          *skb2;
+       struct nc_header        *header = NULL;
+       struct nc_trailer       *trailer = NULL;
+       int                     len = skb->len;
+
+       padlen = ((len + sizeof (struct nc_header)
+                       + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
+       if (!skb_cloned(skb)) {
+               int     headroom = skb_headroom(skb);
+               int     tailroom = skb_tailroom(skb);
+
+               if ((padlen + sizeof (struct nc_trailer)) <= tailroom
+                           && sizeof (struct nc_header) <= headroom)
+                       /* There's enough head and tail room */
+                       goto encapsulate;
+
+               if ((sizeof (struct nc_header) + padlen
+                                       + sizeof (struct nc_trailer)) <
+                               (headroom + tailroom)) {
+                       /* There's enough total room, so just readjust */
+                       skb->data = memmove(skb->head
+                                               + sizeof (struct nc_header),
+                                           skb->data, skb->len);
+                       skb->tail = skb->data + len;
+                       goto encapsulate;
+               }
+       }
+
+       /* Create a new skb to use with the correct size */
+       skb2 = skb_copy_expand(skb,
+                               sizeof (struct nc_header),
+                               sizeof (struct nc_trailer) + padlen,
+                               flags);
+       dev_kfree_skb_any(skb);
+       if (!skb2)
+               return skb2;
+       skb = skb2;
+
+encapsulate:
+       /* header first */
+       header = (struct nc_header *) skb_push(skb, sizeof *header);
+       header->hdr_len = cpu_to_le16(sizeof (*header));
+       header->packet_len = cpu_to_le16(len);
+       header->packet_id = cpu_to_le16((u16)dev->xid++);
+
+       /* maybe pad; then trailer */
+       if (!((skb->len + sizeof *trailer) & 0x01))
+               *skb_put(skb, 1) = PAD_BYTE;
+       trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer);
+       put_unaligned(header->packet_id, &trailer->packet_id);
+#if 0
+       devdbg(dev, "frame >tx h %d p %d id %d",
+               header->hdr_len, header->packet_len,
+               header->packet_id);
+#endif
+       return skb;
+}
+
+static int net1080_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       unsigned        extra = sizeof (struct nc_header)
+                               + 1
+                               + sizeof (struct nc_trailer);
+
+       dev->net->hard_header_len += extra;
+       dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
+       dev->hard_mtu = NC_MAX_PACKET;
+       return usbnet_get_endpoints (dev, intf);
+}
+
+static const struct driver_info        net1080_info = {
+       .description =  "NetChip TurboCONNECT",
+       .flags =        FLAG_FRAMING_NC,
+       .bind =         net1080_bind,
+       .reset =        net1080_reset,
+       .check_connect = net1080_check_connect,
+       .rx_fixup =     net1080_rx_fixup,
+       .tx_fixup =     net1080_tx_fixup,
+};
+
+static const struct usb_device_id      products [] = {
+{
+       USB_DEVICE(0x0525, 0x1080),     // NetChip ref design
+       .driver_info =  (unsigned long) &net1080_info,
+}, {
+       USB_DEVICE(0x06D0, 0x0622),     // Laplink Gold
+       .driver_info =  (unsigned long) &net1080_info,
+},
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver net1080_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "net1080",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+static int __init net1080_init(void)
+{
+       return usb_register(&net1080_driver);
+}
+module_init(net1080_init);
+
+static void __exit net1080_exit(void)
+{
+       usb_deregister(&net1080_driver);
+}
+module_exit(net1080_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links");
+MODULE_LICENSE("GPL");
index fcd6d3ccef4460d48c3d534876ae68bdb6ac88cf..7484d34780fcb7e0dced0bdcb24556b776d6e2fa 100644 (file)
@@ -825,7 +825,6 @@ static void pegasus_tx_timeout(struct net_device *net)
        pegasus_t *pegasus = netdev_priv(net);
        if (netif_msg_timer(pegasus))
                printk(KERN_WARNING "%s: tx timeout\n", net->name);
-       pegasus->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
        usb_unlink_urb(pegasus->tx_urb);
        pegasus->stats.tx_errors++;
 }
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
new file mode 100644 (file)
index 0000000..74c2b35
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * PL-2301/2302 USB host-to-host link cables
+ * Copyright (C) 2000-2005 by David Brownell
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+
+/*
+ * Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
+ *
+ * The protocol and handshaking used here should be bug-compatible
+ * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
+ *
+ * HEADS UP:  this handshaking isn't all that robust.  This driver
+ * gets confused easily if you unplug one end of the cable then
+ * try to connect it again; you'll need to restart both ends. The
+ * "naplink" software (used by some PlayStation/2 deveopers) does
+ * the handshaking much better!   Also, sometimes this hardware
+ * seems to get wedged under load.  Prolific docs are weak, and
+ * don't identify differences between PL2301 and PL2302, much less
+ * anything to explain the different PL2302 versions observed.
+ */
+
+/*
+ * Bits 0-4 can be used for software handshaking; they're set from
+ * one end, cleared from the other, "read" with the interrupt byte.
+ */
+#define        PL_S_EN         (1<<7)          /* (feature only) suspend enable */
+/* reserved bit -- rx ready (6) ? */
+#define        PL_TX_READY     (1<<5)          /* (interrupt only) transmit ready */
+#define        PL_RESET_OUT    (1<<4)          /* reset output pipe */
+#define        PL_RESET_IN     (1<<3)          /* reset input pipe */
+#define        PL_TX_C         (1<<2)          /* transmission complete */
+#define        PL_TX_REQ       (1<<1)          /* transmission received */
+#define        PL_PEER_E       (1<<0)          /* peer exists */
+
+static inline int
+pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
+{
+       return usb_control_msg(dev->udev,
+               usb_rcvctrlpipe(dev->udev, 0),
+               req,
+               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               val, index,
+               NULL, 0,
+               USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int
+pl_clear_QuickLink_features(struct usbnet *dev, int val)
+{
+       return pl_vendor_req(dev, 1, (u8) val, 0);
+}
+
+static inline int
+pl_set_QuickLink_features(struct usbnet *dev, int val)
+{
+       return pl_vendor_req(dev, 3, (u8) val, 0);
+}
+
+static int pl_reset(struct usbnet *dev)
+{
+       /* some units seem to need this reset, others reject it utterly.
+        * FIXME be more like "naplink" or windows drivers.
+        */
+       (void) pl_set_QuickLink_features(dev,
+               PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
+       return 0;
+}
+
+static const struct driver_info        prolific_info = {
+       .description =  "Prolific PL-2301/PL-2302",
+       .flags =        FLAG_NO_SETINT,
+               /* some PL-2302 versions seem to fail usb_set_interface() */
+       .reset =        pl_reset,
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Proilific's name won't normally be on the cables, and
+ * may not be on the device.
+ */
+
+static const struct usb_device_id      products [] = {
+
+{
+       USB_DEVICE(0x067b, 0x0000),     // PL-2301
+       .driver_info =  (unsigned long) &prolific_info,
+}, {
+       USB_DEVICE(0x067b, 0x0001),     // PL-2302
+       .driver_info =  (unsigned long) &prolific_info,
+},
+
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver plusb_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "plusb",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+static int __init plusb_init(void)
+{
+       return usb_register(&plusb_driver);
+}
+module_init(plusb_init);
+
+static void __exit plusb_exit(void)
+{
+       usb_deregister(&plusb_driver);
+}
+module_exit(plusb_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("Prolific PL-2301/2302 USB Host to Host Link Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
new file mode 100644 (file)
index 0000000..2ed2e5f
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ * Host Side support for RNDIS Networking Links
+ * Copyright (C) 2005 by David Brownell
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb_cdc.h>
+
+#include "usbnet.h"
+
+
+/*
+ * RNDIS is NDIS remoted over USB.  It's a MSFT variant of CDC ACM ... of
+ * course ACM was intended for modems, not Ethernet links!  USB's standard
+ * for Ethernet links is "CDC Ethernet", which is significantly simpler.
+ */
+
+/*
+ * CONTROL uses CDC "encapsulated commands" with funky notifications.
+ *  - control-out:  SEND_ENCAPSULATED
+ *  - interrupt-in:  RESPONSE_AVAILABLE
+ *  - control-in:  GET_ENCAPSULATED
+ *
+ * We'll try to ignore the RESPONSE_AVAILABLE notifications.
+ */
+struct rndis_msg_hdr {
+       __le32  msg_type;                       /* RNDIS_MSG_* */
+       __le32  msg_len;
+       // followed by data that varies between messages
+       __le32  request_id;
+       __le32  status;
+       // ... and more
+} __attribute__ ((packed));
+
+/* RNDIS defines this (absurdly huge) control timeout */
+#define        RNDIS_CONTROL_TIMEOUT_MS        (10 * 1000)
+
+
+#define ccpu2 __constant_cpu_to_le32
+
+#define RNDIS_MSG_COMPLETION   ccpu2(0x80000000)
+
+/* codes for "msg_type" field of rndis messages;
+ * only the data channel uses packet messages (maybe batched);
+ * everything else goes on the control channel.
+ */
+#define RNDIS_MSG_PACKET       ccpu2(0x00000001)       /* 1-N packets */
+#define RNDIS_MSG_INIT         ccpu2(0x00000002)
+#define RNDIS_MSG_INIT_C       (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_HALT         ccpu2(0x00000003)
+#define RNDIS_MSG_QUERY                ccpu2(0x00000004)
+#define RNDIS_MSG_QUERY_C      (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_SET          ccpu2(0x00000005)
+#define RNDIS_MSG_SET_C        (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_RESET                ccpu2(0x00000006)
+#define RNDIS_MSG_RESET_C      (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_INDICATE     ccpu2(0x00000007)
+#define RNDIS_MSG_KEEPALIVE    ccpu2(0x00000008)
+#define RNDIS_MSG_KEEPALIVE_C  (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
+
+/* codes for "status" field of completion messages */
+#define        RNDIS_STATUS_SUCCESS            ccpu2(0x00000000)
+#define        RNDIS_STATUS_FAILURE            ccpu2(0xc0000001)
+#define        RNDIS_STATUS_INVALID_DATA       ccpu2(0xc0010015)
+#define        RNDIS_STATUS_NOT_SUPPORTED      ccpu2(0xc00000bb)
+#define        RNDIS_STATUS_MEDIA_CONNECT      ccpu2(0x4001000b)
+#define        RNDIS_STATUS_MEDIA_DISCONNECT   ccpu2(0x4001000c)
+
+
+struct rndis_data_hdr {
+       __le32  msg_type;               /* RNDIS_MSG_PACKET */
+       __le32  msg_len;                // rndis_data_hdr + data_len + pad
+       __le32  data_offset;            // 36 -- right after header
+       __le32  data_len;               // ... real packet size
+
+       __le32  oob_data_offset;        // zero
+       __le32  oob_data_len;           // zero
+       __le32  num_oob;                // zero
+       __le32  packet_data_offset;     // zero
+
+       __le32  packet_data_len;        // zero
+       __le32  vc_handle;              // zero
+       __le32  reserved;               // zero
+} __attribute__ ((packed));
+
+struct rndis_init {            /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_INIT */
+       __le32  msg_len;                        // 24
+       __le32  request_id;
+       __le32  major_version;                  // of rndis (1.0)
+       __le32  minor_version;
+       __le32  max_transfer_size;
+} __attribute__ ((packed));
+
+struct rndis_init_c {          /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_INIT_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+       __le32  major_version;                  // of rndis (1.0)
+       __le32  minor_version;
+       __le32  device_flags;
+       __le32  medium;                         // zero == 802.3
+       __le32  max_packets_per_message;
+       __le32  max_transfer_size;
+       __le32  packet_alignment;               // max 7; (1<<n) bytes
+       __le32  af_list_offset;                 // zero
+       __le32  af_list_size;                   // zero
+} __attribute__ ((packed));
+
+struct rndis_halt {            /* OUT (no reply) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_HALT */
+       __le32  msg_len;
+       __le32  request_id;
+} __attribute__ ((packed));
+
+struct rndis_query {           /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_QUERY */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  oid;
+       __le32  len;
+       __le32  offset;
+/*?*/  __le32  handle;                         // zero
+} __attribute__ ((packed));
+
+struct rndis_query_c {         /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_QUERY_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+       __le32  len;
+       __le32  offset;
+} __attribute__ ((packed));
+
+struct rndis_set {             /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_SET */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  oid;
+       __le32  len;
+       __le32  offset;
+/*?*/  __le32  handle;                         // zero
+} __attribute__ ((packed));
+
+struct rndis_set_c {           /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_SET_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+} __attribute__ ((packed));
+
+struct rndis_reset {           /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_RESET */
+       __le32  msg_len;
+       __le32  reserved;
+} __attribute__ ((packed));
+
+struct rndis_reset_c {         /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_RESET_C */
+       __le32  msg_len;
+       __le32  status;
+       __le32  addressing_lost;
+} __attribute__ ((packed));
+
+struct rndis_indicate {                /* IN (unrequested) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_INDICATE */
+       __le32  msg_len;
+       __le32  status;
+       __le32  length;
+       __le32  offset;
+/**/   __le32  diag_status;
+       __le32  error_offset;
+/**/   __le32  message;
+} __attribute__ ((packed));
+
+struct rndis_keepalive {       /* OUT (optionally IN) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_KEEPALIVE */
+       __le32  msg_len;
+       __le32  request_id;
+} __attribute__ ((packed));
+
+struct rndis_keepalive_c {     /* IN (optionally OUT) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_KEEPALIVE_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+} __attribute__ ((packed));
+
+/* NOTE:  about 30 OIDs are "mandatory" for peripherals to support ... and
+ * there are gobs more that may optionally be supported.  We'll avoid as much
+ * of that mess as possible.
+ */
+#define OID_802_3_PERMANENT_ADDRESS    ccpu2(0x01010101)
+#define OID_GEN_CURRENT_PACKET_FILTER  ccpu2(0x0001010e)
+
+/*
+ * RNDIS notifications from device: command completion; "reverse"
+ * keepalives; etc
+ */
+static void rndis_status(struct usbnet *dev, struct urb *urb)
+{
+       devdbg(dev, "rndis status urb, len %d stat %d",
+               urb->actual_length, urb->status);
+       // FIXME for keepalives, respond immediately (asynchronously)
+       // if not an RNDIS status, do like cdc_status(dev,urb) does
+}
+
+/*
+ * RPC done RNDIS-style.  Caller guarantees:
+ * - message is properly byteswapped
+ * - there's no other request pending
+ * - buf can hold up to 1KB response (required by RNDIS spec)
+ * On return, the first few entries are already byteswapped.
+ *
+ * Call context is likely probe(), before interface name is known,
+ * which is why we won't try to use it in the diagnostics.
+ */
+static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
+{
+       struct cdc_state        *info = (void *) &dev->data;
+       int                     retval;
+       unsigned                count;
+       __le32                  rsp;
+       u32                     xid = 0, msg_len, request_id;
+
+       /* REVISIT when this gets called from contexts other than probe() or
+        * disconnect(): either serialize, or dispatch responses on xid
+        */
+
+       /* Issue the request; don't bother byteswapping our xid */
+       if (likely(buf->msg_type != RNDIS_MSG_HALT
+                       && buf->msg_type != RNDIS_MSG_RESET)) {
+               xid = dev->xid++;
+               if (!xid)
+                       xid = dev->xid++;
+               buf->request_id = (__force __le32) xid;
+       }
+       retval = usb_control_msg(dev->udev,
+               usb_sndctrlpipe(dev->udev, 0),
+               USB_CDC_SEND_ENCAPSULATED_COMMAND,
+               USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+               0, info->u->bMasterInterface0,
+               buf, le32_to_cpu(buf->msg_len),
+               RNDIS_CONTROL_TIMEOUT_MS);
+       if (unlikely(retval < 0 || xid == 0))
+               return retval;
+
+       // FIXME Seems like some devices discard responses when
+       // we time out and cancel our "get response" requests...
+       // so, this is fragile.  Probably need to poll for status.
+
+       /* ignore status endpoint, just poll the control channel;
+        * the request probably completed immediately
+        */
+       rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
+       for (count = 0; count < 10; count++) {
+               memset(buf, 0, 1024);
+               retval = usb_control_msg(dev->udev,
+                       usb_rcvctrlpipe(dev->udev, 0),
+                       USB_CDC_GET_ENCAPSULATED_RESPONSE,
+                       USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       0, info->u->bMasterInterface0,
+                       buf, 1024,
+                       RNDIS_CONTROL_TIMEOUT_MS);
+               if (likely(retval >= 8)) {
+                       msg_len = le32_to_cpu(buf->msg_len);
+                       request_id = (__force u32) buf->request_id;
+                       if (likely(buf->msg_type == rsp)) {
+                               if (likely(request_id == xid)) {
+                                       if (unlikely(rsp == RNDIS_MSG_RESET_C))
+                                               return 0;
+                                       if (likely(RNDIS_STATUS_SUCCESS
+                                                       == buf->status))
+                                               return 0;
+                                       dev_dbg(&info->control->dev,
+                                               "rndis reply status %08x\n",
+                                               le32_to_cpu(buf->status));
+                                       return -EL3RST;
+                               }
+                               dev_dbg(&info->control->dev,
+                                       "rndis reply id %d expected %d\n",
+                                       request_id, xid);
+                               /* then likely retry */
+                       } else switch (buf->msg_type) {
+                       case RNDIS_MSG_INDICATE: {      /* fault */
+                               // struct rndis_indicate *msg = (void *)buf;
+                               dev_info(&info->control->dev,
+                                        "rndis fault indication\n");
+                               }
+                               break;
+                       case RNDIS_MSG_KEEPALIVE: {     /* ping */
+                               struct rndis_keepalive_c *msg = (void *)buf;
+
+                               msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
+                               msg->msg_len = ccpu2(sizeof *msg);
+                               msg->status = RNDIS_STATUS_SUCCESS;
+                               retval = usb_control_msg(dev->udev,
+                                       usb_sndctrlpipe(dev->udev, 0),
+                                       USB_CDC_SEND_ENCAPSULATED_COMMAND,
+                                       USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                                       0, info->u->bMasterInterface0,
+                                       msg, sizeof *msg,
+                                       RNDIS_CONTROL_TIMEOUT_MS);
+                               if (unlikely(retval < 0))
+                                       dev_dbg(&info->control->dev,
+                                               "rndis keepalive err %d\n",
+                                               retval);
+                               }
+                               break;
+                       default:
+                               dev_dbg(&info->control->dev,
+                                       "unexpected rndis msg %08x len %d\n",
+                                       le32_to_cpu(buf->msg_type), msg_len);
+                       }
+               } else {
+                       /* device probably issued a protocol stall; ignore */
+                       dev_dbg(&info->control->dev,
+                               "rndis response error, code %d\n", retval);
+               }
+               msleep(2);
+       }
+       dev_dbg(&info->control->dev, "rndis response timeout\n");
+       return -ETIMEDOUT;
+}
+
+static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int                     retval;
+       struct net_device       *net = dev->net;
+       union {
+               void                    *buf;
+               struct rndis_msg_hdr    *header;
+               struct rndis_init       *init;
+               struct rndis_init_c     *init_c;
+               struct rndis_query      *get;
+               struct rndis_query_c    *get_c;
+               struct rndis_set        *set;
+               struct rndis_set_c      *set_c;
+       } u;
+       u32                     tmp;
+
+       /* we can't rely on i/o from stack working, or stack allocation */
+       u.buf = kmalloc(1024, GFP_KERNEL);
+       if (!u.buf)
+               return -ENOMEM;
+       retval = usbnet_generic_cdc_bind(dev, intf);
+       if (retval < 0)
+               goto done;
+
+       net->hard_header_len += sizeof (struct rndis_data_hdr);
+
+       /* initialize; max transfer is 16KB at full speed */
+       u.init->msg_type = RNDIS_MSG_INIT;
+       u.init->msg_len = ccpu2(sizeof *u.init);
+       u.init->major_version = ccpu2(1);
+       u.init->minor_version = ccpu2(0);
+       u.init->max_transfer_size = ccpu2(net->mtu + net->hard_header_len);
+
+       retval = rndis_command(dev, u.header);
+       if (unlikely(retval < 0)) {
+               /* it might not even be an RNDIS device!! */
+               dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
+fail:
+               usb_driver_release_interface(driver_of(intf),
+                       ((struct cdc_state *)&(dev->data))->data);
+               goto done;
+       }
+       dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size);
+       /* REVISIT:  peripheral "alignment" request is ignored ... */
+       dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu,
+               1 << le32_to_cpu(u.init_c->packet_alignment));
+
+       /* get designated host ethernet address */
+       memset(u.get, 0, sizeof *u.get);
+       u.get->msg_type = RNDIS_MSG_QUERY;
+       u.get->msg_len = ccpu2(sizeof *u.get);
+       u.get->oid = OID_802_3_PERMANENT_ADDRESS;
+
+       retval = rndis_command(dev, u.header);
+       if (unlikely(retval < 0)) {
+               dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
+               goto fail;
+       }
+       tmp = le32_to_cpu(u.get_c->offset);
+       if (unlikely((tmp + 8) > (1024 - ETH_ALEN)
+                       || u.get_c->len != ccpu2(ETH_ALEN))) {
+               dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n",
+                       tmp, le32_to_cpu(u.get_c->len));
+               retval = -EDOM;
+               goto fail;
+       }
+       memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN);
+
+       /* set a nonzero filter to enable data transfers */
+       memset(u.set, 0, sizeof *u.set);
+       u.set->msg_type = RNDIS_MSG_SET;
+       u.set->msg_len = ccpu2(4 + sizeof *u.set);
+       u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
+       u.set->len = ccpu2(4);
+       u.set->offset = ccpu2((sizeof *u.set) - 8);
+       *(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
+
+       retval = rndis_command(dev, u.header);
+       if (unlikely(retval < 0)) {
+               dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
+               goto fail;
+       }
+
+       retval = 0;
+done:
+       kfree(u.buf);
+       return retval;
+}
+
+static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct rndis_halt       *halt;
+
+       /* try to clear any rndis state/activity (no i/o from stack!) */
+       halt = kcalloc(1, sizeof *halt, SLAB_KERNEL);
+       if (halt) {
+               halt->msg_type = RNDIS_MSG_HALT;
+               halt->msg_len = ccpu2(sizeof *halt);
+               (void) rndis_command(dev, (void *)halt);
+               kfree(halt);
+       }
+
+       return usbnet_cdc_unbind(dev, intf);
+}
+
+/*
+ * DATA -- host must not write zlps
+ */
+static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       /* peripheral may have batched packets to us... */
+       while (likely(skb->len)) {
+               struct rndis_data_hdr   *hdr = (void *)skb->data;
+               struct sk_buff          *skb2;
+               u32                     msg_len, data_offset, data_len;
+
+               msg_len = le32_to_cpu(hdr->msg_len);
+               data_offset = le32_to_cpu(hdr->data_offset);
+               data_len = le32_to_cpu(hdr->data_len);
+
+               /* don't choke if we see oob, per-packet data, etc */
+               if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET
+                               || skb->len < msg_len
+                               || (data_offset + data_len + 8) > msg_len)) {
+                       dev->stats.rx_frame_errors++;
+                       devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
+                               le32_to_cpu(hdr->msg_type),
+                               msg_len, data_offset, data_len, skb->len);
+                       return 0;
+               }
+               skb_pull(skb, 8 + data_offset);
+
+               /* at most one packet left? */
+               if (likely((data_len - skb->len) <= sizeof *hdr)) {
+                       skb_trim(skb, data_len);
+                       break;
+               }
+
+               /* try to return all the packets in the batch */
+               skb2 = skb_clone(skb, GFP_ATOMIC);
+               if (unlikely(!skb2))
+                       break;
+               skb_pull(skb, msg_len - sizeof *hdr);
+               skb_trim(skb2, data_len);
+               usbnet_skb_return(dev, skb2);
+       }
+
+       /* caller will usbnet_skb_return the remaining packet */
+       return 1;
+}
+
+static struct sk_buff *
+rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+       struct rndis_data_hdr   *hdr;
+       struct sk_buff          *skb2;
+       unsigned                len = skb->len;
+
+       if (likely(!skb_cloned(skb))) {
+               int     room = skb_headroom(skb);
+
+               /* enough head room as-is? */
+               if (unlikely((sizeof *hdr) <= room))
+                       goto fill;
+
+               /* enough room, but needs to be readjusted? */
+               room += skb_tailroom(skb);
+               if (likely((sizeof *hdr) <= room)) {
+                       skb->data = memmove(skb->head + sizeof *hdr,
+                                           skb->data, len);
+                       skb->tail = skb->data + len;
+                       goto fill;
+               }
+       }
+
+       /* create a new skb, with the correct size (and tailpad) */
+       skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
+       dev_kfree_skb_any(skb);
+       if (unlikely(!skb2))
+               return skb2;
+       skb = skb2;
+
+       /* fill out the RNDIS header.  we won't bother trying to batch
+        * packets; Linux minimizes wasted bandwidth through tx queues.
+        */
+fill:
+       hdr = (void *) __skb_push(skb, sizeof *hdr);
+       memset(hdr, 0, sizeof *hdr);
+       hdr->msg_type = RNDIS_MSG_PACKET;
+       hdr->msg_len = cpu_to_le32(skb->len);
+       hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
+       hdr->data_len = cpu_to_le32(len);
+
+       /* FIXME make the last packet always be short ... */
+       return skb;
+}
+
+
+static const struct driver_info        rndis_info = {
+       .description =  "RNDIS device",
+       .flags =        FLAG_ETHER | FLAG_FRAMING_RN,
+       .bind =         rndis_bind,
+       .unbind =       rndis_unbind,
+       .status =       rndis_status,
+       .rx_fixup =     rndis_rx_fixup,
+       .tx_fixup =     rndis_tx_fixup,
+};
+
+#undef ccpu2
+
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id      products [] = {
+{
+       /* RNDIS is MSFT's un-official variant of CDC ACM */
+       USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+       .driver_info = (unsigned long) &rndis_info,
+},
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver rndis_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "rndis_host",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+static int __init rndis_init(void)
+{
+       return usb_register(&rndis_driver);
+}
+module_init(rndis_init);
+
+static void __exit rndis_exit(void)
+{
+       usb_deregister(&rndis_driver);
+}
+module_exit(rndis_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("USB Host side RNDIS driver");
+MODULE_LICENSE("GPL");
index 59ab40ebb394b4e72fd56ff73eeed8f7b04bc61f..c3d4e3589e30a1a63063aacf5adc6bb0336a4a47 100644 (file)
@@ -653,7 +653,6 @@ static void rtl8150_tx_timeout(struct net_device *netdev)
 {
        rtl8150_t *dev = netdev_priv(netdev);
        warn("%s: Tx timeout.", netdev->name);
-       dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
        usb_unlink_urb(dev->tx_urb);
        dev->stats.tx_errors++;
 }
index a2f67245f6da37adac5a5bb93e68aea202c3aafb..6c460918d54f53a81bb6b6c0cd5fd163796c66a1 100644 (file)
@@ -1,10 +1,7 @@
 /*
- * USB Networking Links
- * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
- * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
+ * USB Network driver infrastructure
+ * Copyright (C) 2000-2005 by David Brownell
  * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
- * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
- * Copyright (c) 2002-2003 TiVo Inc.
  *
  * 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
 
 /*
  * This is a generic "USB networking" framework that works with several
- * kinds of full and high speed networking devices:
- *
- *   + USB host-to-host "network cables", used for IP-over-USB links.
- *     These are often used for Laplink style connectivity products.
- *     - AnchorChip 2720
- *     - Belkin, eTEK (interops with Win32 drivers)
- *     - GeneSys GL620USB-A
- *     - NetChip 1080 (interoperates with NetChip Win32 drivers)
- *     - Prolific PL-2301/2302 (replaces "plusb" driver)
- *     - KC Technology KC2190
- *
- *   + Smart USB devices can support such links directly, using Internet
- *     standard protocols instead of proprietary host-to-device links.
- *     - Linux PDAs like iPaq, Yopy, and Zaurus
- *     - The BLOB boot loader (for diskless booting)
- *     - Linux "gadgets", perhaps using PXA-2xx or Net2280 controllers
- *     - Devices using EPSON's sample USB firmware
- *     - CDC-Ethernet class devices, such as many cable modems
- *
- *   + Adapters to networks such as Ethernet.
- *     - AX8817X based USB 2.0 products
- *
- * Links to these devices can be bridged using Linux Ethernet bridging.
- * With minor exceptions, these all use similar USB framing for network
- * traffic, but need different protocols for control traffic.
- *
- * USB devices can implement their side of this protocol at the cost
- * of two bulk endpoints; it's not restricted to "cable" applications.
- * See the SA1110, Zaurus, or EPSON device/client support in this driver;
- * slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) or
- * "g_ether" (in the Linux "gadget" framework) implement that behavior
- * within devices.
- *
- *
- * CHANGELOG:
- *
- * 13-sep-2000 experimental, new
- * 10-oct-2000 usb_device_id table created. 
- * 28-oct-2000 misc fixes; mostly, discard more TTL-mangled rx packets.
- * 01-nov-2000 usb_device_id table and probing api update by
- *             Adam J. Richter <adam@yggdrasil.com>.
- * 18-dec-2000 (db) tx watchdog, "net1080" renaming to "usbnet", device_info
- *             and prolific support, isolate net1080-specific bits, cleanup.
- *             fix unlink_urbs oops in D3 PM resume code path.
- *
- * 02-feb-2001 (db) fix tx skb sharing, packet length, match_flags, ...
- * 08-feb-2001 stubbed in "linuxdev", maybe the SA-1100 folk can use it;
- *             AnchorChips 2720 support (from spec) for testing;
- *             fix bit-ordering problem with ethernet multicast addr
- * 19-feb-2001  Support for clearing halt conditions. SA1100 UDC support
- *             updates. Oleg Drokin (green@iXcelerator.com)
- * 25-mar-2001 More SA-1100 updates, including workaround for ip problem
- *             expecting cleared skb->cb and framing change to match latest
- *             handhelds.org version (Oleg).  Enable device IDs from the
- *             Win32 Belkin driver; other cleanups (db).
- * 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various
- *             cleanups for problems not yet seen in the field. (db)
- * 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices,
- *             from Ioannis Mavroukakis <i.mavroukakis@btinternet.com>;
- *             rx unlinks somehow weren't async; minor cleanup.
- * 03-nov-2001 Merged GeneSys driver; original code from Jiun-Jie Huang
- *             <huangjj@genesyslogic.com.tw>, updated by Stanislav Brabec
- *             <utx@penguin.cz>.  Made framing options (NetChip/GeneSys)
- *             tie mostly to (sub)driver info.  Workaround some PL-2302
- *             chips that seem to reject SET_INTERFACE requests.
- *
- * 06-apr-2002 Added ethtool support, based on a patch from Brad Hards.
- *             Level of diagnostics is more configurable; they use device
- *             location (usb_device->devpath) instead of address (2.5).
- *             For tx_fixup, memflags can't be NOIO.
- * 07-may-2002 Generalize/cleanup keventd support, handling rx stalls (mostly
- *             for USB 2.0 TTs) and memory shortages (potential) too. (db)
- *             Use "locally assigned" IEEE802 address space. (Brad Hards)
- * 18-oct-2002 Support for Zaurus (Pavel Machek), related cleanup (db).
- * 14-dec-2002 Remove Zaurus-private crc32 code (Pavel); 2.5 oops fix,
- *             cleanups and stubbed PXA-250 support (db), fix for framing
- *             issues on Z, net1080, and gl620a (Toby Milne)
- *
- * 31-mar-2003 Use endpoint descriptors:  high speed support, simpler sa1100
- *             vs pxa25x, and CDC Ethernet.  Throttle down log floods on
- *             disconnect; other cleanups. (db)  Flush net1080 fifos
- *             after several sequential framing errors. (Johannes Erdfelt)
- * 22-aug-2003 AX8817X support (Dave Hollis).
- * 14-jun-2004  Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
- *             (Neil Bortnak)
- * 03-nov-2004 Trivial patch for KC2190 (KC-190) chip. (Jonathan McDowell)
- *
- * 01-feb-2005 AX88772 support (Phil Chang & Dave Hollis)
- *-------------------------------------------------------------------------*/
+ * kinds of full and high speed networking devices:  host-to-host cables,
+ * smart usb peripherals, and actual Ethernet adapters.
+ *
+ * These devices usually differ in terms of control protocols (if they
+ * even have one!) and sometimes they define new framing to wrap or batch
+ * Ethernet packets.  Otherwise, they talk to USB pretty much the same,
+ * so interface (un)binding, endpoint I/O queues, fault handling, and other
+ * issues can usefully be addressed by this framework.
+ */
 
 // #define     DEBUG                   // error path messages, extra info
 // #define     VERBOSE                 // more; success messages
 #   define DEBUG
 #endif
 #include <linux/module.h>
-#include <linux/kmod.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/random.h>
 #include <linux/ethtool.h>
 #include <linux/workqueue.h>
 #include <linux/mii.h>
-#include <asm/uaccess.h>
-#include <asm/unaligned.h>
 #include <linux/usb.h>
-#include <asm/io.h>
-#include <asm/scatterlist.h>
-#include <linux/mm.h>
-#include <linux/dma-mapping.h>
 
-#define DRIVER_VERSION         "03-Nov-2004"
+#include "usbnet.h"
+
+#define DRIVER_VERSION         "22-Aug-2005"
 
 
 /*-------------------------------------------------------------------------*/
  * One maximum size Ethernet packet takes twenty four of them.
  * For high speed, each frame comfortably fits almost 36 max size
  * Ethernet packets (so queues should be bigger).
+ *
+ * REVISIT qlens should be members of 'struct usbnet'; the goal is to
+ * let the USB host controller be busy for 5msec or more before an irq
+ * is required, under load.  Jumbograms change the equation.
  */
 #define        RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
 #define        TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
 
-// packets are always ethernet inside
-// ... except they can be bigger (limit of 64K with NetChip framing)
-#define MIN_PACKET     sizeof(struct ethhdr)
-#define MAX_PACKET     32768
-
 // reawaken network queue this soon after stopping; else watchdog barks
 #define TX_TIMEOUT_JIFFIES     (5*HZ)
 
 // us (it polls at HZ/4 usually) before we report too many false errors.
 #define THROTTLE_JIFFIES       (HZ/8)
 
-// for vendor-specific control operations
-#define        CONTROL_TIMEOUT_MS      500
-
-// between wakeups
-#define UNLINK_TIMEOUT_MS      3
-
-/*-------------------------------------------------------------------------*/
-
-// randomly generated ethernet address
-static u8      node_id [ETH_ALEN];
-
-// state we keep for each device we handle
-struct usbnet {
-       // housekeeping
-       struct usb_device       *udev;
-       struct driver_info      *driver_info;
-       wait_queue_head_t       *wait;
-
-       // i/o info: pipes etc
-       unsigned                in, out;
-       struct usb_host_endpoint *status;
-       unsigned                maxpacket;
-       struct timer_list       delay;
-
-       // protocol/interface state
-       struct net_device       *net;
-       struct net_device_stats stats;
-       int                     msg_enable;
-       unsigned long           data [5];
-
-       struct mii_if_info      mii;
-
-       // various kinds of pending driver work
-       struct sk_buff_head     rxq;
-       struct sk_buff_head     txq;
-       struct sk_buff_head     done;
-       struct urb              *interrupt;
-       struct tasklet_struct   bh;
-
-       struct work_struct      kevent;
-       unsigned long           flags;
-#              define EVENT_TX_HALT    0
-#              define EVENT_RX_HALT    1
-#              define EVENT_RX_MEMORY  2
-#              define EVENT_STS_SPLIT  3
-#              define EVENT_LINK_RESET 4
-};
-
-// device-specific info used by the driver
-struct driver_info {
-       char            *description;
-
-       int             flags;
-/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
-#define FLAG_FRAMING_NC        0x0001          /* guard against device dropouts */ 
-#define FLAG_FRAMING_GL        0x0002          /* genelink batches packets */
-#define FLAG_FRAMING_Z 0x0004          /* zaurus adds a trailer */
-#define FLAG_FRAMING_RN        0x0008          /* RNDIS batches, plus huge header */
-
-#define FLAG_NO_SETINT 0x0010          /* device can't set_interface() */
-#define FLAG_ETHER     0x0020          /* maybe use "eth%d" names */
-
-#define FLAG_FRAMING_AX 0x0040          /* AX88772/178 packets */
-
-       /* init device ... can sleep, or cause probe() failure */
-       int     (*bind)(struct usbnet *, struct usb_interface *);
-
-       /* cleanup device ... can sleep, but can't fail */
-       void    (*unbind)(struct usbnet *, struct usb_interface *);
-
-       /* reset device ... can sleep */
-       int     (*reset)(struct usbnet *);
-
-       /* see if peer is connected ... can sleep */
-       int     (*check_connect)(struct usbnet *);
-
-       /* for status polling */
-       void    (*status)(struct usbnet *, struct urb *);
-
-       /* link reset handling, called from defer_kevent */
-       int     (*link_reset)(struct usbnet *);
-
-       /* fixup rx packet (strip framing) */
-       int     (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
-
-       /* fixup tx packet (add framing) */
-       struct sk_buff  *(*tx_fixup)(struct usbnet *dev,
-                               struct sk_buff *skb, int flags);
-
-       // FIXME -- also an interrupt mechanism
-       // useful for at least PL2301/2302 and GL620USB-A
-       // and CDC use them to report 'is it connected' changes
-
-       /* for new devices, use the descriptor-reading code instead */
-       int             in;             /* rx endpoint */
-       int             out;            /* tx endpoint */
-
-       unsigned long   data;           /* Misc driver specific data */
-};
-
-// we record the state for each of our queued skbs
-enum skb_state {
-       illegal = 0,
-       tx_start, tx_done,
-       rx_start, rx_done, rx_cleanup
-};
-
-struct skb_data {      // skb->cb is one of these
-       struct urb              *urb;
-       struct usbnet           *dev;
-       enum skb_state          state;
-       size_t                  length;
-};
-
-static const char driver_name [] = "usbnet";
-
-/* use ethtool to change the level for any given device */
-static int msg_level = -1;
-module_param (msg_level, int, 0);
-MODULE_PARM_DESC (msg_level, "Override default message level");
-
-
-#ifdef DEBUG
-#define devdbg(usbnet, fmt, arg...) \
-       printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-#else
-#define devdbg(usbnet, fmt, arg...) do {} while(0)
-#endif
-
-#define deverr(usbnet, fmt, arg...) \
-       printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-#define devwarn(usbnet, fmt, arg...) \
-       printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-
-#define devinfo(usbnet, fmt, arg...) \
-       printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
-
-/*-------------------------------------------------------------------------*/
-
-static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
-static u32 usbnet_get_link (struct net_device *);
-static u32 usbnet_get_msglevel (struct net_device *);
-static void usbnet_set_msglevel (struct net_device *, u32);
-static void defer_kevent (struct usbnet *, int);
-
-/* mostly for PDA style devices, which are always connected if present */
-static int always_connected (struct usbnet *dev)
-{
-       return 0;
-}
-
-/* handles CDC Ethernet and many other network "bulk data" interfaces */
-static int
-get_endpoints (struct usbnet *dev, struct usb_interface *intf)
-{
-       int                             tmp;
-       struct usb_host_interface       *alt = NULL;
-       struct usb_host_endpoint        *in = NULL, *out = NULL;
-       struct usb_host_endpoint        *status = NULL;
-
-       for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
-               unsigned        ep;
-
-               in = out = status = NULL;
-               alt = intf->altsetting + tmp;
-
-               /* take the first altsetting with in-bulk + out-bulk;
-                * remember any status endpoint, just in case;
-                * ignore other endpoints and altsetttings.
-                */
-               for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
-                       struct usb_host_endpoint        *e;
-                       int                             intr = 0;
-
-                       e = alt->endpoint + ep;
-                       switch (e->desc.bmAttributes) {
-                       case USB_ENDPOINT_XFER_INT:
-                               if (!(e->desc.bEndpointAddress & USB_DIR_IN))
-                                       continue;
-                               intr = 1;
-                               /* FALLTHROUGH */
-                       case USB_ENDPOINT_XFER_BULK:
-                               break;
-                       default:
-                               continue;
-                       }
-                       if (e->desc.bEndpointAddress & USB_DIR_IN) {
-                               if (!intr && !in)
-                                       in = e;
-                               else if (intr && !status)
-                                       status = e;
-                       } else {
-                               if (!out)
-                                       out = e;
-                       }
-               }
-               if (in && out)
-                       break;
-       }
-       if (!alt || !in || !out)
-               return -EINVAL;
-
-       if (alt->desc.bAlternateSetting != 0
-                       || !(dev->driver_info->flags & FLAG_NO_SETINT)) {
-               tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber,
-                               alt->desc.bAlternateSetting);
-               if (tmp < 0)
-                       return tmp;
-       }
-       
-       dev->in = usb_rcvbulkpipe (dev->udev,
-                       in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-       dev->out = usb_sndbulkpipe (dev->udev,
-                       out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-       dev->status = status;
-       return 0;
-}
-
-static void intr_complete (struct urb *urb, struct pt_regs *regs);
-
-static int init_status (struct usbnet *dev, struct usb_interface *intf)
-{
-       char            *buf = NULL;
-       unsigned        pipe = 0;
-       unsigned        maxp;
-       unsigned        period;
-
-       if (!dev->driver_info->status)
-               return 0;
-
-       pipe = usb_rcvintpipe (dev->udev,
-                       dev->status->desc.bEndpointAddress
-                               & USB_ENDPOINT_NUMBER_MASK);
-       maxp = usb_maxpacket (dev->udev, pipe, 0);
-
-       /* avoid 1 msec chatter:  min 8 msec poll rate */
-       period = max ((int) dev->status->desc.bInterval,
-               (dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
-
-       buf = kmalloc (maxp, SLAB_KERNEL);
-       if (buf) {
-               dev->interrupt = usb_alloc_urb (0, SLAB_KERNEL);
-               if (!dev->interrupt) {
-                       kfree (buf);
-                       return -ENOMEM;
-               } else {
-                       usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
-                               buf, maxp, intr_complete, dev, period);
-                       dev_dbg(&intf->dev,
-                               "status ep%din, %d bytes period %d\n",
-                               usb_pipeendpoint(pipe), maxp, period);
-               }
-       }
-       return  0;
-}
-
-static void skb_return (struct usbnet *dev, struct sk_buff *skb)
-{
-       int     status;
-
-       skb->dev = dev->net;
-       skb->protocol = eth_type_trans (skb, dev->net);
-       dev->stats.rx_packets++;
-       dev->stats.rx_bytes += skb->len;
-
-       if (netif_msg_rx_status (dev))
-               devdbg (dev, "< rx, len %zu, type 0x%x",
-                       skb->len + sizeof (struct ethhdr), skb->protocol);
-       memset (skb->cb, 0, sizeof (struct skb_data));
-       status = netif_rx (skb);
-       if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev))
-               devdbg (dev, "netif_rx status %d", status);
-}
-
-\f
-#ifdef CONFIG_USB_ALI_M5632
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * ALi M5632 driver ... does high speed
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info        ali_m5632_info = {
-       .description =  "ALi M5632",
-};
-
-
-#endif
-
-\f
-#ifdef CONFIG_USB_AN2720
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * AnchorChips 2720 driver ... http://www.cypress.com
- *
- * This doesn't seem to have a way to detect whether the peer is
- * connected, or need any reset handshaking.  It's got pretty big
- * internal buffers (handles most of a frame's worth of data).
- * Chip data sheets don't describe any vendor control messages.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info        an2720_info = {
-       .description =  "AnchorChips/Cypress 2720",
-       // no reset available!
-       // no check_connect available!
-
-       .in = 2, .out = 2,              // direction distinguishes these
-};
-
-#endif /* CONFIG_USB_AN2720 */
-
-\f
-#ifdef CONFIG_USB_AX8817X
-/* ASIX AX8817X based USB 2.0 Ethernet Devices */
-
-#define HAVE_HARDWARE
-#define NEED_MII
-
-#include <linux/crc32.h>
-
-#define AX_CMD_SET_SW_MII              0x06
-#define AX_CMD_READ_MII_REG            0x07
-#define AX_CMD_WRITE_MII_REG           0x08
-#define AX_CMD_SET_HW_MII              0x0a
-#define AX_CMD_READ_EEPROM             0x0b
-#define AX_CMD_WRITE_EEPROM            0x0c
-#define AX_CMD_WRITE_ENABLE            0x0d
-#define AX_CMD_WRITE_DISABLE           0x0e
-#define AX_CMD_WRITE_RX_CTL            0x10
-#define AX_CMD_READ_IPG012             0x11
-#define AX_CMD_WRITE_IPG0              0x12
-#define AX_CMD_WRITE_IPG1              0x13
-#define AX_CMD_WRITE_IPG2              0x14
-#define AX_CMD_WRITE_MULTI_FILTER      0x16
-#define AX_CMD_READ_NODE_ID            0x17
-#define AX_CMD_READ_PHY_ID             0x19
-#define AX_CMD_READ_MEDIUM_STATUS      0x1a
-#define AX_CMD_WRITE_MEDIUM_MODE       0x1b
-#define AX_CMD_READ_MONITOR_MODE       0x1c
-#define AX_CMD_WRITE_MONITOR_MODE      0x1d
-#define AX_CMD_WRITE_GPIOS             0x1f
-#define AX_CMD_SW_RESET                        0x20
-#define AX_CMD_SW_PHY_STATUS           0x21
-#define AX_CMD_SW_PHY_SELECT           0x22
-#define AX88772_CMD_READ_NODE_ID       0x13
-
-#define AX_MONITOR_MODE                        0x01
-#define AX_MONITOR_LINK                        0x02
-#define AX_MONITOR_MAGIC               0x04
-#define AX_MONITOR_HSFS                        0x10
-
-/* AX88172 Medium Status Register values */
-#define AX_MEDIUM_FULL_DUPLEX          0x02
-#define AX_MEDIUM_TX_ABORT_ALLOW       0x04
-#define AX_MEDIUM_FLOW_CONTROL_EN      0x10
-
-#define AX_MCAST_FILTER_SIZE           8
-#define AX_MAX_MCAST                   64
-
-#define AX_EEPROM_LEN                  0x40
-
-#define AX_SWRESET_CLEAR               0x00
-#define AX_SWRESET_RR                  0x01
-#define AX_SWRESET_RT                  0x02
-#define AX_SWRESET_PRTE                        0x04
-#define AX_SWRESET_PRL                 0x08
-#define AX_SWRESET_BZ                  0x10
-#define AX_SWRESET_IPRL                        0x20
-#define AX_SWRESET_IPPD                        0x40
-
-#define AX88772_IPG0_DEFAULT           0x15
-#define AX88772_IPG1_DEFAULT           0x0c
-#define AX88772_IPG2_DEFAULT           0x12
-
-#define AX88772_MEDIUM_FULL_DUPLEX     0x0002
-#define AX88772_MEDIUM_RESERVED                0x0004
-#define AX88772_MEDIUM_RX_FC_ENABLE    0x0010
-#define AX88772_MEDIUM_TX_FC_ENABLE    0x0020
-#define AX88772_MEDIUM_PAUSE_FORMAT    0x0080
-#define AX88772_MEDIUM_RX_ENABLE       0x0100
-#define AX88772_MEDIUM_100MB           0x0200
-#define AX88772_MEDIUM_DEFAULT \
-       (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
-        AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
-        AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
-
-#define AX_EEPROM_MAGIC                        0xdeadbeef
-
-/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
-struct ax8817x_data {
-       u8 multi_filter[AX_MCAST_FILTER_SIZE];
-};
-
-struct ax88172_int_data {
-       u16 res1;
-       u8 link;
-       u16 res2;
-       u8 status;
-       u16 res3;
-} __attribute__ ((packed));
-
-static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
-                           u16 size, void *data)
-{
-       return usb_control_msg(
-               dev->udev,
-               usb_rcvctrlpipe(dev->udev, 0),
-               cmd,
-               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               value,
-               index,
-               data,
-               size,
-               CONTROL_TIMEOUT_MS);
-}
-
-static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
-                            u16 size, void *data)
-{
-       return usb_control_msg(
-               dev->udev,
-               usb_sndctrlpipe(dev->udev, 0),
-               cmd,
-               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               value,
-               index,
-               data,
-               size,
-               CONTROL_TIMEOUT_MS);
-}
-
-static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
-{
-       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
-
-       if (urb->status < 0)
-               printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
-                       urb->status);
-
-       kfree(req);
-       usb_free_urb(urb);
-}
-
-static void ax8817x_status(struct usbnet *dev, struct urb *urb)
-{
-       struct ax88172_int_data *event;
-       int link;
-
-       if (urb->actual_length < 8)
-               return;
-
-       event = urb->transfer_buffer;
-       link = event->link & 0x01;
-       if (netif_carrier_ok(dev->net) != link) {
-               if (link) {
-                       netif_carrier_on(dev->net);
-                       defer_kevent (dev, EVENT_LINK_RESET );
-               } else
-                       netif_carrier_off(dev->net);
-               devdbg(dev, "ax8817x - Link Status is: %d", link);
-       }
-}
-
-static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
-                                   u16 size, void *data)
-{
-       struct usb_ctrlrequest *req;
-       int status;
-       struct urb *urb;
-
-       if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
-               devdbg(dev, "Error allocating URB in write_cmd_async!");
-               return;
-       }
-
-       if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
-               deverr(dev, "Failed to allocate memory for control request");
-               usb_free_urb(urb);
-               return;
-       }
-
-       req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
-       req->bRequest = cmd;
-       req->wValue = cpu_to_le16(value);
-       req->wIndex = cpu_to_le16(index); 
-       req->wLength = cpu_to_le16(size);
-
-       usb_fill_control_urb(urb, dev->udev,
-                            usb_sndctrlpipe(dev->udev, 0),
-                            (void *)req, data, size,
-                            ax8817x_async_cmd_callback, req);
-
-       if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-               deverr(dev, "Error submitting the control message: status=%d", status);
-               kfree(req);
-               usb_free_urb(urb);
-       }
-}
-
-static void ax8817x_set_multicast(struct net_device *net)
-{
-       struct usbnet *dev = netdev_priv(net);
-       struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
-       u8 rx_ctl = 0x8c;
-
-       if (net->flags & IFF_PROMISC) {
-               rx_ctl |= 0x01;
-       } else if (net->flags & IFF_ALLMULTI
-                  || net->mc_count > AX_MAX_MCAST) {
-               rx_ctl |= 0x02;
-       } else if (net->mc_count == 0) {
-               /* just broadcast and directed */
-       } else {
-               /* We use the 20 byte dev->data
-                * for our 8 byte filter buffer
-                * to avoid allocating memory that
-                * is tricky to free later */
-               struct dev_mc_list *mc_list = net->mc_list;
-               u32 crc_bits;
-               int i;
-
-               memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
-
-               /* Build the multicast hash filter. */
-               for (i = 0; i < net->mc_count; i++) {
-                       crc_bits =
-                           ether_crc(ETH_ALEN,
-                                     mc_list->dmi_addr) >> 26;
-                       data->multi_filter[crc_bits >> 3] |=
-                           1 << (crc_bits & 7);
-                       mc_list = mc_list->next;
-               }
-
-               ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
-                                  AX_MCAST_FILTER_SIZE, data->multi_filter);
-
-               rx_ctl |= 0x10;
-       }
-
-       ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
-}
-
-static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
-{
-       struct usbnet *dev = netdev_priv(netdev);
-       u16 res;
-       u8 buf[1];
-
-       ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
-       ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
-       ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
-
-       return res & 0xffff;
-}
-
-static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
-{
-       struct usbnet *dev = netdev_priv(netdev);
-       u16 res = val;
-       u8 buf[1];
-
-       ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
-       ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
-       ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
-}
-
-static int ax88172_link_reset(struct usbnet *dev)
-{
-       u16 lpa;
-       u8 mode;
-
-       mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
-       lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
-       if (lpa & LPA_DUPLEX)
-               mode |= AX_MEDIUM_FULL_DUPLEX;
-       ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
-
-       return 0;
-}
-
-static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
-{
-       struct usbnet *dev = netdev_priv(net);
-       u8 opt;
-
-       if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
-               wolinfo->supported = 0;
-               wolinfo->wolopts = 0;
-               return;
-       }
-       wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
-       wolinfo->wolopts = 0;
-       if (opt & AX_MONITOR_MODE) {
-               if (opt & AX_MONITOR_LINK)
-                       wolinfo->wolopts |= WAKE_PHY;
-               if (opt & AX_MONITOR_MAGIC)
-                       wolinfo->wolopts |= WAKE_MAGIC;
-       }
-}
-
-static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
-{
-       struct usbnet *dev = netdev_priv(net);
-       u8 opt = 0;
-       u8 buf[1];
-
-       if (wolinfo->wolopts & WAKE_PHY)
-               opt |= AX_MONITOR_LINK;
-       if (wolinfo->wolopts & WAKE_MAGIC)
-               opt |= AX_MONITOR_MAGIC;
-       if (opt != 0)
-               opt |= AX_MONITOR_MODE;
-
-       if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
-                             opt, 0, 0, &buf) < 0)
-               return -EINVAL;
-
-       return 0;
-}
-
-static int ax8817x_get_eeprom_len(struct net_device *net)
-{
-       return AX_EEPROM_LEN;
-}
-
-static int ax8817x_get_eeprom(struct net_device *net,
-                             struct ethtool_eeprom *eeprom, u8 *data)
-{
-       struct usbnet *dev = netdev_priv(net);
-       u16 *ebuf = (u16 *)data;
-       int i;
-
-       /* Crude hack to ensure that we don't overwrite memory
-        * if an odd length is supplied
-        */
-       if (eeprom->len % 2)
-               return -EINVAL;
-
-       eeprom->magic = AX_EEPROM_MAGIC;
-
-       /* ax8817x returns 2 bytes from eeprom on read */
-       for (i=0; i < eeprom->len / 2; i++) {
-               if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, 
-                       eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
-                       return -EINVAL;
-       }
-       return 0;
-}
-
-static void ax8817x_get_drvinfo (struct net_device *net,
-                                struct ethtool_drvinfo *info)
-{
-       /* Inherit standard device info */
-       usbnet_get_drvinfo(net, info);
-       info->eedump_len = 0x3e;
-}
-
-static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
-{
-       struct usbnet *dev = netdev_priv(net);
-
-       return mii_ethtool_gset(&dev->mii,cmd);
-}
-
-static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
-{
-       struct usbnet *dev = netdev_priv(net);
-
-       return mii_ethtool_sset(&dev->mii,cmd);
-}
-
-/* We need to override some ethtool_ops so we require our
-   own structure so we don't interfere with other usbnet
-   devices that may be connected at the same time. */
-static struct ethtool_ops ax8817x_ethtool_ops = {
-       .get_drvinfo            = ax8817x_get_drvinfo,
-       .get_link               = ethtool_op_get_link,
-       .get_msglevel           = usbnet_get_msglevel,
-       .set_msglevel           = usbnet_set_msglevel,
-       .get_wol                = ax8817x_get_wol,
-       .set_wol                = ax8817x_set_wol,
-       .get_eeprom_len         = ax8817x_get_eeprom_len,
-       .get_eeprom             = ax8817x_get_eeprom,
-       .get_settings           = ax8817x_get_settings,
-       .set_settings           = ax8817x_set_settings,
-};
-
-static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
-{
-       int ret = 0;
-       void *buf;
-       int i;
-       unsigned long gpio_bits = dev->driver_info->data;
-
-       get_endpoints(dev,intf);
-
-       buf = kmalloc(ETH_ALEN, GFP_KERNEL);
-       if(!buf) {
-               ret = -ENOMEM;
-               goto out1;
-       }
-
-       /* Toggle the GPIOs in a manufacturer/model specific way */
-       for (i = 2; i >= 0; i--) {
-               if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
-                                       (gpio_bits >> (i * 8)) & 0xff, 0, 0,
-                                       buf)) < 0)
-                       goto out2;
-               msleep(5);
-       }
-
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
-               dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
-               goto out2;
-       }
-
-       /* Get the MAC address */
-       memset(buf, 0, ETH_ALEN);
-       if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) {
-               dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
-               goto out2;
-       }
-       memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
-       /* Get the PHY id */
-       if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
-               dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
-               goto out2;
-       } else if (ret < 2) {
-               /* this should always return 2 bytes */
-               dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret);
-               ret = -EIO;
-               goto out2;
-       }
-
-       /* Initialize MII structure */
-       dev->mii.dev = dev->net;
-       dev->mii.mdio_read = ax8817x_mdio_read;
-       dev->mii.mdio_write = ax8817x_mdio_write;
-       dev->mii.phy_id_mask = 0x3f;
-       dev->mii.reg_num_mask = 0x1f;
-       dev->mii.phy_id = *((u8 *)buf + 1);
-
-       dev->net->set_multicast_list = ax8817x_set_multicast;
-       dev->net->ethtool_ops = &ax8817x_ethtool_ops;
-
-       ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
-       ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
-               ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
-       mii_nway_restart(&dev->mii);
-
-       return 0;
-out2:
-       kfree(buf);
-out1:
-       return ret;
-}
-
-static struct ethtool_ops ax88772_ethtool_ops = {
-       .get_drvinfo            = ax8817x_get_drvinfo,
-       .get_link               = ethtool_op_get_link,
-       .get_msglevel           = usbnet_get_msglevel,
-       .set_msglevel           = usbnet_set_msglevel,
-       .get_wol                = ax8817x_get_wol,
-       .set_wol                = ax8817x_set_wol,
-       .get_eeprom_len         = ax8817x_get_eeprom_len,
-       .get_eeprom             = ax8817x_get_eeprom,
-       .get_settings           = ax8817x_get_settings,
-       .set_settings           = ax8817x_set_settings,
-};
-
-static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
-{
-       int ret;
-       void *buf;
-
-       get_endpoints(dev,intf);
-
-       buf = kmalloc(6, GFP_KERNEL);
-       if(!buf) {
-               dbg ("Cannot allocate memory for buffer");
-               ret = -ENOMEM;
-               goto out1;
-       }
-
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
-                                    0x00B0, 0, 0, buf)) < 0)
-               goto out2;
-
-       msleep(5);
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) {
-               dbg("Select PHY #1 failed: %d", ret);
-               goto out2;
-       }
-
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, 0, 0, buf)) < 0) {
-               dbg("Failed to power down internal PHY: %d", ret);
-               goto out2;
-       }
-
-       msleep(150);
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, 0, 0, buf)) < 0) {
-               dbg("Failed to perform software reset: %d", ret);
-               goto out2;
-       }
-
-       msleep(150);
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
-               dbg("Failed to set Internal/External PHY reset control: %d", ret);
-               goto out2;
-       }
-
-       msleep(150);
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0000, 0, 0,
-                              buf)) < 0) {
-               dbg("Failed to reset RX_CTL: %d", ret);
-               goto out2;
-       }
-
-       /* Get the MAC address */
-       memset(buf, 0, ETH_ALEN);
-       if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) {
-               dbg("Failed to read MAC address: %d", ret);
-               goto out2;
-       }
-       memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, buf)) < 0) {
-               dbg("Enabling software MII failed: %d", ret);
-               goto out2;
-       }
-
-       if (((ret =
-             ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0)
-           || (*((u16 *)buf) != 0x003b)) {
-               dbg("Read PHY register 2 must be 0x3b00: %d", ret);
-               goto out2;
-       }
-
-       /* Initialize MII structure */
-       dev->mii.dev = dev->net;
-       dev->mii.mdio_read = ax8817x_mdio_read;
-       dev->mii.mdio_write = ax8817x_mdio_write;
-       dev->mii.phy_id_mask = 0xff;
-       dev->mii.reg_num_mask = 0xff;
-
-       /* Get the PHY id */
-       if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
-               dbg("Error reading PHY ID: %02x", ret);
-               goto out2;
-       } else if (ret < 2) {
-               /* this should always return 2 bytes */
-               dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
-                   ret);
-               ret = -EIO;
-               goto out2;
-       }
-       dev->mii.phy_id = *((u8 *)buf + 1);
-
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, 0, 0, buf)) < 0) {
-               dbg("Set external PHY reset pin level: %d", ret);
-               goto out2;
-       }
-       msleep(150);
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
-               dbg("Set Internal/External PHY reset control: %d", ret);
-               goto out2;
-       }
-       msleep(150);
-
-
-       dev->net->set_multicast_list = ax8817x_set_multicast;
-       dev->net->ethtool_ops = &ax88772_ethtool_ops;
-
-       ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
-       ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
-                       ADVERTISE_ALL | ADVERTISE_CSMA);
-       mii_nway_restart(&dev->mii);
-
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
-               dbg("Write medium mode register: %d", ret);
-               goto out2;
-       }
-
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
-               dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
-               goto out2;
-       }
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
-               dbg("Failed to set hardware MII: %02x", ret);
-               goto out2;
-       }
-
-       /* Set RX_CTL to default values with 2k buffer, and enable cactus */
-       if ((ret =
-            ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
-                              buf)) < 0) {
-               dbg("Reset RX_CTL failed: %d", ret);
-               goto out2;
-       }
-
-       kfree(buf);
-
-       return 0;
-
-out2:
-       kfree(buf);
-out1:
-       return ret;
-}
-
-static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
-       u32 *header;
-       char *packet;
-       struct sk_buff *ax_skb;
-       u16 size;
-
-       header = (u32 *) skb->data;
-       le32_to_cpus(header);
-       packet = (char *)(header + 1);
-
-       skb_pull(skb, 4);
-
-       while (skb->len > 0) {
-               if ((short)(*header & 0x0000ffff) !=
-                   ~((short)((*header & 0xffff0000) >> 16))) {
-                       devdbg(dev,"header length data is error");
-               }
-               /* get the packet length */
-               size = (u16) (*header & 0x0000ffff);
-
-               if ((skb->len) - ((size + 1) & 0xfffe) == 0)
-                       return 2;
-               if (size > ETH_FRAME_LEN) {
-                       devdbg(dev,"invalid rx length %d", size);
-                       return 0;
-               }
-               ax_skb = skb_clone(skb, GFP_ATOMIC);
-               if (ax_skb) {
-                       ax_skb->len = size;
-                       ax_skb->data = packet;
-                       ax_skb->tail = packet + size;
-                       skb_return(dev, ax_skb);
-               } else {
-                       return 0;
-               }
-
-               skb_pull(skb, (size + 1) & 0xfffe);
-
-               if (skb->len == 0)
-                       break;
-
-               header = (u32 *) skb->data;
-               le32_to_cpus(header);
-               packet = (char *)(header + 1);
-               skb_pull(skb, 4);
-       }
-
-       if (skb->len < 0) {
-               devdbg(dev,"invalid rx length %d", skb->len);
-               return 0;
-       }
-       return 1;
-}
-
-static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
-                                       int flags)
-{
-       int padlen;
-       int headroom = skb_headroom(skb);
-       int tailroom = skb_tailroom(skb);
-       u32 *packet_len;
-       u32 *padbytes_ptr;
-
-       padlen = ((skb->len + 4) % 512) ? 0 : 4;
-
-       if ((!skb_cloned(skb))
-           && ((headroom + tailroom) >= (4 + padlen))) {
-               if ((headroom < 4) || (tailroom < padlen)) {
-                       skb->data = memmove(skb->head + 4, skb->data, skb->len);
-                       skb->tail = skb->data + skb->len;
-               }
-       } else {
-               struct sk_buff *skb2;
-               skb2 = skb_copy_expand(skb, 4, padlen, flags);
-               dev_kfree_skb_any(skb);
-               skb = skb2;
-               if (!skb)
-                       return NULL;
-       }
-
-       packet_len = (u32 *) skb_push(skb, 4);
-
-       packet_len = (u32 *) skb->data;
-       *packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
-
-       if ((skb->len % 512) == 0) {
-               padbytes_ptr = (u32 *) skb->tail;
-               *padbytes_ptr = 0xffff0000;
-               skb_put(skb, padlen);
-       }
-       return skb;
-}
-
-static int ax88772_link_reset(struct usbnet *dev)
-{
-       u16 lpa;
-       u16 mode;
-
-       mode = AX88772_MEDIUM_DEFAULT;
-       lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
-
-       if ((lpa & LPA_DUPLEX) == 0)
-               mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
-       if ((lpa & LPA_100) == 0)
-               mode &= ~AX88772_MEDIUM_100MB;
-       ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
-
-       return 0;
-}
-
-static const struct driver_info ax8817x_info = {
-       .description = "ASIX AX8817x USB 2.0 Ethernet",
-       .bind = ax8817x_bind,
-       .status = ax8817x_status,
-       .link_reset = ax88172_link_reset,
-       .reset = ax88172_link_reset,
-       .flags =  FLAG_ETHER,
-       .data = 0x00130103,
-};
-
-static const struct driver_info dlink_dub_e100_info = {
-       .description = "DLink DUB-E100 USB Ethernet",
-       .bind = ax8817x_bind,
-       .status = ax8817x_status,
-       .link_reset = ax88172_link_reset,
-       .reset = ax88172_link_reset,
-       .flags =  FLAG_ETHER,
-       .data = 0x009f9d9f,
-};
-
-static const struct driver_info netgear_fa120_info = {
-       .description = "Netgear FA-120 USB Ethernet",
-       .bind = ax8817x_bind,
-       .status = ax8817x_status,
-       .link_reset = ax88172_link_reset,
-       .reset = ax88172_link_reset,
-       .flags =  FLAG_ETHER,
-       .data = 0x00130103,
-};
-
-static const struct driver_info hawking_uf200_info = {
-       .description = "Hawking UF200 USB Ethernet",
-       .bind = ax8817x_bind,
-       .status = ax8817x_status,
-       .link_reset = ax88172_link_reset,
-       .reset = ax88172_link_reset,
-       .flags =  FLAG_ETHER,
-       .data = 0x001f1d1f,
-};
-
-static const struct driver_info ax88772_info = {
-       .description = "ASIX AX88772 USB 2.0 Ethernet",
-       .bind = ax88772_bind,
-       .status = ax8817x_status,
-       .link_reset = ax88772_link_reset,
-       .reset = ax88772_link_reset,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
-       .rx_fixup = ax88772_rx_fixup,
-       .tx_fixup = ax88772_tx_fixup,
-       .data = 0x00130103,
-};
-
-#endif /* CONFIG_USB_AX8817X */
-
-
-\f
-#ifdef CONFIG_USB_BELKIN
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Belkin F5U104 ... two NetChip 2280 devices + Atmel microcontroller
- *
- * ... also two eTEK designs, including one sold as "Advance USBNET"
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info        belkin_info = {
-       .description =  "Belkin, eTEK, or compatible",
-};
-
-#endif /* CONFIG_USB_BELKIN */
-
-
-\f
-/*-------------------------------------------------------------------------
- *
- * Communications Device Class declarations.
- * Used by CDC Ethernet, and some CDC variants
- *
- *-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_USB_CDCETHER
-#define NEED_GENERIC_CDC
-#endif
-
-#ifdef CONFIG_USB_ZAURUS
-/* Ethernet variant uses funky framing, broken ethernet addressing */
-#define NEED_GENERIC_CDC
-#endif
-
-#ifdef CONFIG_USB_RNDIS
-/* ACM variant uses even funkier framing, complex control RPC scheme */
-#define NEED_GENERIC_CDC
-#endif
-
-
-#ifdef NEED_GENERIC_CDC
-
-#include <linux/usb_cdc.h>
-
-struct cdc_state {
-       struct usb_cdc_header_desc      *header;
-       struct usb_cdc_union_desc       *u;
-       struct usb_cdc_ether_desc       *ether;
-       struct usb_interface            *control;
-       struct usb_interface            *data;
-};
-
-static struct usb_driver usbnet_driver;
-
-/*
- * probes control interface, claims data interface, collects the bulk
- * endpoints, activates data interface (if needed), maybe sets MTU.
- * all pure cdc, except for certain firmware workarounds.
- */
-static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
-{
-       u8                              *buf = intf->cur_altsetting->extra;
-       int                             len = intf->cur_altsetting->extralen;
-       struct usb_interface_descriptor *d;
-       struct cdc_state                *info = (void *) &dev->data;
-       int                             status;
-       int                             rndis;
-
-       if (sizeof dev->data < sizeof *info)
-               return -EDOM;
-
-       /* expect strict spec conformance for the descriptors, but
-        * cope with firmware which stores them in the wrong place
-        */
-       if (len == 0 && dev->udev->actconfig->extralen) {
-               /* Motorola SB4100 (and others: Brad Hards says it's
-                * from a Broadcom design) put CDC descriptors here
-                */
-               buf = dev->udev->actconfig->extra;
-               len = dev->udev->actconfig->extralen;
-               if (len)
-                       dev_dbg (&intf->dev,
-                               "CDC descriptors on config\n");
-       }
-
-       /* this assumes that if there's a non-RNDIS vendor variant
-        * of cdc-acm, it'll fail RNDIS requests cleanly.
-        */
-       rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
-
-       memset (info, 0, sizeof *info);
-       info->control = intf;
-       while (len > 3) {
-               if (buf [1] != USB_DT_CS_INTERFACE)
-                       goto next_desc;
-
-               /* use bDescriptorSubType to identify the CDC descriptors.
-                * We expect devices with CDC header and union descriptors.
-                * For CDC Ethernet we need the ethernet descriptor.
-                * For RNDIS, ignore two (pointless) CDC modem descriptors
-                * in favor of a complicated OID-based RPC scheme doing what
-                * CDC Ethernet achieves with a simple descriptor.
-                */
-               switch (buf [2]) {
-               case USB_CDC_HEADER_TYPE:
-                       if (info->header) {
-                               dev_dbg (&intf->dev, "extra CDC header\n");
-                               goto bad_desc;
-                       }
-                       info->header = (void *) buf;
-                       if (info->header->bLength != sizeof *info->header) {
-                               dev_dbg (&intf->dev, "CDC header len %u\n",
-                                       info->header->bLength);
-                               goto bad_desc;
-                       }
-                       break;
-               case USB_CDC_UNION_TYPE:
-                       if (info->u) {
-                               dev_dbg (&intf->dev, "extra CDC union\n");
-                               goto bad_desc;
-                       }
-                       info->u = (void *) buf;
-                       if (info->u->bLength != sizeof *info->u) {
-                               dev_dbg (&intf->dev, "CDC union len %u\n",
-                                       info->u->bLength);
-                               goto bad_desc;
-                       }
-
-                       /* we need a master/control interface (what we're
-                        * probed with) and a slave/data interface; union
-                        * descriptors sort this all out.
-                        */
-                       info->control = usb_ifnum_to_if(dev->udev,
-                                               info->u->bMasterInterface0);
-                       info->data = usb_ifnum_to_if(dev->udev,
-                                               info->u->bSlaveInterface0);
-                       if (!info->control || !info->data) {
-                               dev_dbg (&intf->dev,
-                                       "master #%u/%p slave #%u/%p\n",
-                                       info->u->bMasterInterface0,
-                                       info->control,
-                                       info->u->bSlaveInterface0,
-                                       info->data);
-                               goto bad_desc;
-                       }
-                       if (info->control != intf) {
-                               dev_dbg (&intf->dev, "bogus CDC Union\n");
-                               /* Ambit USB Cable Modem (and maybe others)
-                                * interchanges master and slave interface.
-                                */
-                               if (info->data == intf) {
-                                       info->data = info->control;
-                                       info->control = intf;
-                               } else
-                                       goto bad_desc;
-                       }
-
-                       /* a data interface altsetting does the real i/o */
-                       d = &info->data->cur_altsetting->desc;
-                       if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
-                               dev_dbg (&intf->dev, "slave class %u\n",
-                                       d->bInterfaceClass);
-                               goto bad_desc;
-                       }
-                       break;
-               case USB_CDC_ETHERNET_TYPE:
-                       if (info->ether) {
-                               dev_dbg (&intf->dev, "extra CDC ether\n");
-                               goto bad_desc;
-                       }
-                       info->ether = (void *) buf;
-                       if (info->ether->bLength != sizeof *info->ether) {
-                               dev_dbg (&intf->dev, "CDC ether len %u\n",
-                                       info->ether->bLength);
-                               goto bad_desc;
-                       }
-                       dev->net->mtu = le16_to_cpup (
-                                               &info->ether->wMaxSegmentSize)
-                                       - ETH_HLEN;
-                       /* because of Zaurus, we may be ignoring the host
-                        * side link address we were given.
-                        */
-                       break;
-               }
-next_desc:
-               len -= buf [0]; /* bLength */
-               buf += buf [0];
-       }
-
-       if (!info->header || !info->u || (!rndis && !info->ether)) {
-               dev_dbg (&intf->dev, "missing cdc %s%s%sdescriptor\n",
-                       info->header ? "" : "header ",
-                       info->u ? "" : "union ",
-                       info->ether ? "" : "ether ");
-               goto bad_desc;
-       }
-
-       /* claim data interface and set it up ... with side effects.
-        * network traffic can't flow until an altsetting is enabled.
-        */
-       status = usb_driver_claim_interface (&usbnet_driver, info->data, dev);
-       if (status < 0)
-               return status;
-       status = get_endpoints (dev, info->data);
-       if (status < 0) {
-               /* ensure immediate exit from usbnet_disconnect */
-               usb_set_intfdata(info->data, NULL);
-               usb_driver_release_interface (&usbnet_driver, info->data);
-               return status;
-       }
-
-       /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
-       dev->status = NULL;
-       if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
-               struct usb_endpoint_descriptor  *desc;
-
-               dev->status = &info->control->cur_altsetting->endpoint [0];
-               desc = &dev->status->desc;
-               if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
-                               || !(desc->bEndpointAddress & USB_DIR_IN)
-                               || (le16_to_cpu(desc->wMaxPacketSize)
-                                       < sizeof (struct usb_cdc_notification))
-                               || !desc->bInterval) {
-                       dev_dbg (&intf->dev, "bad notification endpoint\n");
-                       dev->status = NULL;
-               }
-       }
-       if (rndis && !dev->status) {
-               dev_dbg (&intf->dev, "missing RNDIS status endpoint\n");
-               usb_set_intfdata(info->data, NULL);
-               usb_driver_release_interface (&usbnet_driver, info->data);
-               return -ENODEV;
-       }
-       return 0;
-
-bad_desc:
-       dev_info (&dev->udev->dev, "bad CDC descriptors\n");
-       return -ENODEV;
-}
-
-static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
-{
-       struct cdc_state                *info = (void *) &dev->data;
-
-       /* disconnect master --> disconnect slave */
-       if (intf == info->control && info->data) {
-               /* ensure immediate exit from usbnet_disconnect */
-               usb_set_intfdata(info->data, NULL);
-               usb_driver_release_interface (&usbnet_driver, info->data);
-               info->data = NULL;
-       }
-
-       /* and vice versa (just in case) */
-       else if (intf == info->data && info->control) {
-               /* ensure immediate exit from usbnet_disconnect */
-               usb_set_intfdata(info->control, NULL);
-               usb_driver_release_interface (&usbnet_driver, info->control);
-               info->control = NULL;
-       }
-}
-
-#endif /* NEED_GENERIC_CDC */
-
-\f
-#ifdef CONFIG_USB_CDCETHER
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Communications Device Class, Ethernet Control model
- *
- * Takes two interfaces.  The DATA interface is inactive till an altsetting
- * is selected.  Configuration data includes class descriptors.
- *
- * This should interop with whatever the 2.4 "CDCEther.c" driver
- * (by Brad Hards) talked with.
- *
- *-------------------------------------------------------------------------*/
-
-#include <linux/ctype.h>
-
-
-static void dumpspeed (struct usbnet *dev, __le32 *speeds)
-{
-       if (netif_msg_timer (dev))
-               devinfo (dev, "link speeds: %u kbps up, %u kbps down",
-                       __le32_to_cpu(speeds[0]) / 1000,
-               __le32_to_cpu(speeds[1]) / 1000);
-}
-
-static void cdc_status (struct usbnet *dev, struct urb *urb)
-{
-       struct usb_cdc_notification     *event;
-
-       if (urb->actual_length < sizeof *event)
-               return;
-       
-       /* SPEED_CHANGE can get split into two 8-byte packets */
-       if (test_and_clear_bit (EVENT_STS_SPLIT, &dev->flags)) {
-               dumpspeed (dev, (__le32 *) urb->transfer_buffer);
-               return;
-       }
-
-       event = urb->transfer_buffer;
-       switch (event->bNotificationType) {
-       case USB_CDC_NOTIFY_NETWORK_CONNECTION:
-               if (netif_msg_timer (dev))
-                       devdbg (dev, "CDC: carrier %s",
-                                       event->wValue ? "on" : "off");
-               if (event->wValue)
-                       netif_carrier_on(dev->net);
-               else
-                       netif_carrier_off(dev->net);
-               break;
-       case USB_CDC_NOTIFY_SPEED_CHANGE:       /* tx/rx rates */
-               if (netif_msg_timer (dev))
-                       devdbg (dev, "CDC: speed change (len %d)",
-                                       urb->actual_length);
-               if (urb->actual_length != (sizeof *event + 8))
-                       set_bit (EVENT_STS_SPLIT, &dev->flags);
-               else
-                       dumpspeed (dev, (__le32 *) &event[1]);
-               break;
-       // case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:      /* RNDIS; or unsolicited */
-       default:
-               deverr (dev, "CDC: unexpected notification %02x!",
-                                event->bNotificationType);
-               break;
-       }
-}
-
-static u8 nibble (unsigned char c)
-{
-       if (likely (isdigit (c)))
-               return c - '0';
-       c = toupper (c);
-       if (likely (isxdigit (c)))
-               return 10 + c - 'A';
-       return 0;
-}
-
-static inline int
-get_ethernet_addr (struct usbnet *dev, struct usb_cdc_ether_desc *e)
-{
-       int             tmp, i;
-       unsigned char   buf [13];
-
-       tmp = usb_string (dev->udev, e->iMACAddress, buf, sizeof buf);
-       if (tmp != 12) {
-               dev_dbg (&dev->udev->dev,
-                       "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
-               if (tmp >= 0)
-                       tmp = -EINVAL;
-               return tmp;
-       }
-       for (i = tmp = 0; i < 6; i++, tmp += 2)
-               dev->net->dev_addr [i] =
-                        (nibble (buf [tmp]) << 4) + nibble (buf [tmp + 1]);
-       return 0;
-}
-
-static int cdc_bind (struct usbnet *dev, struct usb_interface *intf)
-{
-       int                             status;
-       struct cdc_state                *info = (void *) &dev->data;
-
-       status = generic_cdc_bind (dev, intf);
-       if (status < 0)
-               return status;
-
-       status = get_ethernet_addr (dev, info->ether);
-       if (status < 0) {
-               usb_set_intfdata(info->data, NULL);
-               usb_driver_release_interface (&usbnet_driver, info->data);
-               return status;
-       }
-
-       /* FIXME cdc-ether has some multicast code too, though it complains
-        * in routine cases.  info->ether describes the multicast support.
-        */
-       return 0;
-}
-
-static const struct driver_info        cdc_info = {
-       .description =  "CDC Ethernet Device",
-       .flags =        FLAG_ETHER,
-       // .check_connect = cdc_check_connect,
-       .bind =         cdc_bind,
-       .unbind =       cdc_unbind,
-       .status =       cdc_status,
-};
-
-#endif /* CONFIG_USB_CDCETHER */
-
-
-\f
-#ifdef CONFIG_USB_EPSON2888
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * EPSON USB clients
- *
- * This is the same idea as Linux PDAs (below) except the firmware in the
- * device might not be Tux-powered.  Epson provides reference firmware that
- * implements this interface.  Product developers can reuse or modify that
- * code, such as by using their own product and vendor codes.
- *
- * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info        epson2888_info = {
-       .description =  "Epson USB Device",
-       .check_connect = always_connected,
-
-       .in = 4, .out = 3,
-};
-
-#endif /* CONFIG_USB_EPSON2888 */
-
-\f
-#ifdef CONFIG_USB_GENESYS
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * GeneSys GL620USB-A (www.genesyslogic.com.tw)
- *
- * ... should partially interop with the Win32 driver for this hardware
- * The GeneSys docs imply there's some NDIS issue motivating this framing.
- *
- * Some info from GeneSys:
- *  - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
- *    (Some cables, like the BAFO-100c, use the half duplex version.)
- *  - For the full duplex model, the low bit of the version code says
- *    which side is which ("left/right").
- *  - For the half duplex type, a control/interrupt handshake settles
- *    the transfer direction.  (That's disabled here, partially coded.)
- *    A control URB would block until other side writes an interrupt.
- *
- * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
- * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
- *
- *-------------------------------------------------------------------------*/
-
-// control msg write command
-#define GENELINK_CONNECT_WRITE                 0xF0
-// interrupt pipe index
-#define GENELINK_INTERRUPT_PIPE                        0x03
-// interrupt read buffer size
-#define INTERRUPT_BUFSIZE                      0x08
-// interrupt pipe interval value
-#define GENELINK_INTERRUPT_INTERVAL            0x10
-// max transmit packet number per transmit
-#define GL_MAX_TRANSMIT_PACKETS                        32
-// max packet length
-#define GL_MAX_PACKET_LEN                      1514
-// max receive buffer size 
-#define GL_RCV_BUF_SIZE                \
-       (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
-
-struct gl_packet {
-       u32             packet_length;
-       char            packet_data [1];
-};
-
-struct gl_header {
-       u32                     packet_count;
-       struct gl_packet        packets;
-};
-
-#ifdef GENELINK_ACK
-
-// FIXME:  this code is incomplete, not debugged; it doesn't
-// handle interrupts correctly.  interrupts should be generic
-// code like all other device I/O, anyway.
-
-struct gl_priv { 
-       struct urb      *irq_urb;
-       char            irq_buf [INTERRUPT_BUFSIZE];
-};
-
-static inline int gl_control_write (struct usbnet *dev, u8 request, u16 value)
-{
-       int retval;
-
-       retval = usb_control_msg (dev->udev,
-                     usb_sndctrlpipe (dev->udev, 0),
-                     request,
-                     USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-                     value, 
-                     0,                        // index
-                     0,                        // data buffer
-                     0,                        // size
-                     CONTROL_TIMEOUT_MS);
-       return retval;
-}
-
-static void gl_interrupt_complete (struct urb *urb, struct pt_regs *regs)
-{
-       int status = urb->status;
-       
-       switch (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__, status);
-               return;
-       default:
-               dbg("%s - nonzero urb status received: %d",
-                               __FUNCTION__, urb->status);
-       }
-
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status)
-               err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, status);
-}
-
-static int gl_interrupt_read (struct usbnet *dev)
-{
-       struct gl_priv  *priv = dev->priv_data;
-       int             retval;
-
-       // issue usb interrupt read
-       if (priv && priv->irq_urb) {
-               // submit urb
-               if ((retval = usb_submit_urb (priv->irq_urb, GFP_KERNEL)) != 0)
-                       dbg ("gl_interrupt_read: submit fail - %X...", retval);
-               else
-                       dbg ("gl_interrupt_read: submit success...");
-       }
-
-       return 0;
-}
-
-// check whether another side is connected
-static int genelink_check_connect (struct usbnet *dev)
-{
-       int                     retval;
-
-       dbg ("genelink_check_connect...");
-
-       // detect whether another side is connected
-       if ((retval = gl_control_write (dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
-               dbg ("%s: genelink_check_connect write fail - %X",
-                       dev->net->name, retval);
-               return retval;
-       }
-
-       // usb interrupt read to ack another side 
-       if ((retval = gl_interrupt_read (dev)) != 0) {
-               dbg ("%s: genelink_check_connect read fail - %X",
-                       dev->net->name, retval);
-               return retval;
-       }
-
-       dbg ("%s: genelink_check_connect read success", dev->net->name);
-       return 0;
-}
-
-// allocate and initialize the private data for genelink
-static int genelink_init (struct usbnet *dev)
-{
-       struct gl_priv *priv;
-
-       // allocate the private data structure
-       if ((priv = kmalloc (sizeof *priv, GFP_KERNEL)) == 0) {
-               dbg ("%s: cannot allocate private data per device",
-                       dev->net->name);
-               return -ENOMEM;
-       }
-
-       // allocate irq urb
-       if ((priv->irq_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
-               dbg ("%s: cannot allocate private irq urb per device",
-                       dev->net->name);
-               kfree (priv);
-               return -ENOMEM;
-       }
-
-       // fill irq urb
-       usb_fill_int_urb (priv->irq_urb, dev->udev,
-               usb_rcvintpipe (dev->udev, GENELINK_INTERRUPT_PIPE),
-               priv->irq_buf, INTERRUPT_BUFSIZE,
-               gl_interrupt_complete, 0,
-               GENELINK_INTERRUPT_INTERVAL);
-
-       // set private data pointer
-       dev->priv_data = priv;
-
-       return 0;
-}
-
-// release the private data
-static int genelink_free (struct usbnet *dev)
-{
-       struct gl_priv  *priv = dev->priv_data;
-
-       if (!priv) 
-               return 0;
-
-// FIXME:  can't cancel here; it's synchronous, and
-// should have happened earlier in any case (interrupt
-// handling needs to be generic)
-
-       // cancel irq urb first
-       usb_kill_urb (priv->irq_urb);
-
-       // free irq urb
-       usb_free_urb (priv->irq_urb);
-
-       // free the private data structure
-       kfree (priv);
-
-       return 0;
-}
-
-#endif
-
-static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
-{
-       struct gl_header        *header;
-       struct gl_packet        *packet;
-       struct sk_buff          *gl_skb;
-       u32                     size;
-
-       header = (struct gl_header *) skb->data;
-
-       // get the packet count of the received skb
-       le32_to_cpus (&header->packet_count);
-       if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS)
-                       || (header->packet_count < 0)) {
-               dbg ("genelink: invalid received packet count %d",
-                       header->packet_count);
-               return 0;
-       }
-
-       // set the current packet pointer to the first packet
-       packet = &header->packets;
-
-       // decrement the length for the packet count size 4 bytes
-       skb_pull (skb, 4);
-
-       while (header->packet_count > 1) {
-               // get the packet length
-               size = packet->packet_length;
-
-               // this may be a broken packet
-               if (size > GL_MAX_PACKET_LEN) {
-                       dbg ("genelink: invalid rx length %d", size);
-                       return 0;
-               }
-
-               // allocate the skb for the individual packet
-               gl_skb = alloc_skb (size, GFP_ATOMIC);
-               if (gl_skb) {
-
-                       // copy the packet data to the new skb
-                       memcpy(skb_put(gl_skb, size), packet->packet_data, size);
-                       skb_return (dev, gl_skb);
-               }
-
-               // advance to the next packet
-               packet = (struct gl_packet *)
-                       &packet->packet_data [size];
-               header->packet_count--;
-
-               // shift the data pointer to the next gl_packet
-               skb_pull (skb, size + 4);
-       }
-
-       // skip the packet length field 4 bytes
-       skb_pull (skb, 4);
-
-       if (skb->len > GL_MAX_PACKET_LEN) {
-               dbg ("genelink: invalid rx length %d", skb->len);
-               return 0;
-       }
-       return 1;
-}
-
-static struct sk_buff *
-genelink_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
-{
-       int     padlen;
-       int     length = skb->len;
-       int     headroom = skb_headroom (skb);
-       int     tailroom = skb_tailroom (skb);
-       u32     *packet_count;
-       u32     *packet_len;
-
-       // FIXME:  magic numbers, bleech
-       padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
-
-       if ((!skb_cloned (skb))
-                       && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
-               if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
-                       skb->data = memmove (skb->head + (4 + 4*1),
-                                            skb->data, skb->len);
-                       skb->tail = skb->data + skb->len;
-               }
-       } else {
-               struct sk_buff  *skb2;
-               skb2 = skb_copy_expand (skb, (4 + 4*1) , padlen, flags);
-               dev_kfree_skb_any (skb);
-               skb = skb2;
-               if (!skb)
-                       return NULL;
-       }
-
-       // attach the packet count to the header
-       packet_count = (u32 *) skb_push (skb, (4 + 4*1));
-       packet_len = packet_count + 1;
-
-       // FIXME little endian?
-       *packet_count = 1;
-       *packet_len = length;
-
-       // add padding byte
-       if ((skb->len % dev->maxpacket) == 0)
-               skb_put (skb, 1);
-
-       return skb;
-}
-
-static const struct driver_info        genelink_info = {
-       .description =  "Genesys GeneLink",
-       .flags =        FLAG_FRAMING_GL | FLAG_NO_SETINT,
-       .rx_fixup =     genelink_rx_fixup,
-       .tx_fixup =     genelink_tx_fixup,
-
-       .in = 1, .out = 2,
-
-#ifdef GENELINK_ACK
-       .check_connect =genelink_check_connect,
-#endif
-};
-
-#endif /* CONFIG_USB_GENESYS */
-
-
-\f
-#ifdef CONFIG_USB_NET1080
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Netchip 1080 driver ... http://www.netchip.com
- * Used in LapLink cables
- *
- *-------------------------------------------------------------------------*/
-
-#define dev_packet_id  data[0]
-#define frame_errors   data[1]
-
-/*
- * NetChip framing of ethernet packets, supporting additional error
- * checks for links that may drop bulk packets from inside messages.
- * Odd USB length == always short read for last usb packet.
- *     - nc_header
- *     - Ethernet header (14 bytes)
- *     - payload
- *     - (optional padding byte, if needed so length becomes odd)
- *     - nc_trailer
- *
- * This framing is to be avoided for non-NetChip devices.
- */
-
-struct nc_header {             // packed:
-       __le16  hdr_len;                // sizeof nc_header (LE, all)
-       __le16  packet_len;             // payload size (including ethhdr)
-       __le16  packet_id;              // detects dropped packets
-#define MIN_HEADER     6
-
-       // all else is optional, and must start with:
-       // u16  vendorId;               // from usb-if
-       // u16  productId;
-} __attribute__((__packed__));
-
-#define        PAD_BYTE        ((unsigned char)0xAC)
-
-struct nc_trailer {
-       __le16  packet_id;
-} __attribute__((__packed__));
-
-// packets may use FLAG_FRAMING_NC and optional pad
-#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
-                               + sizeof (struct ethhdr) \
-                               + (mtu) \
-                               + 1 \
-                               + sizeof (struct nc_trailer))
-
-#define MIN_FRAMED     FRAMED_SIZE(0)
-
-
-/*
- * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
- * before the hardware drops it.  If that's done, the driver will need to
- * frame network packets to guard against the dropped USB packets.  The win32
- * driver sets this for both sides of the link.
- */
-#define        NC_READ_TTL_MS  ((u8)255)       // ms
-
-/*
- * We ignore most registers and EEPROM contents.
- */
-#define        REG_USBCTL      ((u8)0x04)
-#define REG_TTL                ((u8)0x10)
-#define REG_STATUS     ((u8)0x11)
-
-/*
- * Vendor specific requests to read/write data
- */
-#define        REQUEST_REGISTER        ((u8)0x10)
-#define        REQUEST_EEPROM          ((u8)0x11)
-
-static int
-nc_vendor_read (struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
-{
-       int status = usb_control_msg (dev->udev,
-               usb_rcvctrlpipe (dev->udev, 0),
-               req,
-               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               0, regnum,
-               retval_ptr, sizeof *retval_ptr,
-               CONTROL_TIMEOUT_MS);
-       if (status > 0)
-               status = 0;
-       if (!status)
-               le16_to_cpus (retval_ptr);
-       return status;
-}
-
-static inline int
-nc_register_read (struct usbnet *dev, u8 regnum, u16 *retval_ptr)
-{
-       return nc_vendor_read (dev, REQUEST_REGISTER, regnum, retval_ptr);
-}
-
-// no retval ... can become async, usable in_interrupt()
-static void
-nc_vendor_write (struct usbnet *dev, u8 req, u8 regnum, u16 value)
-{
-       usb_control_msg (dev->udev,
-               usb_sndctrlpipe (dev->udev, 0),
-               req,
-               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               value, regnum,
-               NULL, 0,                        // data is in setup packet
-               CONTROL_TIMEOUT_MS);
-}
-
-static inline void
-nc_register_write (struct usbnet *dev, u8 regnum, u16 value)
-{
-       nc_vendor_write (dev, REQUEST_REGISTER, regnum, value);
-}
-
-
-#if 0
-static void nc_dump_registers (struct usbnet *dev)
-{
-       u8      reg;
-       u16     *vp = kmalloc (sizeof (u16));
-
-       if (!vp) {
-               dbg ("no memory?");
-               return;
-       }
-
-       dbg ("%s registers:", dev->net->name);
-       for (reg = 0; reg < 0x20; reg++) {
-               int retval;
-
-               // reading some registers is trouble
-               if (reg >= 0x08 && reg <= 0xf)
-                       continue;
-               if (reg >= 0x12 && reg <= 0x1e)
-                       continue;
-
-               retval = nc_register_read (dev, reg, vp);
-               if (retval < 0)
-                       dbg ("%s reg [0x%x] ==> error %d",
-                               dev->net->name, reg, retval);
-               else
-                       dbg ("%s reg [0x%x] = 0x%x",
-                               dev->net->name, reg, *vp);
-       }
-       kfree (vp);
-}
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Control register
- */
-
-#define        USBCTL_WRITABLE_MASK    0x1f0f
-// bits 15-13 reserved, r/o
-#define        USBCTL_ENABLE_LANG      (1 << 12)
-#define        USBCTL_ENABLE_MFGR      (1 << 11)
-#define        USBCTL_ENABLE_PROD      (1 << 10)
-#define        USBCTL_ENABLE_SERIAL    (1 << 9)
-#define        USBCTL_ENABLE_DEFAULTS  (1 << 8)
-// bits 7-4 reserved, r/o
-#define        USBCTL_FLUSH_OTHER      (1 << 3)
-#define        USBCTL_FLUSH_THIS       (1 << 2)
-#define        USBCTL_DISCONN_OTHER    (1 << 1)
-#define        USBCTL_DISCONN_THIS     (1 << 0)
-
-static inline void nc_dump_usbctl (struct usbnet *dev, u16 usbctl)
-{
-       if (!netif_msg_link (dev))
-               return;
-       devdbg (dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
-                       " this%s%s;"
-                       " other%s%s; r/o 0x%x",
-               dev->udev->bus->bus_name, dev->udev->devpath,
-               usbctl,
-               (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
-               (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
-               (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
-               (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
-               (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
-
-               (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
-               (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
-               (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
-               (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
-               usbctl & ~USBCTL_WRITABLE_MASK
-               );
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Status register
- */
-
-#define        STATUS_PORT_A           (1 << 15)
-
-#define        STATUS_CONN_OTHER       (1 << 14)
-#define        STATUS_SUSPEND_OTHER    (1 << 13)
-#define        STATUS_MAILBOX_OTHER    (1 << 12)
-#define        STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
-
-#define        STATUS_CONN_THIS        (1 << 6)
-#define        STATUS_SUSPEND_THIS     (1 << 5)
-#define        STATUS_MAILBOX_THIS     (1 << 4)
-#define        STATUS_PACKETS_THIS(n)  (((n) >> 0) && 0x03)
-
-#define        STATUS_UNSPEC_MASK      0x0c8c
-#define        STATUS_NOISE_MASK       ((u16)~(0x0303|STATUS_UNSPEC_MASK))
-
-
-static inline void nc_dump_status (struct usbnet *dev, u16 status)
-{
-       if (!netif_msg_link (dev))
-               return;
-       devdbg (dev, "net1080 %s-%s status 0x%x:"
-                       " this (%c) PKT=%d%s%s%s;"
-                       " other PKT=%d%s%s%s; unspec 0x%x",
-               dev->udev->bus->bus_name, dev->udev->devpath,
-               status,
-
-               // XXX the packet counts don't seem right
-               // (1 at reset, not 0); maybe UNSPEC too
-
-               (status & STATUS_PORT_A) ? 'A' : 'B',
-               STATUS_PACKETS_THIS (status),
-               (status & STATUS_CONN_THIS) ? " CON" : "",
-               (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
-               (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
-
-               STATUS_PACKETS_OTHER (status),
-               (status & STATUS_CONN_OTHER) ? " CON" : "",
-               (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
-               (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
-
-               status & STATUS_UNSPEC_MASK
-               );
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * TTL register
- */
-
-#define        TTL_THIS(ttl)   (0x00ff & ttl)
-#define        TTL_OTHER(ttl)  (0x00ff & (ttl >> 8))
-#define MK_TTL(this,other)     ((u16)(((other)<<8)|(0x00ff&(this))))
-
-static inline void nc_dump_ttl (struct usbnet *dev, u16 ttl)
-{
-       if (netif_msg_link (dev))
-               devdbg (dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
-                       dev->udev->bus->bus_name, dev->udev->devpath,
-                       ttl, TTL_THIS (ttl), TTL_OTHER (ttl));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int net1080_reset (struct usbnet *dev)
-{
-       u16             usbctl, status, ttl;
-       u16             *vp = kmalloc (sizeof (u16), GFP_KERNEL);
-       int             retval;
-
-       if (!vp)
-               return -ENOMEM;
-
-       // nc_dump_registers (dev);
-
-       if ((retval = nc_register_read (dev, REG_STATUS, vp)) < 0) {
-               dbg ("can't read %s-%s status: %d",
-                       dev->udev->bus->bus_name, dev->udev->devpath, retval);
-               goto done;
-       }
-       status = *vp;
-       nc_dump_status (dev, status);
-
-       if ((retval = nc_register_read (dev, REG_USBCTL, vp)) < 0) {
-               dbg ("can't read USBCTL, %d", retval);
-               goto done;
-       }
-       usbctl = *vp;
-       nc_dump_usbctl (dev, usbctl);
-
-       nc_register_write (dev, REG_USBCTL,
-                       USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
-
-       if ((retval = nc_register_read (dev, REG_TTL, vp)) < 0) {
-               dbg ("can't read TTL, %d", retval);
-               goto done;
-       }
-       ttl = *vp;
-       // nc_dump_ttl (dev, ttl);
-
-       nc_register_write (dev, REG_TTL,
-                       MK_TTL (NC_READ_TTL_MS, TTL_OTHER (ttl)) );
-       dbg ("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
-
-       if (netif_msg_link (dev))
-               devinfo (dev, "port %c, peer %sconnected",
-                       (status & STATUS_PORT_A) ? 'A' : 'B',
-                       (status & STATUS_CONN_OTHER) ? "" : "dis"
-                       );
-       retval = 0;
-
-done:
-       kfree (vp);
-       return retval;
-}
-
-static int net1080_check_connect (struct usbnet *dev)
-{
-       int                     retval;
-       u16                     status;
-       u16                     *vp = kmalloc (sizeof (u16), GFP_KERNEL);
-
-       if (!vp)
-               return -ENOMEM;
-       retval = nc_register_read (dev, REG_STATUS, vp);
-       status = *vp;
-       kfree (vp);
-       if (retval != 0) {
-               dbg ("%s net1080_check_conn read - %d", dev->net->name, retval);
-               return retval;
-       }
-       if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
-               return -ENOLINK;
-       return 0;
-}
-
-static void nc_flush_complete (struct urb *urb, struct pt_regs *regs)
-{
-       kfree (urb->context);
-       usb_free_urb(urb);
-}
-
-static void nc_ensure_sync (struct usbnet *dev)
-{
-       dev->frame_errors++;
-       if (dev->frame_errors > 5) {
-               struct urb              *urb;
-               struct usb_ctrlrequest  *req;
-               int                     status;
-
-               /* Send a flush */
-               urb = usb_alloc_urb (0, SLAB_ATOMIC);
-               if (!urb)
-                       return;
-
-               req = kmalloc (sizeof *req, GFP_ATOMIC);
-               if (!req) {
-                       usb_free_urb (urb);
-                       return;
-               }
-
-               req->bRequestType = USB_DIR_OUT
-                       | USB_TYPE_VENDOR
-                       | USB_RECIP_DEVICE;
-               req->bRequest = REQUEST_REGISTER;
-               req->wValue = cpu_to_le16 (USBCTL_FLUSH_THIS
-                               | USBCTL_FLUSH_OTHER);
-               req->wIndex = cpu_to_le16 (REG_USBCTL);
-               req->wLength = cpu_to_le16 (0);
-
-               /* queue an async control request, we don't need
-                * to do anything when it finishes except clean up.
-                */
-               usb_fill_control_urb (urb, dev->udev,
-                       usb_sndctrlpipe (dev->udev, 0),
-                       (unsigned char *) req,
-                       NULL, 0,
-                       nc_flush_complete, req);
-               status = usb_submit_urb (urb, GFP_ATOMIC);
-               if (status) {
-                       kfree (req);
-                       usb_free_urb (urb);
-                       return;
-               }
-
-               if (netif_msg_rx_err (dev))
-                       devdbg (dev, "flush net1080; too many framing errors");
-               dev->frame_errors = 0;
-       }
-}
-
-static int net1080_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
-{
-       struct nc_header        *header;
-       struct nc_trailer       *trailer;
-       u16                     hdr_len, packet_len;
-
-       if (!(skb->len & 0x01)
-                       || MIN_FRAMED > skb->len
-                       || skb->len > FRAMED_SIZE (dev->net->mtu)) {
-               dev->stats.rx_frame_errors++;
-               dbg ("rx framesize %d range %d..%d mtu %d", skb->len,
-                       (int)MIN_FRAMED, (int)FRAMED_SIZE (dev->net->mtu),
-                       dev->net->mtu);
-               nc_ensure_sync (dev);
-               return 0;
-       }
-
-       header = (struct nc_header *) skb->data;
-       hdr_len = le16_to_cpup (&header->hdr_len);
-       packet_len = le16_to_cpup (&header->packet_len);
-       if (FRAMED_SIZE (packet_len) > MAX_PACKET) {
-               dev->stats.rx_frame_errors++;
-               dbg ("packet too big, %d", packet_len);
-               nc_ensure_sync (dev);
-               return 0;
-       } else if (hdr_len < MIN_HEADER) {
-               dev->stats.rx_frame_errors++;
-               dbg ("header too short, %d", hdr_len);
-               nc_ensure_sync (dev);
-               return 0;
-       } else if (hdr_len > MIN_HEADER) {
-               // out of band data for us?
-               dbg ("header OOB, %d bytes", hdr_len - MIN_HEADER);
-               nc_ensure_sync (dev);
-               // switch (vendor/product ids) { ... }
-       }
-       skb_pull (skb, hdr_len);
-
-       trailer = (struct nc_trailer *)
-               (skb->data + skb->len - sizeof *trailer);
-       skb_trim (skb, skb->len - sizeof *trailer);
-
-       if ((packet_len & 0x01) == 0) {
-               if (skb->data [packet_len] != PAD_BYTE) {
-                       dev->stats.rx_frame_errors++;
-                       dbg ("bad pad");
-                       return 0;
-               }
-               skb_trim (skb, skb->len - 1);
-       }
-       if (skb->len != packet_len) {
-               dev->stats.rx_frame_errors++;
-               dbg ("bad packet len %d (expected %d)",
-                       skb->len, packet_len);
-               nc_ensure_sync (dev);
-               return 0;
-       }
-       if (header->packet_id != get_unaligned (&trailer->packet_id)) {
-               dev->stats.rx_fifo_errors++;
-               dbg ("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
-                       le16_to_cpu (header->packet_id),
-                       le16_to_cpu (trailer->packet_id));
-               return 0;
-       }
-#if 0
-       devdbg (dev, "frame <rx h %d p %d id %d", header->hdr_len,
-               header->packet_len, header->packet_id);
-#endif
-       dev->frame_errors = 0;
-       return 1;
-}
-
-static struct sk_buff *
-net1080_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
-{
-       int                     padlen;
-       struct sk_buff          *skb2;
-
-       padlen = ((skb->len + sizeof (struct nc_header)
-                       + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
-       if (!skb_cloned (skb)) {
-               int     headroom = skb_headroom (skb);
-               int     tailroom = skb_tailroom (skb);
-
-               if ((padlen + sizeof (struct nc_trailer)) <= tailroom
-                           && sizeof (struct nc_header) <= headroom)
-                       /* There's enough head and tail room */
-                       return skb;
-
-               if ((sizeof (struct nc_header) + padlen
-                                       + sizeof (struct nc_trailer)) <
-                               (headroom + tailroom)) {
-                       /* There's enough total room, so just readjust */
-                       skb->data = memmove (skb->head
-                                               + sizeof (struct nc_header),
-                                           skb->data, skb->len);
-                       skb->tail = skb->data + skb->len;
-                       return skb;
-               }
-       }
-
-       /* Create a new skb to use with the correct size */
-       skb2 = skb_copy_expand (skb,
-                               sizeof (struct nc_header),
-                               sizeof (struct nc_trailer) + padlen,
-                               flags);
-       dev_kfree_skb_any (skb);
-       return skb2;
-}
-
-static const struct driver_info        net1080_info = {
-       .description =  "NetChip TurboCONNECT",
-       .flags =        FLAG_FRAMING_NC,
-       .reset =        net1080_reset,
-       .check_connect =net1080_check_connect,
-       .rx_fixup =     net1080_rx_fixup,
-       .tx_fixup =     net1080_tx_fixup,
-};
-
-#endif /* CONFIG_USB_NET1080 */
-
-
-\f
-#ifdef CONFIG_USB_PL2301
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
- *
- * The protocol and handshaking used here should be bug-compatible
- * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
- *
- *-------------------------------------------------------------------------*/
-
-/*
- * Bits 0-4 can be used for software handshaking; they're set from
- * one end, cleared from the other, "read" with the interrupt byte.
- */
-#define        PL_S_EN         (1<<7)          /* (feature only) suspend enable */
-/* reserved bit -- rx ready (6) ? */
-#define        PL_TX_READY     (1<<5)          /* (interrupt only) transmit ready */
-#define        PL_RESET_OUT    (1<<4)          /* reset output pipe */
-#define        PL_RESET_IN     (1<<3)          /* reset input pipe */
-#define        PL_TX_C         (1<<2)          /* transmission complete */
-#define        PL_TX_REQ       (1<<1)          /* transmission received */
-#define        PL_PEER_E       (1<<0)          /* peer exists */
-
-static inline int
-pl_vendor_req (struct usbnet *dev, u8 req, u8 val, u8 index)
-{
-       return usb_control_msg (dev->udev,
-               usb_rcvctrlpipe (dev->udev, 0),
-               req,
-               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               val, index,
-               NULL, 0,
-               CONTROL_TIMEOUT_MS);
-}
-
-static inline int
-pl_clear_QuickLink_features (struct usbnet *dev, int val)
-{
-       return pl_vendor_req (dev, 1, (u8) val, 0);
-}
-
-static inline int
-pl_set_QuickLink_features (struct usbnet *dev, int val)
-{
-       return pl_vendor_req (dev, 3, (u8) val, 0);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int pl_reset (struct usbnet *dev)
-{
-       /* some units seem to need this reset, others reject it utterly.
-        * FIXME be more like "naplink" or windows drivers.
-        */
-       (void) pl_set_QuickLink_features (dev,
-               PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
-       return 0;
-}
-
-static const struct driver_info        prolific_info = {
-       .description =  "Prolific PL-2301/PL-2302",
-       .flags =        FLAG_NO_SETINT,
-               /* some PL-2302 versions seem to fail usb_set_interface() */
-       .reset =        pl_reset,
-};
-
-#endif /* CONFIG_USB_PL2301 */
-
-\f
-#ifdef CONFIG_USB_KC2190
-#define HAVE_HARDWARE
-static const struct driver_info kc2190_info = {
-       .description =  "KC Technology KC-190",
-};
-#endif /* CONFIG_USB_KC2190 */
-
-\f
-#ifdef CONFIG_USB_ARMLINUX
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Intel's SA-1100 chip integrates basic USB support, and is used
- * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
- * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
- * network using minimal USB framing data.
- *
- * This describes the driver currently in standard ARM Linux kernels.
- * The Zaurus uses a different driver (see later).
- *
- * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
- * and different USB endpoint numbering than the SA1100 devices.  The
- * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
- * so we rely on the endpoint descriptors.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info        linuxdev_info = {
-       .description =  "Linux Device",
-       .check_connect = always_connected,
-};
-
-static const struct driver_info        yopy_info = {
-       .description =  "Yopy",
-       .check_connect = always_connected,
-};
-
-static const struct driver_info        blob_info = {
-       .description =  "Boot Loader OBject",
-       .check_connect = always_connected,
-};
-
-#endif /* CONFIG_USB_ARMLINUX */
-
-\f
-#ifdef CONFIG_USB_ZAURUS
-#define        HAVE_HARDWARE
-
-#include <linux/crc32.h>
-
-/*-------------------------------------------------------------------------
- *
- * Zaurus is also a SA-1110 based PDA, but one using a different driver
- * (and framing) for its USB slave/gadget controller than the case above.
- *
- * For the current version of that driver, the main way that framing is
- * nonstandard (also from perspective of the CDC ethernet model!) is a
- * crc32, added to help detect when some sa1100 usb-to-memory DMA errata
- * haven't been fully worked around.  Also, all Zaurii use the same
- * default Ethernet address.
- *
- * PXA based models use the same framing, and also can't implement
- * set_interface properly.
- *
- * All known Zaurii lie about their standards conformance.  Most lie by
- * saying they support CDC Ethernet.  Some lie and say they support CDC
- * MDLM (as if for access to cell phone modems).  Someone, please beat 
- * on Sharp (and other such vendors) for a while with a cluestick.
- *
- *-------------------------------------------------------------------------*/
-
-static struct sk_buff *
-zaurus_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
-{
-       int                     padlen;
-       struct sk_buff          *skb2;
+// between wakeups
+#define UNLINK_TIMEOUT_MS      3
 
-       padlen = 2;
-       if (!skb_cloned (skb)) {
-               int     tailroom = skb_tailroom (skb);
-               if ((padlen + 4) <= tailroom)
-                       goto done;
-       }
-       skb2 = skb_copy_expand (skb, 0, 4 + padlen, flags);
-       dev_kfree_skb_any (skb);
-       skb = skb2;
-       if (skb) {
-               u32             fcs;
-done:
-               fcs = crc32_le (~0, skb->data, skb->len);
-               fcs = ~fcs;
+/*-------------------------------------------------------------------------*/
 
-               *skb_put (skb, 1) = fcs       & 0xff;
-               *skb_put (skb, 1) = (fcs>> 8) & 0xff;
-               *skb_put (skb, 1) = (fcs>>16) & 0xff;
-               *skb_put (skb, 1) = (fcs>>24) & 0xff;
-       }
-       return skb;
-}
+// randomly generated ethernet address
+static u8      node_id [ETH_ALEN];
 
-static const struct driver_info        zaurus_sl5x00_info = {
-       .description =  "Sharp Zaurus SL-5x00",
-       .flags =        FLAG_FRAMING_Z,
-       .check_connect = always_connected,
-       .bind =         generic_cdc_bind,
-       .unbind =       cdc_unbind,
-       .tx_fixup =     zaurus_tx_fixup,
-};
-#define        ZAURUS_STRONGARM_INFO   ((unsigned long)&zaurus_sl5x00_info)
-
-static const struct driver_info        zaurus_pxa_info = {
-       .description =  "Sharp Zaurus, PXA-2xx based",
-       .flags =        FLAG_FRAMING_Z,
-       .check_connect = always_connected,
-       .bind =         generic_cdc_bind,
-       .unbind =       cdc_unbind,
-       .tx_fixup =     zaurus_tx_fixup,
-};
-#define        ZAURUS_PXA_INFO         ((unsigned long)&zaurus_pxa_info)
-
-static const struct driver_info        olympus_mxl_info = {
-       .description =  "Olympus R1000",
-       .flags =        FLAG_FRAMING_Z,
-       .check_connect = always_connected,
-       .bind =         generic_cdc_bind,
-       .unbind =       cdc_unbind,
-       .tx_fixup =     zaurus_tx_fixup,
-};
-#define        OLYMPUS_MXL_INFO        ((unsigned long)&olympus_mxl_info)
+static const char driver_name [] = "usbnet";
 
+/* use ethtool to change the level for any given device */
+static int msg_level = -1;
+module_param (msg_level, int, 0);
+MODULE_PARM_DESC (msg_level, "Override default message level");
 
-/* Some more recent products using Lineo/Belcarra code will wrongly claim
- * CDC MDLM conformance.  They aren't conformant:  data endpoints live
- * in the control interface, there's no data interface, and it's not used
- * to talk to a cell phone radio.  But at least we can detect these two
- * pseudo-classes, rather than growing this product list with entries for
- * each new nonconformant product (sigh).
- */
-static const u8 safe_guid[16] = {
-       0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
-       0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
-};
-static const u8 blan_guid[16] = {
-       0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
-       0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
-};
+/*-------------------------------------------------------------------------*/
 
-static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
+/* handles CDC Ethernet and many other network "bulk data" interfaces */
+int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
 {
-       u8                              *buf = intf->cur_altsetting->extra;
-       int                             len = intf->cur_altsetting->extralen;
-       struct usb_cdc_mdlm_desc        *desc = NULL;
-       struct usb_cdc_mdlm_detail_desc *detail = NULL;
+       int                             tmp;
+       struct usb_host_interface       *alt = NULL;
+       struct usb_host_endpoint        *in = NULL, *out = NULL;
+       struct usb_host_endpoint        *status = NULL;
+
+       for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
+               unsigned        ep;
 
-       while (len > 3) {
-               if (buf [1] != USB_DT_CS_INTERFACE)
-                       goto next_desc;
+               in = out = status = NULL;
+               alt = intf->altsetting + tmp;
 
-               /* use bDescriptorSubType, and just verify that we get a
-                * "BLAN" (or "SAFE") descriptor.
+               /* take the first altsetting with in-bulk + out-bulk;
+                * remember any status endpoint, just in case;
+                * ignore other endpoints and altsetttings.
                 */
-               switch (buf [2]) {
-               case USB_CDC_MDLM_TYPE:
-                       if (desc) {
-                               dev_dbg (&intf->dev, "extra MDLM\n");
-                               goto bad_desc;
-                       }
-                       desc = (void *) buf;
-                       if (desc->bLength != sizeof *desc) {
-                               dev_dbg (&intf->dev, "MDLM len %u\n",
-                                       desc->bLength);
-                               goto bad_desc;
-                       }
-                       /* expect bcdVersion 1.0, ignore */
-                       if (memcmp(&desc->bGUID, blan_guid, 16)
-                                   && memcmp(&desc->bGUID, safe_guid, 16) ) {
-                               /* hey, this one might _really_ be MDLM! */
-                               dev_dbg (&intf->dev, "MDLM guid\n");
-                               goto bad_desc;
-                       }
-                       break;
-               case USB_CDC_MDLM_DETAIL_TYPE:
-                       if (detail) {
-                               dev_dbg (&intf->dev, "extra MDLM detail\n");
-                               goto bad_desc;
-                       }
-                       detail = (void *) buf;
-                       switch (detail->bGuidDescriptorType) {
-                       case 0:                 /* "SAFE" */
-                               if (detail->bLength != (sizeof *detail + 2))
-                                       goto bad_detail;
-                               break;
-                       case 1:                 /* "BLAN" */
-                               if (detail->bLength != (sizeof *detail + 3))
-                                       goto bad_detail;
+               for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
+                       struct usb_host_endpoint        *e;
+                       int                             intr = 0;
+
+                       e = alt->endpoint + ep;
+                       switch (e->desc.bmAttributes) {
+                       case USB_ENDPOINT_XFER_INT:
+                               if (!(e->desc.bEndpointAddress & USB_DIR_IN))
+                                       continue;
+                               intr = 1;
+                               /* FALLTHROUGH */
+                       case USB_ENDPOINT_XFER_BULK:
                                break;
                        default:
-                               goto bad_detail;
+                               continue;
                        }
-
-                       /* assuming we either noticed BLAN already, or will
-                        * find it soon, there are some data bytes here:
-                        *  - bmNetworkCapabilities (unused)
-                        *  - bmDataCapabilities (bits, see below)
-                        *  - bPad (ignored, for PADAFTER -- BLAN-only)
-                        * bits are:
-                        *  - 0x01 -- Zaurus framing (add CRC)
-                        *  - 0x02 -- PADBEFORE (CRC includes some padding)
-                        *  - 0x04 -- PADAFTER (some padding after CRC)
-                        *  - 0x08 -- "fermat" packet mangling (for hw bugs)
-                        * the PADBEFORE appears not to matter; we interop
-                        * with devices that use it and those that don't.
-                        */
-                       if ((detail->bDetailData[1] & ~02) != 0x01) {
-                               /* bmDataCapabilites == 0 would be fine too,
-                                * but framing is minidriver-coupled for now.
-                                */
-bad_detail:
-                               dev_dbg (&intf->dev,
-                                               "bad MDLM detail, %d %d %d\n",
-                                               detail->bLength,
-                                               detail->bDetailData[0],
-                                               detail->bDetailData[2]);
-                               goto bad_desc;
+                       if (e->desc.bEndpointAddress & USB_DIR_IN) {
+                               if (!intr && !in)
+                                       in = e;
+                               else if (intr && !status)
+                                       status = e;
+                       } else {
+                               if (!out)
+                                       out = e;
                        }
-                       break;
                }
-next_desc:
-               len -= buf [0]; /* bLength */
-               buf += buf [0];
+               if (in && out)
+                       break;
        }
+       if (!alt || !in || !out)
+               return -EINVAL;
 
-       if (!desc || !detail) {
-               dev_dbg (&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
-                       desc ? "" : "func ",
-                       detail ? "" : "detail ");
-               goto bad_desc;
+       if (alt->desc.bAlternateSetting != 0
+                       || !(dev->driver_info->flags & FLAG_NO_SETINT)) {
+               tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber,
+                               alt->desc.bAlternateSetting);
+               if (tmp < 0)
+                       return tmp;
        }
+       
+       dev->in = usb_rcvbulkpipe (dev->udev,
+                       in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+       dev->out = usb_sndbulkpipe (dev->udev,
+                       out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+       dev->status = status;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
 
-       /* There's probably a CDC Ethernet descriptor there, but we can't
-        * rely on the Ethernet address it provides since not all vendors
-        * bother to make it unique.  Likewise there's no point in tracking
-        * of the CDC event notifications.
-        */
-       return get_endpoints (dev, intf);
+static void intr_complete (struct urb *urb, struct pt_regs *regs);
 
-bad_desc:
-       dev_info (&dev->udev->dev, "unsupported MDLM descriptors\n");
-       return -ENODEV;
-}
+static int init_status (struct usbnet *dev, struct usb_interface *intf)
+{
+       char            *buf = NULL;
+       unsigned        pipe = 0;
+       unsigned        maxp;
+       unsigned        period;
 
-static const struct driver_info        bogus_mdlm_info = {
-       .description =  "pseudo-MDLM (BLAN) device",
-       .flags =        FLAG_FRAMING_Z,
-       .check_connect = always_connected,
-       .tx_fixup =     zaurus_tx_fixup,
-       .bind =         blan_mdlm_bind,
-};
+       if (!dev->driver_info->status)
+               return 0;
+
+       pipe = usb_rcvintpipe (dev->udev,
+                       dev->status->desc.bEndpointAddress
+                               & USB_ENDPOINT_NUMBER_MASK);
+       maxp = usb_maxpacket (dev->udev, pipe, 0);
+
+       /* avoid 1 msec chatter:  min 8 msec poll rate */
+       period = max ((int) dev->status->desc.bInterval,
+               (dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
+
+       buf = kmalloc (maxp, SLAB_KERNEL);
+       if (buf) {
+               dev->interrupt = usb_alloc_urb (0, SLAB_KERNEL);
+               if (!dev->interrupt) {
+                       kfree (buf);
+                       return -ENOMEM;
+               } else {
+                       usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
+                               buf, maxp, intr_complete, dev, period);
+                       dev_dbg(&intf->dev,
+                               "status ep%din, %d bytes period %d\n",
+                               usb_pipeendpoint(pipe), maxp, period);
+               }
+       }
+       return  0;
+}
 
-#else
+/* Passes this packet up the stack, updating its accounting.
+ * Some link protocols batch packets, so their rx_fixup paths
+ * can return clones as well as just modify the original skb.
+ */
+void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
+{
+       int     status;
 
-/* blacklist all those devices */
-#define        ZAURUS_STRONGARM_INFO   0
-#define        ZAURUS_PXA_INFO         0
-#define        OLYMPUS_MXL_INFO        0
+       skb->dev = dev->net;
+       skb->protocol = eth_type_trans (skb, dev->net);
+       dev->stats.rx_packets++;
+       dev->stats.rx_bytes += skb->len;
 
-#endif
+       if (netif_msg_rx_status (dev))
+               devdbg (dev, "< rx, len %zu, type 0x%x",
+                       skb->len + sizeof (struct ethhdr), skb->protocol);
+       memset (skb->cb, 0, sizeof (struct skb_data));
+       status = netif_rx (skb);
+       if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev))
+               devdbg (dev, "netif_rx status %d", status);
+}
+EXPORT_SYMBOL_GPL(usbnet_skb_return);
 
 \f
 /*-------------------------------------------------------------------------
@@ -2868,22 +230,12 @@ static const struct driver_info  bogus_mdlm_info = {
 static int usbnet_change_mtu (struct net_device *net, int new_mtu)
 {
        struct usbnet   *dev = netdev_priv(net);
+       int             ll_mtu = new_mtu + net->hard_header_len;
 
-       if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
+       if (new_mtu <= 0 || ll_mtu > dev->hard_mtu)
                return -EINVAL;
-#ifdef CONFIG_USB_NET1080
-       if (((dev->driver_info->flags) & FLAG_FRAMING_NC)) {
-               if (FRAMED_SIZE (new_mtu) > MAX_PACKET)
-                       return -EINVAL;
-       }
-#endif
-#ifdef CONFIG_USB_GENESYS
-       if (((dev->driver_info->flags) & FLAG_FRAMING_GL)
-                       && new_mtu > GL_MAX_PACKET_LEN)
-               return -EINVAL;
-#endif
        // no second zero-length packet read wanted after mtu-sized packets
-       if (((new_mtu + sizeof (struct ethhdr)) % dev->maxpacket) == 0)
+       if ((ll_mtu % dev->maxpacket) == 0)
                return -EDOM;
        net->mtu = new_mtu;
        return 0;
@@ -2922,7 +274,7 @@ static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_hea
  * NOTE:  annoying asymmetry:  if it's active, schedule_work() fails,
  * but tasklet_schedule() doesn't.  hope the failure is rare.
  */
-static void defer_kevent (struct usbnet *dev, int work)
+void usbnet_defer_kevent (struct usbnet *dev, int work)
 {
        set_bit (work, &dev->flags);
        if (!schedule_work (&dev->kevent))
@@ -2930,50 +282,24 @@ static void defer_kevent (struct usbnet *dev, int work)
        else
                devdbg (dev, "kevent %d scheduled", work);
 }
+EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
 /*-------------------------------------------------------------------------*/
 
 static void rx_complete (struct urb *urb, struct pt_regs *regs);
 
-static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
+static void rx_submit (struct usbnet *dev, struct urb *urb, unsigned flags)
 {
        struct sk_buff          *skb;
        struct skb_data         *entry;
        int                     retval = 0;
        unsigned long           lockflags;
-       size_t                  size;
-
-#ifdef CONFIG_USB_NET1080
-       if (dev->driver_info->flags & FLAG_FRAMING_NC)
-               size = FRAMED_SIZE (dev->net->mtu);
-       else
-#endif
-#ifdef CONFIG_USB_GENESYS
-       if (dev->driver_info->flags & FLAG_FRAMING_GL)
-               size = GL_RCV_BUF_SIZE;
-       else
-#endif
-#ifdef CONFIG_USB_ZAURUS
-       if (dev->driver_info->flags & FLAG_FRAMING_Z)
-               size = 6 + (sizeof (struct ethhdr) + dev->net->mtu);
-       else
-#endif
-#ifdef CONFIG_USB_RNDIS
-       if (dev->driver_info->flags & FLAG_FRAMING_RN)
-               size = RNDIS_MAX_TRANSFER;
-       else
-#endif
-#ifdef CONFIG_USB_AX8817X
-       if (dev->driver_info->flags & FLAG_FRAMING_AX)
-               size = 2048;
-       else
-#endif
-               size = (sizeof (struct ethhdr) + dev->net->mtu);
+       size_t                  size = dev->rx_urb_size;
 
        if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
                if (netif_msg_rx_err (dev))
                        devdbg (dev, "no rx skb");
-               defer_kevent (dev, EVENT_RX_MEMORY);
+               usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
                usb_free_urb (urb);
                return;
        }
@@ -2987,7 +313,6 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
 
        usb_fill_bulk_urb (urb, dev->udev, dev->in,
                skb->data, size, rx_complete, skb);
-       urb->transfer_flags |= URB_ASYNC_UNLINK;
 
        spin_lock_irqsave (&dev->rxq.lock, lockflags);
 
@@ -2996,10 +321,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
                        && !test_bit (EVENT_RX_HALT, &dev->flags)) {
                switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ 
                case -EPIPE:
-                       defer_kevent (dev, EVENT_RX_HALT);
+                       usbnet_defer_kevent (dev, EVENT_RX_HALT);
                        break;
                case -ENOMEM:
-                       defer_kevent (dev, EVENT_RX_MEMORY);
+                       usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
                        break;
                case -ENODEV:
                        if (netif_msg_ifdown (dev))
@@ -3037,7 +362,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
        // else network stack removes extra byte if we forced a short packet
 
        if (skb->len)
-               skb_return (dev, skb);
+               usbnet_skb_return (dev, skb);
        else {
                if (netif_msg_rx_err (dev))
                        devdbg (dev, "drop");
@@ -3063,7 +388,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
        switch (urb_status) {
            // success
            case 0:
-               if (MIN_PACKET > skb->len || skb->len > MAX_PACKET) {
+               if (skb->len < dev->net->hard_header_len) {
                        entry->state = rx_cleanup;
                        dev->stats.rx_errors++;
                        dev->stats.rx_length_errors++;
@@ -3078,7 +403,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
            // storm, recovering as needed.
            case -EPIPE:
                dev->stats.rx_errors++;
-               defer_kevent (dev, EVENT_RX_HALT);
+               usbnet_defer_kevent (dev, EVENT_RX_HALT);
                // FALLTHROUGH
 
            // software-driven interface shutdown
@@ -3320,55 +645,58 @@ done:
 
 /*-------------------------------------------------------------------------*/
 
-static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+/* ethtool methods; minidrivers may need to add some more, but
+ * they'll probably want to use this base set.
+ */
+
+void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
 {
        struct usbnet *dev = netdev_priv(net);
 
+       /* REVISIT don't always return "usbnet" */
        strncpy (info->driver, driver_name, sizeof info->driver);
        strncpy (info->version, DRIVER_VERSION, sizeof info->version);
        strncpy (info->fw_version, dev->driver_info->description,
                sizeof info->fw_version);
        usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
 }
+EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
 
 static u32 usbnet_get_link (struct net_device *net)
 {
        struct usbnet *dev = netdev_priv(net);
 
-       /* If a check_connect is defined, return it's results */
+       /* If a check_connect is defined, return its result */
        if (dev->driver_info->check_connect)
                return dev->driver_info->check_connect (dev) == 0;
 
-       /* Otherwise, we're up to avoid breaking scripts */
+       /* Otherwise, say we're up (to avoid breaking scripts) */
        return 1;
 }
 
-static u32 usbnet_get_msglevel (struct net_device *net)
+u32 usbnet_get_msglevel (struct net_device *net)
 {
        struct usbnet *dev = netdev_priv(net);
 
        return dev->msg_enable;
 }
+EXPORT_SYMBOL_GPL(usbnet_get_msglevel);
 
-static void usbnet_set_msglevel (struct net_device *net, u32 level)
+void usbnet_set_msglevel (struct net_device *net, u32 level)
 {
        struct usbnet *dev = netdev_priv(net);
 
        dev->msg_enable = level;
 }
+EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
 
-static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
-{
-#ifdef NEED_MII
-       {
-       struct usbnet *dev = netdev_priv(net);
-
-       if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
-               return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
-       }
-#endif
-       return -EOPNOTSUPP;
-}
+/* drivers may override default ethtool_ops in their bind() routine */
+static struct ethtool_ops usbnet_ethtool_ops = {
+       .get_drvinfo            = usbnet_get_drvinfo,
+       .get_link               = usbnet_get_link,
+       .get_msglevel           = usbnet_get_msglevel,
+       .set_msglevel           = usbnet_set_msglevel,
+};
 
 /*-------------------------------------------------------------------------*/
 
@@ -3387,19 +715,24 @@ kevent (void *data)
        if (test_bit (EVENT_TX_HALT, &dev->flags)) {
                unlink_urbs (dev, &dev->txq);
                status = usb_clear_halt (dev->udev, dev->out);
-               if (status < 0 && status != -EPIPE) {
+               if (status < 0
+                               && status != -EPIPE
+                               && status != -ESHUTDOWN) {
                        if (netif_msg_tx_err (dev))
                                deverr (dev, "can't clear tx halt, status %d",
                                        status);
                } else {
                        clear_bit (EVENT_TX_HALT, &dev->flags);
-                       netif_wake_queue (dev->net);
+                       if (status != -ESHUTDOWN)
+                               netif_wake_queue (dev->net);
                }
        }
        if (test_bit (EVENT_RX_HALT, &dev->flags)) {
                unlink_urbs (dev, &dev->rxq);
                status = usb_clear_halt (dev->udev, dev->in);
-               if (status < 0 && status != -EPIPE) {
+               if (status < 0
+                               && status != -EPIPE
+                               && status != -ESHUTDOWN) {
                        if (netif_msg_rx_err (dev))
                                deverr (dev, "can't clear rx halt, status %d",
                                        status);
@@ -3458,7 +791,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
 
                switch (urb->status) {
                case -EPIPE:
-                       defer_kevent (dev, EVENT_TX_HALT);
+                       usbnet_defer_kevent (dev, EVENT_TX_HALT);
                        break;
 
                /* software-driven interface shutdown */
@@ -3515,10 +848,6 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
        struct skb_data         *entry;
        struct driver_info      *info = dev->driver_info;
        unsigned long           flags;
-#ifdef CONFIG_USB_NET1080
-       struct nc_header        *header = NULL;
-       struct nc_trailer       *trailer = NULL;
-#endif /* CONFIG_USB_NET1080 */
 
        // some devices want funky USB-level framing, for
        // win32 driver (usually) and/or hardware quirks
@@ -3544,24 +873,8 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
        entry->state = tx_start;
        entry->length = length;
 
-       // FIXME: reorganize a bit, so that fixup() fills out NetChip
-       // framing too. (Packet ID update needs the spinlock...)
-       // [ BETTER:  we already own net->xmit_lock, that's enough ]
-
-#ifdef CONFIG_USB_NET1080
-       if (info->flags & FLAG_FRAMING_NC) {
-               header = (struct nc_header *) skb_push (skb, sizeof *header);
-               header->hdr_len = cpu_to_le16 (sizeof (*header));
-               header->packet_len = cpu_to_le16 (length);
-               if (!((skb->len + sizeof *trailer) & 0x01))
-                       *skb_put (skb, 1) = PAD_BYTE;
-               trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
-       }
-#endif /* CONFIG_USB_NET1080 */
-
        usb_fill_bulk_urb (urb, dev->udev, dev->out,
                        skb->data, skb->len, tx_complete, skb);
-       urb->transfer_flags |= URB_ASYNC_UNLINK;
 
        /* don't assume the hardware handles USB_ZERO_PACKET
         * NOTE:  strictly conforming cdc-ether devices should expect
@@ -3574,22 +887,10 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
 
        spin_lock_irqsave (&dev->txq.lock, flags);
 
-#ifdef CONFIG_USB_NET1080
-       if (info->flags & FLAG_FRAMING_NC) {
-               header->packet_id = cpu_to_le16 ((u16)dev->dev_packet_id++);
-               put_unaligned (header->packet_id, &trailer->packet_id);
-#if 0
-               devdbg (dev, "frame >tx h %d p %d id %d",
-                       header->hdr_len, header->packet_len,
-                       header->packet_id);
-#endif
-       }
-#endif /* CONFIG_USB_NET1080 */
-
        switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
        case -EPIPE:
                netif_stop_queue (net);
-               defer_kevent (dev, EVENT_TX_HALT);
+               usbnet_defer_kevent (dev, EVENT_TX_HALT);
                break;
        default:
                if (netif_msg_tx_err (dev))
@@ -3692,7 +993,7 @@ static void usbnet_bh (unsigned long param)
  
 // precondition: never called in_interrupt
 
-static void usbnet_disconnect (struct usb_interface *intf)
+void usbnet_disconnect (struct usb_interface *intf)
 {
        struct usbnet           *dev;
        struct usb_device       *xdev;
@@ -3706,7 +1007,8 @@ static void usbnet_disconnect (struct usb_interface *intf)
        xdev = interface_to_usbdev (intf);
 
        if (netif_msg_probe (dev))
-               devinfo (dev, "unregister usbnet usb-%s-%s, %s",
+               devinfo (dev, "unregister '%s' usb-%s-%s, %s",
+                       intf->dev.driver->name,
                        xdev->bus->bus_name, xdev->devpath,
                        dev->driver_info->description);
        
@@ -3722,15 +1024,14 @@ static void usbnet_disconnect (struct usb_interface *intf)
        free_netdev(net);
        usb_put_dev (xdev);
 }
+EXPORT_SYMBOL_GPL(usbnet_disconnect);
 
 
 /*-------------------------------------------------------------------------*/
 
-static struct ethtool_ops usbnet_ethtool_ops;
-
 // precondition: never called in_interrupt
 
-static int
+int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
        struct usbnet                   *dev;
@@ -3779,6 +1080,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        strcpy (net->name, "usb%d");
        memcpy (net->dev_addr, node_id, sizeof node_id);
 
+       /* rx and tx sides can use different message sizes;
+        * bind() should set rx_urb_size in that case.
+        */
+       dev->hard_mtu = net->mtu + net->hard_header_len;
 #if 0
 // dma_supported() is deeply broken on almost all architectures
        // possible with some EHCI controllers
@@ -3793,7 +1098,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        net->stop = usbnet_stop;
        net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
        net->tx_timeout = usbnet_tx_timeout;
-       net->do_ioctl = usbnet_ioctl;
        net->ethtool_ops = &usbnet_ethtool_ops;
 
        // allow device-specific bind/init procedures
@@ -3806,8 +1110,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
                if ((dev->driver_info->flags & FLAG_ETHER) != 0
                                && (net->dev_addr [0] & 0x02) == 0)
                        strcpy (net->name, "eth%d");
-       } else if (!info->in || info->out)
-               status = get_endpoints (dev, udev);
+
+               /* maybe the remote can't receive an Ethernet MTU */
+               if (net->mtu > (dev->hard_mtu - net->hard_header_len))
+                       net->mtu = dev->hard_mtu - net->hard_header_len;
+       } else if (!info->in || !info->out)
+               status = usbnet_get_endpoints (dev, udev);
        else {
                dev->in = usb_rcvbulkpipe (xdev, info->in);
                dev->out = usb_sndbulkpipe (xdev, info->out);
@@ -3819,12 +1127,13 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
                        status = 0;
 
        }
-
        if (status == 0 && dev->status)
                status = init_status (dev, udev);
        if (status < 0)
                goto out1;
 
+       if (!dev->rx_urb_size)
+               dev->rx_urb_size = dev->hard_mtu;
        dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
        
        SET_NETDEV_DEV(net, &udev->dev);
@@ -3832,8 +1141,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        if (status)
                goto out3;
        if (netif_msg_probe (dev))
-               devinfo (dev, "register usbnet at usb-%s-%s, %s, "
+               devinfo (dev, "register '%s' at usb-%s-%s, %s, "
                                "%02x:%02x:%02x:%02x:%02x:%02x",
+                       udev->dev.driver->name,
                        xdev->bus->bus_name, xdev->devpath,
                        dev->driver_info->description,
                        net->dev_addr [0], net->dev_addr [1],
@@ -3857,12 +1167,15 @@ out:
        usb_put_dev(xdev);
        return status;
 }
+EXPORT_SYMBOL_GPL(usbnet_probe);
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_PM
+/* FIXME these suspend/resume methods assume non-CDC style
+ * devices, with only one interface.
+ */
 
-static int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
+int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
        
@@ -3875,8 +1188,9 @@ static int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
        intf->dev.power.power_state = PMSG_SUSPEND;
        return 0;
 }
+EXPORT_SYMBOL_GPL(usbnet_suspend);
 
-static int usbnet_resume (struct usb_interface *intf)
+int usbnet_resume (struct usb_interface *intf)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
 
@@ -3885,357 +1199,27 @@ static int usbnet_resume (struct usb_interface *intf)
        tasklet_schedule (&dev->bh);
        return 0;
 }
+EXPORT_SYMBOL_GPL(usbnet_resume);
 
-#else  /* !CONFIG_PM */
-
-#define        usbnet_suspend  NULL
-#define        usbnet_resume   NULL
-
-#endif /* CONFIG_PM */
-
-/*-------------------------------------------------------------------------*/
-
-#ifndef        HAVE_HARDWARE
-#error You need to configure some hardware for this driver
-#endif
-
-/*
- * chip vendor names won't normally be on the cables, and
- * may not be on the device.
- */
-
-static const struct usb_device_id      products [] = {
-
-#ifdef CONFIG_USB_ALI_M5632
-{
-       USB_DEVICE (0x0402, 0x5632),    // ALi defaults
-       .driver_info =  (unsigned long) &ali_m5632_info,
-},
-#endif
-
-#ifdef CONFIG_USB_AN2720
-{
-       USB_DEVICE (0x0547, 0x2720),    // AnchorChips defaults
-       .driver_info =  (unsigned long) &an2720_info,
-}, {
-       USB_DEVICE (0x0547, 0x2727),    // Xircom PGUNET
-       .driver_info =  (unsigned long) &an2720_info,
-},
-#endif
-
-#ifdef CONFIG_USB_BELKIN
-{
-       USB_DEVICE (0x050d, 0x0004),    // Belkin
-       .driver_info =  (unsigned long) &belkin_info,
-}, {
-       USB_DEVICE (0x056c, 0x8100),    // eTEK
-       .driver_info =  (unsigned long) &belkin_info,
-}, {
-       USB_DEVICE (0x0525, 0x9901),    // Advance USBNET (eTEK)
-       .driver_info =  (unsigned long) &belkin_info,
-},
-#endif
-
-#ifdef CONFIG_USB_AX8817X
-{
-       // Linksys USB200M
-       USB_DEVICE (0x077b, 0x2226),
-       .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // Netgear FA120
-       USB_DEVICE (0x0846, 0x1040),
-       .driver_info =  (unsigned long) &netgear_fa120_info,
-}, {
-       // DLink DUB-E100
-       USB_DEVICE (0x2001, 0x1a00),
-       .driver_info =  (unsigned long) &dlink_dub_e100_info,
-}, {
-       // Intellinet, ST Lab USB Ethernet
-       USB_DEVICE (0x0b95, 0x1720),
-       .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // Hawking UF200, TrendNet TU2-ET100
-       USB_DEVICE (0x07b8, 0x420a),
-       .driver_info =  (unsigned long) &hawking_uf200_info,
-}, {
-        // Billionton Systems, USB2AR 
-        USB_DEVICE (0x08dd, 0x90ff),
-        .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // ATEN UC210T
-       USB_DEVICE (0x0557, 0x2009),
-       .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // Buffalo LUA-U2-KTX
-       USB_DEVICE (0x0411, 0x003d),
-       .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
-       USB_DEVICE (0x6189, 0x182d),
-       .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // corega FEther USB2-TX
-       USB_DEVICE (0x07aa, 0x0017),
-       .driver_info =  (unsigned long) &ax8817x_info,
-}, {
-       // Surecom EP-1427X-2
-       USB_DEVICE (0x1189, 0x0893),
-       .driver_info = (unsigned long) &ax8817x_info,
-}, {
-       // goodway corp usb gwusb2e
-       USB_DEVICE (0x1631, 0x6200),
-       .driver_info = (unsigned long) &ax8817x_info,
-}, {
-       // ASIX AX88772 10/100
-        USB_DEVICE (0x0b95, 0x7720),
-        .driver_info = (unsigned long) &ax88772_info,
-},
-#endif
-
-#ifdef CONFIG_USB_EPSON2888
-{
-       USB_DEVICE (0x0525, 0x2888),    // EPSON USB client
-       .driver_info    = (unsigned long) &epson2888_info,
-},
-#endif
-
-#ifdef CONFIG_USB_GENESYS
-{
-       USB_DEVICE (0x05e3, 0x0502),    // GL620USB-A
-       .driver_info =  (unsigned long) &genelink_info,
-},
-       /* NOT: USB_DEVICE (0x05e3, 0x0501),    // GL620USB
-        * that's half duplex, not currently supported
-        */
-#endif
-
-#ifdef CONFIG_USB_NET1080
-{
-       USB_DEVICE (0x0525, 0x1080),    // NetChip ref design
-       .driver_info =  (unsigned long) &net1080_info,
-}, {
-       USB_DEVICE (0x06D0, 0x0622),    // Laplink Gold
-       .driver_info =  (unsigned long) &net1080_info,
-},
-#endif
-
-#ifdef CONFIG_USB_PL2301
-{
-       USB_DEVICE (0x067b, 0x0000),    // PL-2301
-       .driver_info =  (unsigned long) &prolific_info,
-}, {
-       USB_DEVICE (0x067b, 0x0001),    // PL-2302
-       .driver_info =  (unsigned long) &prolific_info,
-},
-#endif
-
-#ifdef CONFIG_USB_KC2190
-{
-       USB_DEVICE (0x050f, 0x0190),    // KC-190
-       .driver_info =  (unsigned long) &kc2190_info,
-},
-#endif
-
-#ifdef CONFIG_USB_RNDIS
-{
-       /* RNDIS is MSFT's un-official variant of CDC ACM */
-       USB_INTERFACE_INFO (USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
-       .driver_info = (unsigned long) &rndis_info,
-},
-#endif
-
-#ifdef CONFIG_USB_ARMLINUX
-/*
- * SA-1100 using standard ARM Linux kernels, or compatible.
- * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
- * The sa-1100 "usb-eth" driver handles the basic framing.
- *
- * PXA25x or PXA210 ...  these use a "usb-eth" driver much like
- * the sa1100 one, but hardware uses different endpoint numbers.
- *
- * Or the Linux "Ethernet" gadget on hardware that can't talk
- * CDC Ethernet (e.g., no altsettings), in either of two modes:
- *  - acting just like the old "usb-eth" firmware, though
- *    the implementation is different 
- *  - supporting RNDIS as the first/default configuration for
- *    MS-Windows interop; Linux needs to use the other config
- */
-{
-       // 1183 = 0x049F, both used as hex values?
-       // Compaq "Itsy" vendor/product id
-       USB_DEVICE (0x049F, 0x505A),    // usb-eth, or compatible
-       .driver_info =  (unsigned long) &linuxdev_info,
-}, {
-       USB_DEVICE (0x0E7E, 0x1001),    // G.Mate "Yopy"
-       .driver_info =  (unsigned long) &yopy_info,
-}, {
-       USB_DEVICE (0x8086, 0x07d3),    // "blob" bootloader
-       .driver_info =  (unsigned long) &blob_info,
-}, {
-       // Linux Ethernet/RNDIS gadget on pxa210/25x/26x
-       // e.g. Gumstix, current OpenZaurus, ...
-       USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
-       .driver_info =  (unsigned long) &linuxdev_info,
-}, 
-#endif
-
-#if    defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER)
-/*
- * SA-1100 based Sharp Zaurus ("collie"), or compatible.
- * Same idea as above, but different framing.
- *
- * PXA-2xx based models are also lying-about-cdc.
- * Some models don't even tell the same lies ...
- *
- * NOTE:  OpenZaurus versions with 2.6 kernels won't use these entries,
- * unlike the older ones with 2.4 "embedix" kernels.
- *
- * NOTE:  These entries do double-duty, serving as blacklist entries
- * whenever Zaurus support isn't enabled, but CDC Ethernet is.
- */
-#define        ZAURUS_MASTER_INTERFACE \
-       .bInterfaceClass        = USB_CLASS_COMM, \
-       .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET, \
-       .bInterfaceProtocol     = USB_CDC_PROTO_NONE
-{
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                         | USB_DEVICE_ID_MATCH_DEVICE, 
-       .idVendor               = 0x04DD,
-       .idProduct              = 0x8004,
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_STRONGARM_INFO,
-}, {
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                         | USB_DEVICE_ID_MATCH_DEVICE, 
-       .idVendor               = 0x04DD,
-       .idProduct              = 0x8005,       /* A-300 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_PXA_INFO,
-}, {
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                         | USB_DEVICE_ID_MATCH_DEVICE, 
-       .idVendor               = 0x04DD,
-       .idProduct              = 0x8006,       /* B-500/SL-5600 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_PXA_INFO,
-}, {
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                 | USB_DEVICE_ID_MATCH_DEVICE,
-       .idVendor               = 0x04DD,
-       .idProduct              = 0x8007,       /* C-700 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_PXA_INFO,
-}, {
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                | USB_DEVICE_ID_MATCH_DEVICE,
-       .idVendor               = 0x04DD,
-       .idProduct              = 0x9031,       /* C-750 C-760 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_PXA_INFO,
-}, {
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                | USB_DEVICE_ID_MATCH_DEVICE,
-       .idVendor               = 0x04DD,
-       .idProduct              = 0x9032,       /* SL-6000 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_PXA_INFO,
-}, {
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                | USB_DEVICE_ID_MATCH_DEVICE,
-       .idVendor               = 0x04DD,
-       /* reported with some C860 units */
-       .idProduct              = 0x9050,       /* C-860 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = ZAURUS_PXA_INFO,
-},
-
-#ifdef CONFIG_USB_ZAURUS
-       /* At least some (reports vary) PXA units have very different lies
-        * about their standards support:  they claim to be cell phones with
-        * direct access to their radios.  (They don't conform to CDC MDLM.)
-        */
-{
-       USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
-                       USB_CDC_PROTO_NONE),
-       .driver_info = (unsigned long) &bogus_mdlm_info,
-},
-#endif
-
-/* Olympus has some models with a Zaurus-compatible option.
- * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
- */
-{
-       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
-                | USB_DEVICE_ID_MATCH_DEVICE,
-       .idVendor               = 0x07B4,
-       .idProduct              = 0x0F02,       /* R-1000 */
-       ZAURUS_MASTER_INTERFACE,
-       .driver_info = OLYMPUS_MXL_INFO,
-},
-#endif
-
-#ifdef CONFIG_USB_CDCETHER
-{
-       /* CDC Ether uses two interfaces, not necessarily consecutive.
-        * We match the main interface, ignoring the optional device
-        * class so we could handle devices that aren't exclusively
-        * CDC ether.
-        *
-        * NOTE:  this match must come AFTER entries working around
-        * bugs/quirks in a given product (like Zaurus, above).
-        */
-       USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
-                       USB_CDC_PROTO_NONE),
-       .driver_info = (unsigned long) &cdc_info,
-},
-#endif
-
-       { },            // END
-};
-MODULE_DEVICE_TABLE (usb, products);
-
-static struct usb_driver usbnet_driver = {
-       .owner =        THIS_MODULE,
-       .name =         driver_name,
-       .id_table =     products,
-       .probe =        usbnet_probe,
-       .disconnect =   usbnet_disconnect,
-       .suspend =      usbnet_suspend,
-       .resume =       usbnet_resume,
-};
-
-/* Default ethtool_ops assigned.  Devices can override in their bind() routine */
-static struct ethtool_ops usbnet_ethtool_ops = {
-       .get_drvinfo            = usbnet_get_drvinfo,
-       .get_link               = usbnet_get_link,
-       .get_msglevel           = usbnet_get_msglevel,
-       .set_msglevel           = usbnet_set_msglevel,
-};
 
 /*-------------------------------------------------------------------------*/
 
-static int __init usbnet_init (void)
+static int __init usbnet_init(void)
 {
-       // compiler should optimize these out
+       /* compiler should optimize this out */
        BUG_ON (sizeof (((struct sk_buff *)0)->cb)
                        < sizeof (struct skb_data));
-#ifdef CONFIG_USB_CDCETHER
-       BUG_ON ((sizeof (((struct usbnet *)0)->data)
-                       < sizeof (struct cdc_state)));
-#endif
 
        random_ether_addr(node_id);
-
-       return usb_register(&usbnet_driver);
+       return 0;
 }
-module_init (usbnet_init);
+module_init(usbnet_init);
 
-static void __exit usbnet_exit (void)
+static void __exit usbnet_exit(void)
 {
-       usb_deregister (&usbnet_driver);
 }
-module_exit (usbnet_exit);
+module_exit(usbnet_exit);
 
-MODULE_AUTHOR ("David Brownell <dbrownell@users.sourceforge.net>");
-MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (numerous vendors)");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("USB network driver framework");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h
new file mode 100644 (file)
index 0000000..7aa0abd
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * USB Networking Link Interface
+ *
+ * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ *
+ * 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-1307  USA
+ */
+
+
+#ifndef        __USBNET_H
+#define        __USBNET_H
+
+
+/* interface from usbnet core to each USB networking link we handle */
+struct usbnet {
+       /* housekeeping */
+       struct usb_device       *udev;
+       struct driver_info      *driver_info;
+       wait_queue_head_t       *wait;
+
+       /* i/o info: pipes etc */
+       unsigned                in, out;
+       struct usb_host_endpoint *status;
+       unsigned                maxpacket;
+       struct timer_list       delay;
+
+       /* protocol/interface state */
+       struct net_device       *net;
+       struct net_device_stats stats;
+       int                     msg_enable;
+       unsigned long           data [5];
+       u32                     xid;
+       u32                     hard_mtu;       /* count any extra framing */
+       size_t                  rx_urb_size;    /* size for rx urbs  */
+       struct mii_if_info      mii;
+
+       /* various kinds of pending driver work */
+       struct sk_buff_head     rxq;
+       struct sk_buff_head     txq;
+       struct sk_buff_head     done;
+       struct urb              *interrupt;
+       struct tasklet_struct   bh;
+
+       struct work_struct      kevent;
+       unsigned long           flags;
+#              define EVENT_TX_HALT    0
+#              define EVENT_RX_HALT    1
+#              define EVENT_RX_MEMORY  2
+#              define EVENT_STS_SPLIT  3
+#              define EVENT_LINK_RESET 4
+};
+
+static inline struct usb_driver *driver_of(struct usb_interface *intf)
+{
+       return to_usb_driver(intf->dev.driver);
+}
+
+/* interface from the device/framing level "minidriver" to core */
+struct driver_info {
+       char            *description;
+
+       int             flags;
+/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
+#define FLAG_FRAMING_NC        0x0001          /* guard against device dropouts */
+#define FLAG_FRAMING_GL        0x0002          /* genelink batches packets */
+#define FLAG_FRAMING_Z 0x0004          /* zaurus adds a trailer */
+#define FLAG_FRAMING_RN        0x0008          /* RNDIS batches, plus huge header */
+
+#define FLAG_NO_SETINT 0x0010          /* device can't set_interface() */
+#define FLAG_ETHER     0x0020          /* maybe use "eth%d" names */
+
+#define FLAG_FRAMING_AX 0x0040          /* AX88772/178 packets */
+
+       /* init device ... can sleep, or cause probe() failure */
+       int     (*bind)(struct usbnet *, struct usb_interface *);
+
+       /* cleanup device ... can sleep, but can't fail */
+       void    (*unbind)(struct usbnet *, struct usb_interface *);
+
+       /* reset device ... can sleep */
+       int     (*reset)(struct usbnet *);
+
+       /* see if peer is connected ... can sleep */
+       int     (*check_connect)(struct usbnet *);
+
+       /* for status polling */
+       void    (*status)(struct usbnet *, struct urb *);
+
+       /* link reset handling, called from defer_kevent */
+       int     (*link_reset)(struct usbnet *);
+
+       /* fixup rx packet (strip framing) */
+       int     (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
+
+       /* fixup tx packet (add framing) */
+       struct sk_buff  *(*tx_fixup)(struct usbnet *dev,
+                               struct sk_buff *skb, unsigned flags);
+
+       /* for new devices, use the descriptor-reading code instead */
+       int             in;             /* rx endpoint */
+       int             out;            /* tx endpoint */
+
+       unsigned long   data;           /* Misc driver specific data */
+};
+
+/* Minidrivers are just drivers using the "usbnet" core as a powerful
+ * network-specific subroutine library ... that happens to do pretty
+ * much everything except custom framing and chip-specific stuff.
+ */
+extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
+extern int usbnet_suspend (struct usb_interface *, pm_message_t );
+extern int usbnet_resume (struct usb_interface *);
+extern void usbnet_disconnect(struct usb_interface *);
+
+
+/* Drivers that reuse some of the standard USB CDC infrastructure
+ * (notably, using multiple interfaces according to the the CDC
+ * union descriptor) get some helper code.
+ */
+struct cdc_state {
+       struct usb_cdc_header_desc      *header;
+       struct usb_cdc_union_desc       *u;
+       struct usb_cdc_ether_desc       *ether;
+       struct usb_interface            *control;
+       struct usb_interface            *data;
+};
+
+extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
+
+/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
+#define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
+                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+                       |USB_CDC_PACKET_TYPE_DIRECTED)
+
+
+/* we record the state for each of our queued skbs */
+enum skb_state {
+       illegal = 0,
+       tx_start, tx_done,
+       rx_start, rx_done, rx_cleanup
+};
+
+struct skb_data {      /* skb->cb is one of these */
+       struct urb              *urb;
+       struct usbnet           *dev;
+       enum skb_state          state;
+       size_t                  length;
+};
+
+
+extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
+extern void usbnet_defer_kevent (struct usbnet *, int);
+extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
+
+extern u32 usbnet_get_msglevel (struct net_device *);
+extern void usbnet_set_msglevel (struct net_device *, u32);
+extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
+
+/* messaging support includes the interface name, so it must not be
+ * used before it has one ... notably, in minidriver bind() calls.
+ */
+#ifdef DEBUG
+#define devdbg(usbnet, fmt, arg...) \
+       printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+#else
+#define devdbg(usbnet, fmt, arg...) do {} while(0)
+#endif
+
+#define deverr(usbnet, fmt, arg...) \
+       printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+#define devwarn(usbnet, fmt, arg...) \
+       printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+
+#define devinfo(usbnet, fmt, arg...) \
+       printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
+
+
+#endif /* __USBNET_H */
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
new file mode 100644 (file)
index 0000000..ee3b892
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
+ * Copyright (C) 2002-2005 by David Brownell
+ *
+ * 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-1307  USA
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+#include <linux/usb.h>
+#include <linux/usb_cdc.h>
+
+#include "usbnet.h"
+
+
+/*
+ * All known Zaurii lie about their standards conformance.  At least
+ * the earliest SA-1100 models lie by saying they support CDC Ethernet.
+ * Some later models (especially PXA-25x and PXA-27x based ones) lie
+ * and say they support CDC MDLM (for access to cell phone modems).
+ *
+ * There are non-Zaurus products that use these same protocols too.
+ *
+ * The annoying thing is that at the same time Sharp was developing
+ * that annoying standards-breaking software, the Linux community had
+ * a simple "CDC Subset" working reliably on the same SA-1100 hardware.
+ * That is, the same functionality but not violating standards.
+ *
+ * The CDC Ethernet nonconformance points are troublesome to hosts
+ * with a true CDC Ethernet implementation:
+ *   - Framing appends a CRC, which the spec says drivers "must not" do;
+ *   - Transfers data in altsetting zero, instead of altsetting 1;
+ *   - All these peripherals use the same ethernet address.
+ *
+ * The CDC MDLM nonconformance is less immediately troublesome, since all
+ * MDLM implementations are quasi-proprietary anyway.
+ */
+
+static struct sk_buff *
+zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+       int                     padlen;
+       struct sk_buff          *skb2;
+
+       padlen = 2;
+       if (!skb_cloned(skb)) {
+               int     tailroom = skb_tailroom(skb);
+               if ((padlen + 4) <= tailroom)
+                       goto done;
+       }
+       skb2 = skb_copy_expand(skb, 0, 4 + padlen, flags);
+       dev_kfree_skb_any(skb);
+       skb = skb2;
+       if (skb) {
+               u32             fcs;
+done:
+               fcs = crc32_le(~0, skb->data, skb->len);
+               fcs = ~fcs;
+
+               *skb_put (skb, 1) = fcs       & 0xff;
+               *skb_put (skb, 1) = (fcs>> 8) & 0xff;
+               *skb_put (skb, 1) = (fcs>>16) & 0xff;
+               *skb_put (skb, 1) = (fcs>>24) & 0xff;
+       }
+       return skb;
+}
+
+static int zaurus_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       /* Belcarra's funky framing has other options; mostly
+        * TRAILERS (!) with 4 bytes CRC, and maybe 2 pad bytes.
+        */
+       dev->net->hard_header_len += 6;
+       dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
+       return usbnet_generic_cdc_bind(dev, intf);
+}
+
+/* PDA style devices are always connected if present */
+static int always_connected (struct usbnet *dev)
+{
+       return 0;
+}
+
+static const struct driver_info        zaurus_sl5x00_info = {
+       .description =  "Sharp Zaurus SL-5x00",
+       .flags =        FLAG_FRAMING_Z,
+       .check_connect = always_connected,
+       .bind =         zaurus_bind,
+       .unbind =       usbnet_cdc_unbind,
+       .tx_fixup =     zaurus_tx_fixup,
+};
+#define        ZAURUS_STRONGARM_INFO   ((unsigned long)&zaurus_sl5x00_info)
+
+static const struct driver_info        zaurus_pxa_info = {
+       .description =  "Sharp Zaurus, PXA-2xx based",
+       .flags =        FLAG_FRAMING_Z,
+       .check_connect = always_connected,
+       .bind =         zaurus_bind,
+       .unbind =       usbnet_cdc_unbind,
+       .tx_fixup =     zaurus_tx_fixup,
+};
+#define        ZAURUS_PXA_INFO         ((unsigned long)&zaurus_pxa_info)
+
+static const struct driver_info        olympus_mxl_info = {
+       .description =  "Olympus R1000",
+       .flags =        FLAG_FRAMING_Z,
+       .check_connect = always_connected,
+       .bind =         zaurus_bind,
+       .unbind =       usbnet_cdc_unbind,
+       .tx_fixup =     zaurus_tx_fixup,
+};
+#define        OLYMPUS_MXL_INFO        ((unsigned long)&olympus_mxl_info)
+
+
+/* Some more recent products using Lineo/Belcarra code will wrongly claim
+ * CDC MDLM conformance.  They aren't conformant:  data endpoints live
+ * in the control interface, there's no data interface, and it's not used
+ * to talk to a cell phone radio.  But at least we can detect these two
+ * pseudo-classes, rather than growing this product list with entries for
+ * each new nonconformant product (sigh).
+ */
+static const u8 safe_guid[16] = {
+       0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
+       0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
+};
+static const u8 blan_guid[16] = {
+       0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
+       0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
+};
+
+static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u8                              *buf = intf->cur_altsetting->extra;
+       int                             len = intf->cur_altsetting->extralen;
+       struct usb_cdc_mdlm_desc        *desc = NULL;
+       struct usb_cdc_mdlm_detail_desc *detail = NULL;
+
+       while (len > 3) {
+               if (buf [1] != USB_DT_CS_INTERFACE)
+                       goto next_desc;
+
+               /* use bDescriptorSubType, and just verify that we get a
+                * "BLAN" (or "SAFE") descriptor.
+                */
+               switch (buf [2]) {
+               case USB_CDC_MDLM_TYPE:
+                       if (desc) {
+                               dev_dbg(&intf->dev, "extra MDLM\n");
+                               goto bad_desc;
+                       }
+                       desc = (void *) buf;
+                       if (desc->bLength != sizeof *desc) {
+                               dev_dbg(&intf->dev, "MDLM len %u\n",
+                                       desc->bLength);
+                               goto bad_desc;
+                       }
+                       /* expect bcdVersion 1.0, ignore */
+                       if (memcmp(&desc->bGUID, blan_guid, 16)
+                                   && memcmp(&desc->bGUID, safe_guid, 16) ) {
+                               /* hey, this one might _really_ be MDLM! */
+                               dev_dbg(&intf->dev, "MDLM guid\n");
+                               goto bad_desc;
+                       }
+                       break;
+               case USB_CDC_MDLM_DETAIL_TYPE:
+                       if (detail) {
+                               dev_dbg(&intf->dev, "extra MDLM detail\n");
+                               goto bad_desc;
+                       }
+                       detail = (void *) buf;
+                       switch (detail->bGuidDescriptorType) {
+                       case 0:                 /* "SAFE" */
+                               if (detail->bLength != (sizeof *detail + 2))
+                                       goto bad_detail;
+                               break;
+                       case 1:                 /* "BLAN" */
+                               if (detail->bLength != (sizeof *detail + 3))
+                                       goto bad_detail;
+                               break;
+                       default:
+                               goto bad_detail;
+                       }
+
+                       /* assuming we either noticed BLAN already, or will
+                        * find it soon, there are some data bytes here:
+                        *  - bmNetworkCapabilities (unused)
+                        *  - bmDataCapabilities (bits, see below)
+                        *  - bPad (ignored, for PADAFTER -- BLAN-only)
+                        * bits are:
+                        *  - 0x01 -- Zaurus framing (add CRC)
+                        *  - 0x02 -- PADBEFORE (CRC includes some padding)
+                        *  - 0x04 -- PADAFTER (some padding after CRC)
+                        *  - 0x08 -- "fermat" packet mangling (for hw bugs)
+                        * the PADBEFORE appears not to matter; we interop
+                        * with devices that use it and those that don't.
+                        */
+                       if ((detail->bDetailData[1] & ~0x02) != 0x01) {
+                               /* bmDataCapabilites == 0 would be fine too,
+                                * but framing is minidriver-coupled for now.
+                                */
+bad_detail:
+                               dev_dbg(&intf->dev,
+                                               "bad MDLM detail, %d %d %d\n",
+                                               detail->bLength,
+                                               detail->bDetailData[0],
+                                               detail->bDetailData[2]);
+                               goto bad_desc;
+                       }
+                       break;
+               }
+next_desc:
+               len -= buf [0]; /* bLength */
+               buf += buf [0];
+       }
+
+       if (!desc || !detail) {
+               dev_dbg(&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
+                       desc ? "" : "func ",
+                       detail ? "" : "detail ");
+               goto bad_desc;
+       }
+
+       /* There's probably a CDC Ethernet descriptor there, but we can't
+        * rely on the Ethernet address it provides since not all vendors
+        * bother to make it unique.  Likewise there's no point in tracking
+        * of the CDC event notifications.
+        */
+       return usbnet_get_endpoints(dev, intf);
+
+bad_desc:
+       dev_info(&dev->udev->dev, "unsupported MDLM descriptors\n");
+       return -ENODEV;
+}
+
+static const struct driver_info        bogus_mdlm_info = {
+       .description =  "pseudo-MDLM (BLAN) device",
+       .flags =        FLAG_FRAMING_Z,
+       .check_connect = always_connected,
+       .tx_fixup =     zaurus_tx_fixup,
+       .bind =         blan_mdlm_bind,
+};
+
+static const struct usb_device_id      products [] = {
+#define        ZAURUS_MASTER_INTERFACE \
+       .bInterfaceClass        = USB_CLASS_COMM, \
+       .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET, \
+       .bInterfaceProtocol     = USB_CDC_PROTO_NONE
+
+/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8004,
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_STRONGARM_INFO,
+},
+
+/* PXA-2xx based models are also lying-about-cdc.  If you add any
+ * more devices that claim to be CDC Ethernet, make sure they get
+ * added to the blacklist in cdc_ether too.
+ *
+ * NOTE:  OpenZaurus versions with 2.6 kernels won't use these entries,
+ * unlike the older ones with 2.4 "embedix" kernels.
+ */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8005,       /* A-300 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_PXA_INFO,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8006,       /* B-500/SL-5600 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_PXA_INFO,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                 | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x8007,       /* C-700 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_PXA_INFO,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x9031,       /* C-750 C-760 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_PXA_INFO,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       .idProduct              = 0x9032,       /* SL-6000 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_PXA_INFO,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x04DD,
+       /* reported with some C860 units */
+       .idProduct              = 0x9050,       /* C-860 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = ZAURUS_PXA_INFO,
+},
+
+
+/* At least some of the newest PXA units have very different lies about
+ * their standards support:  they claim to be cell phones offering
+ * direct access to their radios!  (No, they don't conform to CDC MDLM.)
+ */
+{
+       USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
+                       USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &bogus_mdlm_info,
+},
+
+/* Olympus has some models with a Zaurus-compatible option.
+ * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
+ */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x07B4,
+       .idProduct              = 0x0F02,       /* R-1000 */
+       ZAURUS_MASTER_INTERFACE,
+       .driver_info = OLYMPUS_MXL_INFO,
+},
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver zaurus_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "zaurus",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+static int __init zaurus_init(void)
+{
+       return usb_register(&zaurus_driver);
+}
+module_init(zaurus_init);
+
+static void __exit zaurus_exit(void)
+{
+       usb_deregister(&zaurus_driver);
+}
+module_exit(zaurus_exit);
+
+MODULE_AUTHOR("Pavel Machek, David Brownell");
+MODULE_DESCRIPTION("Sharp Zaurus PDA, and compatible products");
+MODULE_LICENSE("GPL");
index fc013978837e21fd756a594d53b6d52326b2646f..c4e479ee926aa75b3b53e27eb5744fca5c20859a 100644 (file)
@@ -847,7 +847,6 @@ static void zd1201_tx_timeout(struct net_device *dev)
                return;
        dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
            dev->name);
-       zd->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
        usb_unlink_urb(zd->tx_urb);
        zd->stats.tx_errors++;
        /* Restart the timeout to quiet the watchdog: */
index 012e63e05806076b06a42dc1d3d592fa45fc0fce..05c44ae3ed32adce07adbfb0a3d05edfdc5c1979 100644 (file)
@@ -453,8 +453,8 @@ static int generic_startup (struct usb_serial *serial)
        priv->cbr_mask = B300;
        usb_set_serial_port_data(serial->port[0], priv);
        
-       return (0);     
-}      
+       return 0;
+}
 
 
 static int cypress_earthmate_startup (struct usb_serial *serial)
@@ -464,14 +464,15 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
        dbg("%s", __FUNCTION__);
 
        if (generic_startup(serial)) {
-               dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number);
+               dbg("%s - Failed setting up port %d", __FUNCTION__,
+                               serial->port[0]->number);
                return 1;
        }
 
        priv = usb_get_serial_port_data(serial->port[0]);
        priv->chiptype = CT_EARTHMATE;
-       
-       return (0);     
+
+       return 0;
 } /* cypress_earthmate_startup */
 
 
@@ -482,14 +483,15 @@ static int cypress_hidcom_startup (struct usb_serial *serial)
        dbg("%s", __FUNCTION__);
 
        if (generic_startup(serial)) {
-               dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number);
+               dbg("%s - Failed setting up port %d", __FUNCTION__,
+                               serial->port[0]->number);
                return 1;
        }
 
        priv = usb_get_serial_port_data(serial->port[0]);
        priv->chiptype = CT_CYPHIDCOM;
        
-       return (0);     
+       return 0;
 } /* cypress_hidcom_startup */
 
 
@@ -909,7 +911,8 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
 } /* cypress_ioctl */
 
 
-static void cypress_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void cypress_set_termios (struct usb_serial_port *port,
+               struct termios *old_termios)
 {
        struct cypress_private *priv = usb_get_serial_port_data(port);
        struct tty_struct *tty;
@@ -918,7 +921,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        unsigned long flags;
        __u8 oldlines;
        int linechange = 0;
-       
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        tty = port->tty;
@@ -931,10 +934,12 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        if (!priv->termios_initialized) {
                if (priv->chiptype == CT_EARTHMATE) {
                        *(tty->termios) = tty_std_termios;
-                       tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
+                       tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL |
+                               CLOCAL;
                } else if (priv->chiptype == CT_CYPHIDCOM) {
                        *(tty->termios) = tty_std_termios;
-                       tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+                       tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
+                               CLOCAL;
                }
                priv->termios_initialized = 1;
        }
@@ -946,12 +951,15 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        /* check if there are new settings */
        if (old_termios) {
                if ((cflag != old_termios->c_cflag) ||
-                   (RELEVANT_IFLAG(iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - attempting to set new termios settings", __FUNCTION__);
-                       /* should make a copy of this in case something goes wrong in the function, we can restore it */
+                       (RELEVANT_IFLAG(iflag) !=
+                        RELEVANT_IFLAG(old_termios->c_iflag))) {
+                       dbg("%s - attempting to set new termios settings",
+                                       __FUNCTION__);
+                       /* should make a copy of this in case something goes
+                        * wrong in the function, we can restore it */
                        spin_lock_irqsave(&priv->lock, flags);
                        priv->tmp_termios = *(tty->termios);
-                       spin_unlock_irqrestore(&priv->lock, flags); 
+                       spin_unlock_irqrestore(&priv->lock, flags);
                } else {
                        dbg("%s - nothing to do, exiting", __FUNCTION__);
                        return;
@@ -962,21 +970,34 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        /* set number of data bits, parity, stop bits */
        /* when parity is disabled the parity type bit is ignored */
 
-       stop_bits = cflag & CSTOPB ? 1 : 0; /* 1 means 2 stop bits, 0 means 1 stop bit */
-       
+       /* 1 means 2 stop bits, 0 means 1 stop bit */
+       stop_bits = cflag & CSTOPB ? 1 : 0;
+
        if (cflag & PARENB) {
                parity_enable = 1;
-               parity_type = cflag & PARODD ? 1 : 0; /* 1 means odd parity, 0 means even parity */
+               /* 1 means odd parity, 0 means even parity */
+               parity_type = cflag & PARODD ? 1 : 0;
        } else
                parity_enable = parity_type = 0;
 
        if (cflag & CSIZE) {
                switch (cflag & CSIZE) {
-                       case CS5: data_bits = 0; break;
-                       case CS6: data_bits = 1; break;
-                       case CS7: data_bits = 2; break;
-                       case CS8: data_bits = 3; break;
-                       default: err("%s - CSIZE was set, but not CS5-CS8", __FUNCTION__); data_bits = 3;
+                       case CS5:
+                               data_bits = 0;
+                               break;
+                       case CS6:
+                               data_bits = 1;
+                               break;
+                       case CS7:
+                               data_bits = 2;
+                               break;
+                       case CS8:
+                               data_bits = 3;
+                               break;
+                       default:
+                               err("%s - CSIZE was set, but not CS5-CS8",
+                                               __FUNCTION__);
+                               data_bits = 3;
                }
        } else
                data_bits = 3;
@@ -991,63 +1012,85 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        } else {
                baud_mask = (cflag & CBAUD);
                switch(baud_mask) {
-                       case B300: dbg("%s - setting baud 300bps", __FUNCTION__); break;
-                       case B600: dbg("%s - setting baud 600bps", __FUNCTION__); break;
-                       case B1200: dbg("%s - setting baud 1200bps", __FUNCTION__); break;
-                       case B2400: dbg("%s - setting baud 2400bps", __FUNCTION__); break;
-                       case B4800: dbg("%s - setting baud 4800bps", __FUNCTION__); break;
-                       case B9600: dbg("%s - setting baud 9600bps", __FUNCTION__); break;
-                       case B19200: dbg("%s - setting baud 19200bps", __FUNCTION__); break;
-                       case B38400: dbg("%s - setting baud 38400bps", __FUNCTION__); break;
-                       case B57600: dbg("%s - setting baud 57600bps", __FUNCTION__); break;
-                       case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break;
-                       default: dbg("%s - unknown masked baud rate", __FUNCTION__);
+                       case B300:
+                               dbg("%s - setting baud 300bps", __FUNCTION__);
+                               break;
+                       case B600:
+                               dbg("%s - setting baud 600bps", __FUNCTION__);
+                               break;
+                       case B1200:
+                               dbg("%s - setting baud 1200bps", __FUNCTION__);
+                               break;
+                       case B2400:
+                               dbg("%s - setting baud 2400bps", __FUNCTION__);
+                               break;
+                       case B4800:
+                               dbg("%s - setting baud 4800bps", __FUNCTION__);
+                               break;
+                       case B9600:
+                               dbg("%s - setting baud 9600bps", __FUNCTION__);
+                               break;
+                       case B19200:
+                               dbg("%s - setting baud 19200bps", __FUNCTION__);
+                               break;
+                       case B38400:
+                               dbg("%s - setting baud 38400bps", __FUNCTION__);
+                               break;
+                       case B57600:
+                               dbg("%s - setting baud 57600bps", __FUNCTION__);
+                               break;
+                       case B115200:
+                               dbg("%s - setting baud 115200bps", __FUNCTION__);
+                               break;
+                       default:
+                               dbg("%s - unknown masked baud rate", __FUNCTION__);
                }
                priv->line_control = (CONTROL_DTR | CONTROL_RTS);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
-       
-       dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)", __FUNCTION__,
-           stop_bits, parity_enable, parity_type, data_bits);
 
-       cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable,
-                              parity_type, 0, CYPRESS_SET_CONFIG);
+       dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, "
+                       "%d data_bits (+5)", __FUNCTION__, stop_bits,
+                       parity_enable, parity_type, data_bits);
+
+       cypress_serial_control(port, baud_mask, data_bits, stop_bits,
+                       parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
 
-       /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure
-         * this should confirm that all is working if it returns what we just set */
+       /* we perform a CYPRESS_GET_CONFIG so that the current settings are
+        * filled into the private structure this should confirm that all is
+        * working if it returns what we just set */
        cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
 
-       /* Here we can define custom tty settings for devices
-         *
-         * the main tty termios flag base comes from empeg.c
-         */
+       /* Here we can define custom tty settings for devices; the main tty
+        * termios flag base comes from empeg.c */
 
-       spin_lock_irqsave(&priv->lock, flags);  
+       spin_lock_irqsave(&priv->lock, flags);
        if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {
-
-               dbg("Using custom termios settings for a baud rate of 4800bps.");
+               dbg("Using custom termios settings for a baud rate of "
+                               "4800bps.");
                /* define custom termios settings for NMEA protocol */
 
                tty->termios->c_iflag /* input modes - */
-                       &= ~(IGNBRK             /* disable ignore break */
-                       | BRKINT                /* disable break causes interrupt */
-                       | PARMRK                /* disable mark parity errors */
-                       | ISTRIP                /* disable clear high bit of input characters */
-                       | INLCR                 /* disable translate NL to CR */
-                       | IGNCR                 /* disable ignore CR */
-                       | ICRNL                 /* disable translate CR to NL */
-                       | IXON);                /* disable enable XON/XOFF flow control */
-               
+                       &= ~(IGNBRK  /* disable ignore break */
+                       | BRKINT     /* disable break causes interrupt */
+                       | PARMRK     /* disable mark parity errors */
+                       | ISTRIP     /* disable clear high bit of input char */
+                       | INLCR      /* disable translate NL to CR */
+                       | IGNCR      /* disable ignore CR */
+                       | ICRNL      /* disable translate CR to NL */
+                       | IXON);     /* disable enable XON/XOFF flow control */
+
                tty->termios->c_oflag /* output modes */
-                       &= ~OPOST;              /* disable postprocess output characters */
-               
-               tty->termios->c_lflag /* line discipline modes */
-                       &= ~(ECHO               /* disable echo input characters */
-                       | ECHONL                /* disable echo new line */
-                       | ICANON                /* disable erase, kill, werase, and rprnt special characters */
-                       | ISIG                  /* disable interrupt, quit, and suspend special characters */
-                       | IEXTEN);              /* disable non-POSIX special characters */
+                       &= ~OPOST;    /* disable postprocess output char */
 
+               tty->termios->c_lflag /* line discipline modes */
+                       &= ~(ECHO     /* disable echo input characters */
+                       | ECHONL      /* disable echo new line */
+                       | ICANON      /* disable erase, kill, werase, and rprnt
+                                        special characters */
+                       | ISIG        /* disable interrupt, quit, and suspend
+                                        special characters */
+                       | IEXTEN);    /* disable non-POSIX special characters */
        } /* CT_CYPHIDCOM: Application should handle this for device */
 
        linechange = (priv->line_control != oldlines);
@@ -1060,7 +1103,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        }
 } /* cypress_set_termios */
 
+
 /* returns amount of data still left in soft buffer */
 static int cypress_chars_in_buffer(struct usb_serial_port *port)
 {
@@ -1088,7 +1131,7 @@ static void cypress_throttle (struct usb_serial_port *port)
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->rx_flags = THROTTLED;
-       spin_unlock_irqrestore(&priv->lock, flags);        
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 
@@ -1110,7 +1153,8 @@ static void cypress_unthrottle (struct usb_serial_port *port)
 
                result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
                if (result)
-                       dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
+                       dev_err(&port->dev, "%s - failed submitting read urb, "
+                                       "error %d\n", __FUNCTION__, result);
        }
 }
 
@@ -1122,7 +1166,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        unsigned long flags;
-       char tty_flag = TTY_NORMAL;     
+       char tty_flag = TTY_NORMAL;
        int havedata = 0;
        int bytes = 0;
        int result;
@@ -1131,7 +1175,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (urb->status) {
-               dbg("%s - nonzero read status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero read status received: %d", __FUNCTION__,
+                               urb->status);
                return;
        }
 
@@ -1155,51 +1200,55 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
                case 32:
                        /* This is for the CY7C64013... */
                        priv->current_status = data[0] & 0xF8;
-                       bytes = data[1]+2;
-                       i=2;
+                       bytes = data[1] + 2;
+                       i = 2;
                        if (bytes > 2)
                                havedata = 1;
                        break;
                case 8:
                        /* This is for the CY7C63743... */
                        priv->current_status = data[0] & 0xF8;
-                       bytes = (data[0] & 0x07)+1;
-                       i=1;
+                       bytes = (data[0] & 0x07) + 1;
+                       i = 1;
                        if (bytes > 1)
                                havedata = 1;
                        break;
                default:
-                       dbg("%s - wrong packet size - received %d bytes", __FUNCTION__, urb->actual_length);
+                       dbg("%s - wrong packet size - received %d bytes",
+                                       __FUNCTION__, urb->actual_length);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        goto continue_read;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+       usb_serial_debug_data (debug, &port->dev, __FUNCTION__,
+                       urb->actual_length, data);
 
        spin_lock_irqsave(&priv->lock, flags);
        /* check to see if status has changed */
        if (priv != NULL) {
                if (priv->current_status != priv->prev_status) {
-                       priv->diff_status |= priv->current_status ^ priv->prev_status;
+                       priv->diff_status |= priv->current_status ^
+                               priv->prev_status;
                        wake_up_interruptible(&priv->delta_msr_wait);
                        priv->prev_status = priv->current_status;
                }
        }
-       spin_unlock_irqrestore(&priv->lock, flags);     
+       spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* hangup, as defined in acm.c... this might be a bad place for it though */
-       if (tty && !(tty->termios->c_cflag & CLOCAL) && !(priv->current_status & UART_CD)) {
+       /* hangup, as defined in acm.c... this might be a bad place for it
+        * though */
+       if (tty && !(tty->termios->c_cflag & CLOCAL) &&
+                       !(priv->current_status & UART_CD)) {
                dbg("%s - calling hangup", __FUNCTION__);
                tty_hangup(tty);
                goto continue_read;
        }
 
-       /* There is one error bit... I'm assuming it is a parity error indicator
-        * as the generic firmware will set this bit to 1 if a parity error occurs.
-        * I can not find reference to any other error events.
-        *
-        */
+       /* There is one error bit... I'm assuming it is a parity error
+        * indicator as the generic firmware will set this bit to 1 if a
+        * parity error occurs.
+        * I can not find reference to any other error events. */
        spin_lock_irqsave(&priv->lock, flags);
        if (priv->current_status & CYP_ERROR) {
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -1211,7 +1260,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
        /* process read if there is data other than line status */
        if (tty && (bytes > i)) {
                for (; i < bytes ; ++i) {
-                       dbg("pushing byte number %d - %d - %c",i,data[i],data[i]);
+                       dbg("pushing byte number %d - %d - %c", i, data[i],
+                                       data[i]);
                        if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
                                tty_flip_buffer_push(tty);
                        }
@@ -1221,25 +1271,28 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->bytes_in += bytes;  /* control and status byte(s) are also counted */
+       /* control and status byte(s) are also counted */
+       priv->bytes_in += bytes;
        spin_unlock_irqrestore(&priv->lock, flags);
 
 continue_read:
-       
-       /* Continue trying to always read... unless the port has closed.  */
+
+       /* Continue trying to always read... unless the port has closed. */
 
        if (port->open_count > 0) {
-       usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
-               usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress),
-               port->interrupt_in_urb->transfer_buffer,
-               port->interrupt_in_urb->transfer_buffer_length,
-               cypress_read_int_callback, port,
-               interval);
-       result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
-       if (result)
-               dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
+               usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
+                               usb_rcvintpipe(port->serial->dev,
+                                       port->interrupt_in_endpointAddress),
+                               port->interrupt_in_urb->transfer_buffer,
+                               port->interrupt_in_urb->transfer_buffer_length,
+                               cypress_read_int_callback, port, interval);
+               result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+               if (result)
+                       dev_err(&urb->dev->dev, "%s - failed resubmitting "
+                                       "read urb, error %d\n", __FUNCTION__,
+                                       result);
        }
-       
+
        return;
 } /* cypress_read_int_callback */
 
index d1964a0c4168f0e2e12eddf3a3728227d7ddfd56..0a6e8b474b1ff46db9efd8b423dd9ad36b215c18 100644 (file)
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
 static int debug;
+static __u16 vendor = FTDI_VID;
+static __u16 product;
 
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
 struct ftdi_sio_quirk {
@@ -407,6 +409,34 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
+       /*
+        * These will probably use user-space drivers.  Uncomment them if
+        * you need them or use the user-specified vendor/product module
+        * parameters (see ftdi_sio.h for the numbers).  Make a fuss if
+        * you think the driver should recognize any of them by default.
+        */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
+       /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
        { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
        { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
        { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -418,6 +448,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
        { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
        { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
+       { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
@@ -427,12 +458,21 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_3_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_4_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
+       { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
        { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
        { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
-       { }                                             /* Terminating entry */
+       { },                                    /* Optional parameter entry */
+       { }                                     /* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
@@ -2030,6 +2070,15 @@ static int __init ftdi_init (void)
        int retval;
 
        dbg("%s", __FUNCTION__);
+       if (vendor > 0 && product > 0) {
+               /* Add user specified VID/PID to reserved element of table. */
+               int i;
+               for (i = 0; id_table_combined[i].idVendor; i++)
+                       ;
+               id_table_combined[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+               id_table_combined[i].idVendor = vendor;
+               id_table_combined[i].idProduct = product;
+       }
        retval = usb_serial_register(&ftdi_sio_device);
        if (retval)
                goto failed_sio_register;
@@ -2066,4 +2115,9 @@ MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(vendor, ushort, 0);
+MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
+               __MODULE_STRING(FTDI_VID)")");
+module_param(product, ushort, 0);
+MODULE_PARM_DESC(vendor, "User specified product ID");
 
index 9f4342093e8b11eacbe00e49f81f28e79edf25ca..2c35d74cc6d6a45c0860f951448145e392f3310b 100644 (file)
 /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
 #define FTDI_USB_UIRT_PID      0xF850  /* Product Id */
 
-/* ELV USB Module UO100 (PID sent by Stefan Frings) */
-#define FTDI_ELV_UO100_PID     0xFB58  /* Product Id */
-/* ELV USB Module UM100 (PID sent by Arnim Laeuger) */
-#define FTDI_ELV_UM100_PID     0xFB5A  /* Product Id */
+/*
+ * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
+ * All of these devices use FTDI's vendor ID (0x0403).
+ *
+ * The previously included PID for the UO 100 module was incorrect.
+ * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58).
+ *
+ * Armin Laeuger originally sent the PID for the UM 100 module.
+ */
+#define FTDI_ELV_UR100_PID     0xFB58  /* USB-RS232-Umsetzer (UR 100) */
+#define FTDI_ELV_UM100_PID     0xFB5A  /* USB-Modul UM 100 */
+#define FTDI_ELV_UO100_PID     0xFB5B  /* USB-Modul UO 100 */
+#define FTDI_ELV_ALC8500_PID   0xF06E  /* ALC 8500 Expert */
+/* Additional ELV PIDs that default to using the FTDI D2XX drivers on
+ * MS Windows, rather than the FTDI Virtual Com Port drivers.
+ * Maybe these will be easier to use with the libftdi/libusb user-space
+ * drivers, or possibly the Comedi drivers in some cases. */
+#define FTDI_ELV_CLI7000_PID   0xFB59  /* Computer-Light-Interface (CLI 7000) */
+#define FTDI_ELV_PPS7330_PID   0xFB5C  /* Processor-Power-Supply (PPS 7330) */
+#define FTDI_ELV_TFM100_PID    0xFB5D  /* Temperartur-Feuchte Messgeraet (TFM 100) */
+#define FTDI_ELV_UDF77_PID     0xFB5E  /* USB DCF Funkurh (UDF 77) */
+#define FTDI_ELV_UIO88_PID     0xFB5F  /* USB-I/O Interface (UIO 88) */
+#define FTDI_ELV_UAD8_PID      0xF068  /* USB-AD-Wandler (UAD 8) */
+#define FTDI_ELV_UDA7_PID      0xF069  /* USB-DA-Wandler (UDA 7) */
+#define FTDI_ELV_USI2_PID      0xF06A  /* USB-Schrittmotoren-Interface (USI 2) */
+#define FTDI_ELV_T1100_PID     0xF06B  /* Thermometer (T 1100) */
+#define FTDI_ELV_PCD200_PID    0xF06C  /* PC-Datenlogger (PCD 200) */
+#define FTDI_ELV_ULA200_PID    0xF06D  /* USB-LCD-Ansteuerung (ULA 200) */
+#define FTDI_ELV_FHZ1000PC_PID 0xF06F  /* FHZ 1000 PC */
+#define FTDI_ELV_CSI8_PID      0xE0F0  /* Computer-Schalt-Interface (CSI 8) */
+#define FTDI_ELV_EM1000DL_PID  0xE0F1  /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
+#define FTDI_ELV_PCK100_PID    0xE0F2  /* PC-Kabeltester (PCK 100) */
+#define FTDI_ELV_RFP500_PID    0xE0F3  /* HF-Leistungsmesser (RFP 500) */
+#define FTDI_ELV_FS20SIG_PID   0xE0F4  /* Signalgeber (FS 20 SIG) */
+#define FTDI_ELV_WS300PC_PID   0xE0F6  /* PC-Wetterstation (WS 300 PC) */
+#define FTDI_ELV_FHZ1300PC_PID 0xE0E8  /* FHZ 1300 PC */
+#define FTDI_ELV_WS500_PID     0xE0E9  /* PC-Wetterstation (WS 500) */
 
 /*
  * Definitions for ID TECH (www.idt-net.com) devices
  */
 #define FALCOM_VID             0x0F94  /* Vendor Id */
 #define FALCOM_TWIST_PID       0x0001  /* Falcom Twist USB GPRS modem */
+#define FALCOM_SAMBA_PID       0x0005  /* Falcom Samba USB GPRS modem */
 
 /*
  * SUUNTO product ids
  */
 #define FTDI_ACTIVE_ROBOTS_PID 0xE548  /* USB comms board */
 
+/*
+ * Xsens Technologies BV products (http://www.xsens.com).
+ */
+#define XSENS_CONVERTER_0_PID  0xD388
+#define XSENS_CONVERTER_1_PID  0xD389
+#define XSENS_CONVERTER_2_PID  0xD38A
+#define XSENS_CONVERTER_3_PID  0xD38B
+#define XSENS_CONVERTER_4_PID  0xD38C
+#define XSENS_CONVERTER_5_PID  0xD38D
+#define XSENS_CONVERTER_6_PID  0xD38E
+#define XSENS_CONVERTER_7_PID  0xD38F
+
 /*
  * Evolution Robotics products (http://www.evolution.com/).
  * Submitted by Shawn M. Lavelle.
index fb0926292228b607c5faef3b4a08205f8b3b073d..3b958e60f5e8ee717513d3f0d35cb36c0425db94 100644 (file)
@@ -383,11 +383,8 @@ static int keyspan_write(struct usb_serial_port *port,
                dbg("%s - endpoint %d flip %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), flip);
 
                if (this_urb->status == -EINPROGRESS) {
-                       if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
-                               break;
                        if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ))
                                break;
-                       this_urb->transfer_flags |= URB_ASYNC_UNLINK;
                        usb_unlink_urb(this_urb);
                        break;
                }
@@ -402,7 +399,6 @@ static int keyspan_write(struct usb_serial_port *port,
                /* send the data out the bulk port */
                this_urb->transfer_buffer_length = todo + dataOffset;
 
-               this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
                this_urb->dev = port->serial->dev;
                if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
                        dbg("usb_submit_urb(write bulk) failed (%d)", err);
@@ -1119,10 +1115,8 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
 
 static inline void stop_urb(struct urb *urb)
 {
-       if (urb && urb->status == -EINPROGRESS) {
-               urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+       if (urb && urb->status == -EINPROGRESS)
                usb_kill_urb(urb);
-       }
 }
 
 static void keyspan_close(struct usb_serial_port *port, struct file *filp)
index e9256408757ffdf3a7f5cc3a832bf8b503c808c9..92d0f925d053c64326878afc14704b9d2877cdd7 100644 (file)
 #include "usb-serial.h"
 
 /* Function prototypes */
-static int  option_open (struct usb_serial_port *port, struct file *filp);
-static void option_close (struct usb_serial_port *port, struct file *filp);
-static int  option_startup (struct usb_serial *serial);
-static void option_shutdown (struct usb_serial *serial);
-static void option_rx_throttle (struct usb_serial_port *port);
-static void option_rx_unthrottle (struct usb_serial_port *port);
-static int  option_write_room (struct usb_serial_port *port);
+static int  option_open(struct usb_serial_port *port, struct file *filp);
+static void option_close(struct usb_serial_port *port, struct file *filp);
+static int  option_startup(struct usb_serial *serial);
+static void option_shutdown(struct usb_serial *serial);
+static void option_rx_throttle(struct usb_serial_port *port);
+static void option_rx_unthrottle(struct usb_serial_port *port);
+static int  option_write_room(struct usb_serial_port *port);
 
 static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
 
-static int  option_write (struct usb_serial_port *port,
-                          const unsigned char *buf, int count);
+static int option_write(struct usb_serial_port *port,
+                       const unsigned char *buf, int count);
 
-static int  option_chars_in_buffer (struct usb_serial_port *port);
-static int  option_ioctl (struct usb_serial_port *port, struct file *file,
-                          unsigned int cmd, unsigned long arg);
-static void option_set_termios (struct usb_serial_port *port,
-                                struct termios *old);
-static void option_break_ctl (struct usb_serial_port *port, int break_state);
-static int  option_tiocmget (struct usb_serial_port *port, struct file *file);
-static int  option_tiocmset (struct usb_serial_port *port, struct file *file,
-                             unsigned int set, unsigned int clear);
-static int  option_send_setup (struct usb_serial_port *port);
+static int  option_chars_in_buffer(struct usb_serial_port *port);
+static int  option_ioctl(struct usb_serial_port *port, struct file *file,
+                       unsigned int cmd, unsigned long arg);
+static void option_set_termios(struct usb_serial_port *port,
+                               struct termios *old);
+static void option_break_ctl(struct usb_serial_port *port, int break_state);
+static int  option_tiocmget(struct usb_serial_port *port, struct file *file);
+static int  option_tiocmset(struct usb_serial_port *port, struct file *file,
+                               unsigned int set, unsigned int clear);
+static int  option_send_setup(struct usb_serial_port *port);
 
 /* Vendor and product IDs */
 #define OPTION_VENDOR_ID                       0x0AF0
@@ -76,7 +76,6 @@ static int  option_send_setup (struct usb_serial_port *port);
 #define OPTION_PRODUCT_FUSION  0x6000
 #define OPTION_PRODUCT_FUSION2 0x6300
 
-
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
@@ -129,7 +128,6 @@ static int debug;
 #define debug 0
 #endif
 
-
 /* per port private data */
 
 #define N_IN_URB 4
@@ -156,10 +154,8 @@ struct option_port_private {
        unsigned long tx_start_time[N_OUT_URB];
 };
 
-
 /* Functions used by new usb-serial code. */
-static int __init
-option_init (void)
+static int __init option_init(void)
 {
        int retval;
        retval = usb_serial_register(&option_3port_device);
@@ -179,8 +175,7 @@ failed_3port_device_register:
        return retval;
 }
 
-static void __exit
-option_exit (void)
+static void __exit option_exit(void)
 {
        usb_deregister (&option_driver);
        usb_serial_deregister (&option_3port_device);
@@ -189,39 +184,31 @@ option_exit (void)
 module_init(option_init);
 module_exit(option_exit);
 
-static void
-option_rx_throttle (struct usb_serial_port *port)
+static void option_rx_throttle(struct usb_serial_port *port)
 {
        dbg("%s", __FUNCTION__);
 }
 
-
-static void
-option_rx_unthrottle (struct usb_serial_port *port)
+static void option_rx_unthrottle(struct usb_serial_port *port)
 {
        dbg("%s", __FUNCTION__);
 }
 
-
-static void
-option_break_ctl (struct usb_serial_port *port, int break_state)
+static void option_break_ctl(struct usb_serial_port *port, int break_state)
 {
        /* Unfortunately, I don't know how to send a break */
        dbg("%s", __FUNCTION__);
 }
 
-
-static void
-option_set_termios (struct usb_serial_port *port,
-                    struct termios *old_termios)
+static void option_set_termios(struct usb_serial_port *port,
+                       struct termios *old_termios)
 {
        dbg("%s", __FUNCTION__);
 
        option_send_setup(port);
 }
 
-static int
-option_tiocmget (struct usb_serial_port *port, struct file *file)
+static int option_tiocmget(struct usb_serial_port *port, struct file *file)
 {
        unsigned int value;
        struct option_port_private *portdata;
@@ -238,9 +225,8 @@ option_tiocmget (struct usb_serial_port *port, struct file *file)
        return value;
 }
 
-static int
-option_tiocmset (struct usb_serial_port *port, struct file *file,
-                 unsigned int set, unsigned int clear)
+static int option_tiocmset(struct usb_serial_port *port, struct file *file,
+                       unsigned int set, unsigned int clear)
 {
        struct option_port_private *portdata;
 
@@ -258,17 +244,15 @@ option_tiocmset (struct usb_serial_port *port, struct file *file,
        return option_send_setup(port);
 }
 
-static int
-option_ioctl (struct usb_serial_port *port, struct file *file,
-              unsigned int cmd, unsigned long arg)
+static int option_ioctl(struct usb_serial_port *port, struct file *file,
+                       unsigned int cmd, unsigned long arg)
 {
        return -ENOIOCTLCMD;
 }
 
 /* Write */
-static int
-option_write (struct usb_serial_port *port,
-                         const unsigned char *buf, int count)
+static int option_write(struct usb_serial_port *port,
+                       const unsigned char *buf, int count)
 {
        struct option_port_private *portdata;
        int i;
@@ -289,28 +273,29 @@ option_write (struct usb_serial_port *port,
 
                this_urb = portdata->out_urbs[i];
                if (this_urb->status == -EINPROGRESS) {
-                       if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
-                               continue;
-                       if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
+                       if (time_before(jiffies,
+                                       portdata->tx_start_time[i] + 10 * HZ))
                                continue;
-                       this_urb->transfer_flags |= URB_ASYNC_UNLINK;
                        usb_unlink_urb(this_urb);
                        continue;
                }
                if (this_urb->status != 0)
-                       dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
+                       dbg("usb_write %p failed (err=%d)",
+                               this_urb, this_urb->status);
 
-               dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
+               dbg("%s: endpoint %d buf %d", __FUNCTION__,
+                       usb_pipeendpoint(this_urb->pipe), i);
 
                /* send the data */
                memcpy (this_urb->transfer_buffer, buf, todo);
                this_urb->transfer_buffer_length = todo;
 
-               this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
                this_urb->dev = port->serial->dev;
                err = usb_submit_urb(this_urb, GFP_ATOMIC);
                if (err) {
-                       dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
+                       dbg("usb_submit_urb %p (write bulk) failed "
+                               "(%d, has %d)", this_urb,
+                               err, this_urb->status);
                        continue;
                }
                portdata->tx_start_time[i] = jiffies;
@@ -323,8 +308,7 @@ option_write (struct usb_serial_port *port,
        return count;
 }
 
-static void
-option_indat_callback (struct urb *urb, struct pt_regs *regs)
+static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
 {
        int i, err;
        int endpoint;
@@ -357,14 +341,14 @@ option_indat_callback (struct urb *urb, struct pt_regs *regs)
                if (port->open_count && urb->status != -ESHUTDOWN) {
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err)
-                               printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err);
+                               printk(KERN_ERR "%s: resubmit read urb failed. "
+                                       "(%d)", __FUNCTION__, err);
                }
        }
        return;
 }
 
-static void
-option_outdat_callback (struct urb *urb, struct pt_regs *regs)
+static void option_outdat_callback(struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port;
 
@@ -376,8 +360,7 @@ option_outdat_callback (struct urb *urb, struct pt_regs *regs)
                schedule_work(&port->work);
 }
 
-static void
-option_instat_callback (struct urb *urb, struct pt_regs *regs)
+static void option_instat_callback(struct urb *urb, struct pt_regs *regs)
 {
        int err;
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
@@ -395,10 +378,12 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
                        dbg("%s: NULL req_pkt\n", __FUNCTION__);
                        return;
                }
-               if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) {
+               if ((req_pkt->bRequestType == 0xA1) &&
+                               (req_pkt->bRequest == 0x20)) {
                        int old_dcd_state;
                        unsigned char signals = *((unsigned char *)
-                                       urb->transfer_buffer + sizeof(struct usb_ctrlrequest));
+                                       urb->transfer_buffer +
+                                       sizeof(struct usb_ctrlrequest));
 
                        dbg("%s: signal x%x", __FUNCTION__, signals);
 
@@ -408,12 +393,13 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
 
-                       if (port->tty && !C_CLOCAL(port->tty)
-                                       && old_dcd_state && !portdata->dcd_state) {
+                       if (port->tty && !C_CLOCAL(port->tty) &&
+                                       old_dcd_state && !portdata->dcd_state)
                                tty_hangup(port->tty);
-                       }
-               } else
-                       dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest);
+               } else {
+                       dbg("%s: type %x req %x", __FUNCTION__,
+                               req_pkt->bRequestType,req_pkt->bRequest);
+               }
        } else
                dbg("%s: error %d", __FUNCTION__, urb->status);
 
@@ -422,13 +408,12 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
                urb->dev = serial->dev;
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
-                       dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err);
+                       dbg("%s: resubmit intr urb failed. (%d)",
+                               __FUNCTION__, err);
        }
 }
 
-
-static int
-option_write_room (struct usb_serial_port *port)
+static int option_write_room(struct usb_serial_port *port)
 {
        struct option_port_private *portdata;
        int i;
@@ -447,9 +432,7 @@ option_write_room (struct usb_serial_port *port)
        return data_len;
 }
 
-
-static int
-option_chars_in_buffer (struct usb_serial_port *port)
+static int option_chars_in_buffer(struct usb_serial_port *port)
 {
        struct option_port_private *portdata;
        int i;
@@ -467,9 +450,7 @@ option_chars_in_buffer (struct usb_serial_port *port)
        return data_len;
 }
 
-
-static int
-option_open (struct usb_serial_port *port, struct file *filp)
+static int option_open(struct usb_serial_port *port, struct file *filp)
 {
        struct option_port_private *portdata;
        struct usb_serial *serial = port->serial;
@@ -490,17 +471,21 @@ option_open (struct usb_serial_port *port, struct file *filp)
                if (! urb)
                        continue;
                if (urb->dev != serial->dev) {
-                       dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev);
+                       dbg("%s: dev %p != %p", __FUNCTION__,
+                               urb->dev, serial->dev);
                        continue;
                }
 
-               /* make sure endpoint data toggle is synchronized with the device */
-
+               /*
+                * make sure endpoint data toggle is synchronized with the
+                * device
+                */
                usb_clear_halt(urb->dev, urb->pipe);
 
                err = usb_submit_urb(urb, GFP_KERNEL);
                if (err) {
-                       dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err,
+                       dbg("%s: submit urb %d failed (%d) %d",
+                               __FUNCTION__, i, err,
                                urb->transfer_buffer_length);
                }
        }
@@ -511,7 +496,8 @@ option_open (struct usb_serial_port *port, struct file *filp)
                if (! urb)
                        continue;
                urb->dev = serial->dev;
-               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
+               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                               usb_pipeout(urb->pipe), 0); */
        }
 
        port->tty->low_latency = 1;
@@ -521,17 +507,13 @@ option_open (struct usb_serial_port *port, struct file *filp)
        return (0);
 }
 
-static inline void
-stop_urb (struct urb *urb)
+static inline void stop_urb(struct urb *urb)
 {
-       if (urb && urb->status == -EINPROGRESS) {
-               urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+       if (urb && urb->status == -EINPROGRESS)
                usb_kill_urb(urb);
-       }
 }
 
-static void
-option_close (struct usb_serial_port *port, struct file *filp)
+static void option_close(struct usb_serial_port *port, struct file *filp)
 {
        int i;
        struct usb_serial *serial = port->serial;
@@ -555,12 +537,10 @@ option_close (struct usb_serial_port *port, struct file *filp)
        port->tty = NULL;
 }
 
-
 /* Helper functions used by option_setup_urbs */
-static struct urb *
-option_setup_urb (struct usb_serial *serial, int endpoint,
-                  int dir, void *ctx, char *buf, int len,
-                  void (*callback)(struct urb *, struct pt_regs *regs))
+static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
+               int dir, void *ctx, char *buf, int len,
+               void (*callback)(struct urb *, struct pt_regs *regs))
 {
        struct urb *urb;
 
@@ -582,8 +562,7 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
 }
 
 /* Setup urbs */
-static void
-option_setup_urbs (struct usb_serial *serial)
+static void option_setup_urbs(struct usb_serial *serial)
 {
        int j;
        struct usb_serial_port *port;
@@ -609,9 +588,7 @@ option_setup_urbs (struct usb_serial *serial)
        }
 }
 
-
-static int
-option_send_setup (struct usb_serial_port *port)
+static int option_send_setup(struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
        struct option_port_private *portdata;
@@ -627,16 +604,15 @@ option_send_setup (struct usb_serial_port *port)
                if (portdata->rts_state)
                        val |= 0x02;
 
-               return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                                       0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+               return usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0),
+                               0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
        }
 
        return 0;
 }
 
-
-static int
-option_startup (struct usb_serial *serial)
+static int option_startup(struct usb_serial *serial)
 {
        int i, err;
        struct usb_serial_port *port;
@@ -647,9 +623,10 @@ option_startup (struct usb_serial *serial)
        /* Now setup per port private data */
        for (i = 0; i < serial->num_ports; i++) {
                port = serial->port[i];
-               portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL);
+               portdata = kmalloc(sizeof(*portdata), GFP_KERNEL);
                if (!portdata) {
-                       dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i);
+                       dbg("%s: kmalloc for option_port_private (%d) failed!.",
+                                       __FUNCTION__, i);
                        return (1);
                }
                memset(portdata, 0, sizeof(struct option_port_private));
@@ -660,7 +637,8 @@ option_startup (struct usb_serial *serial)
                        continue;
                err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
                if (err)
-                       dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err);
+                       dbg("%s: submit irq_in urb failed %d",
+                               __FUNCTION__, err);
        }
 
        option_setup_urbs(serial);
@@ -668,8 +646,7 @@ option_startup (struct usb_serial *serial)
        return (0);
 }
 
-static void
-option_shutdown (struct usb_serial *serial)
+static void option_shutdown(struct usb_serial *serial)
 {
        int i, j;
        struct usb_serial_port *port;
index 7eab5d4cf3a8c674a84ebafd73c8e4aaa4e2da27..461474176cfbc8aae66081e1dc1c3b3117c83c37 100644 (file)
@@ -538,8 +538,10 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
 
        dbg("%s -  port %d", __FUNCTION__, port->number);
 
-       usb_clear_halt(serial->dev, port->write_urb->pipe);
-       usb_clear_halt(serial->dev, port->read_urb->pipe);
+       if (priv->type != HX) {
+               usb_clear_halt(serial->dev, port->write_urb->pipe);
+               usb_clear_halt(serial->dev, port->read_urb->pipe);
+       }
 
        buf = kmalloc(10, GFP_KERNEL);
        if (buf==NULL)
index 0267b26dde18ae5b72b38c0d02722b0ac982e07b..e77fbdfc782de8a38d2496ff24b98a0787fa6f19 100644 (file)
@@ -531,7 +531,7 @@ bailout_kref_put:
 
 static void serial_close(struct tty_struct *tty, struct file * filp)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        if (!port)
                return;
@@ -561,7 +561,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
 
 static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
        int retval = -EINVAL;
 
        dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
@@ -580,7 +580,7 @@ exit:
 
 static int serial_write_room (struct tty_struct *tty) 
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
        int retval = -EINVAL;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -599,7 +599,7 @@ exit:
 
 static int serial_chars_in_buffer (struct tty_struct *tty) 
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
        int retval = -EINVAL;
 
        dbg("%s = port %d", __FUNCTION__, port->number);
@@ -618,7 +618,7 @@ exit:
 
 static void serial_throttle (struct tty_struct * tty)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -634,7 +634,7 @@ static void serial_throttle (struct tty_struct * tty)
 
 static void serial_unthrottle (struct tty_struct * tty)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -650,7 +650,7 @@ static void serial_unthrottle (struct tty_struct * tty)
 
 static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
        int retval = -ENODEV;
 
        dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
@@ -672,7 +672,7 @@ exit:
 
 static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -688,7 +688,7 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 
 static void serial_break (struct tty_struct *tty, int break_state)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -749,7 +749,7 @@ done:
 
 static int serial_tiocmget (struct tty_struct *tty, struct file *file)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -768,7 +768,7 @@ exit:
 static int serial_tiocmset (struct tty_struct *tty, struct file *file,
                            unsigned int set, unsigned int clear)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -786,7 +786,7 @@ exit:
 
 void usb_serial_port_softint(void *private)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)private;
+       struct usb_serial_port *port = private;
        struct tty_struct *tty;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
index f1f1c0608c22a9f471aa88779e97f5bde4846fa2..bb9819cc8826834342cf03191ab7803683883a36 100644 (file)
@@ -111,3 +111,15 @@ config USB_STORAGE_JUMPSHOT
          Say Y here to include additional code to support the Lexar Jumpshot
          USB CompactFlash reader.
 
+
+config USB_STORAGE_ONETOUCH
+       bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
+       depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL
+       help
+         Say Y here to include additional code to support the Maxtor OneTouch
+         USB hard drive's onetouch button.
+
+         This code registers the button on the front of Maxtor OneTouch USB
+         hard drive's as an input device. An action can be associated with
+         this input in any keybinding software. (e.g. gnome's keyboard short-
+         cuts)
index 56652ccc2881cb1bd1c21f0b4fb3c93d5abff753..44ab8f9978fe9d3a44fd2675674f3395ac8949b0 100644 (file)
@@ -18,6 +18,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM)    += dpcm.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)   += isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)  += datafab.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
 
 usb-storage-objs :=    scsiglue.o protocol.o transport.o usb.o \
                        initializers.o $(usb-storage-obj-y)
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
new file mode 100644 (file)
index 0000000..2c9402d
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Support for the Maxtor OneTouch USB hard drive's button
+ *
+ * Current development and maintenance by:
+ *     Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
+ *
+ * Initial work by:
+ *     Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
+ *
+ * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
+ *
+ */
+
+/*
+ * 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-1307 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_ch9.h>
+#include <linux/usb_input.h>
+#include "usb.h"
+#include "onetouch.h"
+#include "debug.h"
+
+void onetouch_release_input(void *onetouch_);
+
+struct usb_onetouch {
+       char name[128];
+       char phys[64];
+       struct input_dev dev;   /* input device interface */
+       struct usb_device *udev;        /* usb device */
+
+       struct urb *irq;        /* urb for interrupt in report */
+       unsigned char *data;    /* input data */
+       dma_addr_t data_dma;
+};
+
+static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+       struct usb_onetouch *onetouch = urb->context;
+       signed char *data = onetouch->data;
+       struct input_dev *dev = &onetouch->dev;
+       int status;
+
+       switch (urb->status) {
+       case 0:                 /* success */
+               break;
+       case -ECONNRESET:       /* unlink */
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       /* -EPIPE:  should clear the halt */
+       default:                /* error */
+               goto resubmit;
+       }
+
+       input_regs(dev, regs);
+
+       input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
+                        data[0] & 0x02);
+
+       input_sync(dev);
+resubmit:
+       status = usb_submit_urb (urb, SLAB_ATOMIC);
+       if (status)
+               err ("can't resubmit intr, %s-%s/input0, status %d",
+                       onetouch->udev->bus->bus_name,
+                       onetouch->udev->devpath, status);
+}
+
+static int usb_onetouch_open(struct input_dev *dev)
+{
+       struct usb_onetouch *onetouch = dev->private;
+
+       onetouch->irq->dev = onetouch->udev;
+       if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
+               err("usb_submit_urb failed");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void usb_onetouch_close(struct input_dev *dev)
+{
+       struct usb_onetouch *onetouch = dev->private;
+
+       usb_kill_urb(onetouch->irq);
+}
+
+int onetouch_connect_input(struct us_data *ss)
+{
+       struct usb_device *udev = ss->pusb_dev;
+       struct usb_host_interface *interface;
+       struct usb_endpoint_descriptor *endpoint;
+       struct usb_onetouch *onetouch;
+       int pipe, maxp;
+       char path[64];
+
+       interface = ss->pusb_intf->cur_altsetting;
+
+       if (interface->desc.bNumEndpoints != 3)
+               return -ENODEV;
+
+       endpoint = &interface->endpoint[2].desc;
+       if(!(endpoint->bEndpointAddress & USB_DIR_IN))
+               return -ENODEV;
+       if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+                       != USB_ENDPOINT_XFER_INT)
+               return -ENODEV;
+
+       pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+       maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+
+       if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
+               return -ENOMEM;
+
+       onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
+                                         SLAB_ATOMIC, &onetouch->data_dma);
+       if (!onetouch->data){
+               kfree(onetouch);
+               return -ENOMEM;
+       }
+
+       onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+       if (!onetouch->irq){
+               kfree(onetouch);
+               usb_buffer_free(udev, ONETOUCH_PKT_LEN,
+                               onetouch->data, onetouch->data_dma);
+               return -ENODEV;
+       }
+
+
+       onetouch->udev = udev;
+
+       set_bit(EV_KEY, onetouch->dev.evbit);
+       set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
+       clear_bit(0, onetouch->dev.keybit);
+
+       onetouch->dev.private = onetouch;
+       onetouch->dev.open = usb_onetouch_open;
+       onetouch->dev.close = usb_onetouch_close;
+
+       usb_make_path(udev, path, sizeof(path));
+       sprintf(onetouch->phys, "%s/input0", path);
+
+       onetouch->dev.name = onetouch->name;
+       onetouch->dev.phys = onetouch->phys;
+
+       usb_to_input_id(udev, &onetouch->dev.id);
+
+       onetouch->dev.dev = &udev->dev;
+
+       if (udev->manufacturer)
+               strcat(onetouch->name, udev->manufacturer);
+       if (udev->product)
+               sprintf(onetouch->name, "%s %s", onetouch->name,
+                       udev->product);
+       if (!strlen(onetouch->name))
+               sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
+                       onetouch->dev.id.vendor, onetouch->dev.id.product);
+
+       usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
+                        (maxp > 8 ? 8 : maxp),
+                        usb_onetouch_irq, onetouch, endpoint->bInterval);
+       onetouch->irq->transfer_dma = onetouch->data_dma;
+       onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       ss->extra_destructor = onetouch_release_input;
+       ss->extra = onetouch;
+
+       input_register_device(&onetouch->dev);
+       printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
+
+       return 0;
+}
+
+void onetouch_release_input(void *onetouch_)
+{
+       struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_;
+
+       if (onetouch) {
+               usb_kill_urb(onetouch->irq);
+               input_unregister_device(&onetouch->dev);
+               usb_free_urb(onetouch->irq);
+               usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
+                               onetouch->data, onetouch->data_dma);
+               printk(KERN_INFO "usb-input: deregistering %s\n",
+                               onetouch->dev.name);
+       }
+}
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
new file mode 100644 (file)
index 0000000..41c7aa8
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _ONETOUCH_H_
+#define _ONETOUCH_H_
+
+#define ONETOUCH_PKT_LEN        0x02
+#define ONETOUCH_BUTTON         KEY_PROG1
+
+int onetouch_connect_input(struct us_data *ss);
+
+#endif
index af294bb68c35de7707a8f827a8463b32d3188ded..d34dc9f417f0267f40d1927e3c7f0f8d8d481193 100644 (file)
@@ -156,6 +156,14 @@ static int slave_configure(struct scsi_device *sdev)
                if (us->flags & US_FL_FIX_CAPACITY)
                        sdev->fix_capacity = 1;
 
+               /* Some devices report a SCSI revision level above 2 but are
+                * unable to handle the REPORT LUNS command (for which
+                * support is mandatory at level 3).  Since we already have
+                * a Get-Max-LUN request, we won't lose much by setting the
+                * revision level down to 2.  The only devices that would be
+                * affected are those with sparse LUNs. */
+               sdev->scsi_level = SCSI_2;
+
                /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
                 * Hardware Error) when any low-level error occurs,
                 * recoverable or not.  Setting this flag tells the SCSI
index f3b60288696cfbc1162418368892773959562dbe..356342c6e7a24caebbfacf3fed13d9a992949e1c 100644 (file)
@@ -839,34 +839,31 @@ static int usbat_identify_device(struct us_data *us,
        rc = usbat_device_reset(us);
        if (rc != USB_STOR_TRANSPORT_GOOD)
                return rc;
+       msleep(25);
 
        /*
-        * By examining the device signature after a reset, we can identify
-        * whether the device supports the ATAPI packet interface.
-        * The flash-devices do not support this, whereas the HP CDRW's obviously
-        * do.
-        *
-        * This method is not ideal, but works because no other devices have been
-        * produced based on the USBAT/USBAT02.
-        *
-        * Section 9.1 of the ATAPI-4 spec states (amongst other things) that
-        * after a device reset, a Cylinder low of 0x14 indicates that the device
-        * does support packet commands.
+        * In attempt to distinguish between HP CDRW's and Flash readers, we now
+        * execute the IDENTIFY PACKET DEVICE command. On ATA devices (i.e. flash
+        * readers), this command should fail with error. On ATAPI devices (i.e.
+        * CDROM drives), it should succeed.
         */
-       rc = usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, &status);
-       if (rc != USB_STOR_XFER_GOOD)
-               return USB_STOR_TRANSPORT_ERROR;
+       rc = usbat_write(us, USBAT_ATA, USBAT_ATA_CMD, 0xA1);
+       if (rc != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
 
-       US_DEBUGP("usbat_identify_device: Cylinder low is %02X\n", status);
+       rc = usbat_get_status(us, &status);
+       if (rc != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
 
-       if (status == 0x14) {
+       // Check for error bit
+       if (status & 0x01) {
+                // Device is a CompactFlash reader/writer
+               US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
+               info->devicetype = USBAT_DEV_FLASH;
+       } else {
                // Device is HP 8200
                US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n");
                info->devicetype = USBAT_DEV_HP8200;
-       } else {
-               // Device is a CompactFlash reader/writer
-               US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
-               info->devicetype = USBAT_DEV_FLASH;
        }
 
        return USB_STOR_TRANSPORT_GOOD;
@@ -1239,16 +1236,10 @@ static int usbat_select_and_test_registers(struct us_data *us)
 {
        int selector;
        unsigned char *status = us->iobuf;
-       unsigned char max_selector = 0xB0;
-       if (usbat_get_device_type(us) == USBAT_DEV_FLASH)
-               max_selector = 0xA0;
 
        // try device = master, then device = slave.
-
-       for (selector = 0xA0; selector <= max_selector; selector += 0x10) {
-
-               if (usbat_get_device_type(us) == USBAT_DEV_HP8200 &&
-                       usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != 
+       for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
+               if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
                                USB_STOR_XFER_GOOD)
                        return USB_STOR_TRANSPORT_ERROR;
 
@@ -1334,60 +1325,30 @@ int init_usbat(struct us_data *us)
 
        US_DEBUGP("INIT 3\n");
 
-       // At this point, we need to detect which device we are using
-       if (usbat_set_transport(us, info))
-               return USB_STOR_TRANSPORT_ERROR;
-
-       US_DEBUGP("INIT 4\n");
-
-       if (usbat_get_device_type(us) == USBAT_DEV_HP8200) {
-               msleep(250);
-
-               // Write 0x80 to ISA port 0x3F
-               rc = usbat_write(us, USBAT_ISA, 0x3F, 0x80);
-               if (rc != USB_STOR_XFER_GOOD)
-                       return USB_STOR_TRANSPORT_ERROR;
-
-               US_DEBUGP("INIT 5\n");
-
-               // Read ISA port 0x27
-               rc = usbat_read(us, USBAT_ISA, 0x27, status);
-               if (rc != USB_STOR_XFER_GOOD)
-                       return USB_STOR_TRANSPORT_ERROR;
-
-               US_DEBUGP("INIT 6\n");
-
-               rc = usbat_read_user_io(us, status);
-               if (rc != USB_STOR_XFER_GOOD)
-                       return USB_STOR_TRANSPORT_ERROR;
-
-               US_DEBUGP("INIT 7\n");
-       }
-
        rc = usbat_select_and_test_registers(us);
        if (rc != USB_STOR_TRANSPORT_GOOD)
                return rc;
 
-       US_DEBUGP("INIT 8\n");
+       US_DEBUGP("INIT 4\n");
 
        rc = usbat_read_user_io(us, status);
        if (rc != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       US_DEBUGP("INIT 9\n");
+       US_DEBUGP("INIT 5\n");
 
        // Enable peripheral control signals and card detect
        rc = usbat_device_enable_cdt(us);
        if (rc != USB_STOR_TRANSPORT_GOOD)
                return rc;
 
-       US_DEBUGP("INIT 10\n");
+       US_DEBUGP("INIT 6\n");
 
        rc = usbat_read_user_io(us, status);
        if (rc != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       US_DEBUGP("INIT 11\n");
+       US_DEBUGP("INIT 7\n");
 
        msleep(1400);
 
@@ -1395,13 +1356,19 @@ int init_usbat(struct us_data *us)
        if (rc != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       US_DEBUGP("INIT 12\n");
+       US_DEBUGP("INIT 8\n");
 
        rc = usbat_select_and_test_registers(us);
        if (rc != USB_STOR_TRANSPORT_GOOD)
                return rc;
 
-       US_DEBUGP("INIT 13\n");
+       US_DEBUGP("INIT 9\n");
+
+       // At this point, we need to detect which device we are using
+       if (usbat_set_transport(us, info))
+               return USB_STOR_TRANSPORT_ERROR;
+
+       US_DEBUGP("INIT 10\n");
 
        if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { 
                subcountH = 0x02;
@@ -1412,7 +1379,7 @@ int init_usbat(struct us_data *us)
        if (rc != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       US_DEBUGP("INIT 14\n");
+       US_DEBUGP("INIT 11\n");
 
        return USB_STOR_TRANSPORT_GOOD;
 }
index e6b1c6cf07f24a66eea868df9730e0baac53f15b..c1ba5301ebfc95764f3fb587846339a9acd606c8 100644 (file)
@@ -96,8 +96,8 @@
  * or before the URB_ACTIVE bit was set.  If so, it's essential to cancel
  * the URB if it hasn't been cancelled already (i.e., if the URB_ACTIVE bit
  * is still set).  Either way, the function must then wait for the URB to
- * finish.  Note that because the URB_ASYNC_UNLINK flag is set, the URB can
- * still be in progress even after a call to usb_unlink_urb() returns.
+ * finish.  Note that the URB can still be in progress even after a call to
+ * usb_unlink_urb() returns.
  *
  * The idea is that (1) once the ABORTING or DISCONNECTING bit is set,
  * either the stop_transport() function or the submitting function
@@ -158,8 +158,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
         * hasn't been mapped for DMA.  Yes, this is clunky, but it's
         * easier than always having the caller tell us whether the
         * transfer buffer has already been mapped. */
-       us->current_urb->transfer_flags =
-                       URB_ASYNC_UNLINK | URB_NO_SETUP_DMA_MAP;
+       us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP;
        if (us->current_urb->transfer_buffer == us->iobuf)
                us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        us->current_urb->transfer_dma = us->iobuf_dma;
@@ -611,7 +610,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                unsigned char old_sc_data_direction;
                unsigned char old_cmd_len;
                unsigned char old_cmnd[MAX_COMMAND_SIZE];
-               unsigned long old_serial_number;
                int old_resid;
 
                US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
@@ -648,10 +646,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                old_sg = srb->use_sg;
                srb->use_sg = 0;
 
-               /* change the serial number -- toggle the high bit*/
-               old_serial_number = srb->serial_number;
-               srb->serial_number ^= 0x80000000;
-
                /* issue the auto-sense command */
                old_resid = srb->resid;
                srb->resid = 0;
@@ -662,7 +656,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                srb->request_buffer = old_request_buffer;
                srb->request_bufflen = old_request_bufflen;
                srb->use_sg = old_sg;
-               srb->serial_number = old_serial_number;
                srb->sc_data_direction = old_sc_data_direction;
                srb->cmd_len = old_cmd_len;
                memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
@@ -985,7 +978,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = cpu_to_le32(transfer_length);
        bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
-       bcb->Tag = srb->serial_number;
+       bcb->Tag = ++us->tag;
        bcb->Lun = srb->device->lun;
        if (us->flags & US_FL_SCM_MULT_TARG)
                bcb->Lun |= srb->device->id << 4;
@@ -1074,7 +1067,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
                        le32_to_cpu(bcs->Signature), bcs->Tag, 
                        residue, bcs->Status);
-       if (bcs->Tag != srb->serial_number || bcs->Status > US_BULK_STAT_PHASE) {
+       if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) {
                US_DEBUGP("Bulk logical error\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
index bd0ab3039bdd56c6882857f0ff31a3788cd42b5f..ad0cfd7a782f2e8c5418d04c6e3f13563e9993f7 100644 (file)
@@ -79,6 +79,13 @@ UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001,
                US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), 
 #endif
 
+/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
+UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
+               "VIA Technologies Inc.",
+               "USB 2.0 Card Reader",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE ),
+
 /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
  * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
  * always fails and confuses drive.
@@ -929,6 +936,18 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
               US_FL_SINGLE_LUN ),
 #endif
 
+/* Submitted by: Nick Sillik <n.sillik@temple.edu>
+ * Needed for OneTouch extension to usb-storage
+ *
+ */
+#ifdef CONFIG_USB_STORAGE_ONETOUCH
+       UNUSUAL_DEV(  0x0d49, 0x7010, 0x0000, 0x9999,
+                       "Maxtor",
+                       "OneTouch External Harddrive",
+                       US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+                       0),
+#endif
+
 /* Submitted by Joris Struyve <joris@struyve.be> */
 UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
                "Medion",
index 77e7fc258aa2a7c104da2ba0a74a203525849d4d..cb4c770baf32a52be5d5ced2f0a3db946c43c359 100644 (file)
@@ -90,7 +90,9 @@
 #ifdef CONFIG_USB_STORAGE_JUMPSHOT
 #include "jumpshot.h"
 #endif
-
+#ifdef CONFIG_USB_STORAGE_ONETOUCH
+#include "onetouch.h"
+#endif
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -786,6 +788,7 @@ static void usb_stor_release_resources(struct us_data *us)
         * any more commands.
         */
        US_DEBUGP("-- sending exit command to thread\n");
+       set_bit(US_FLIDX_DISCONNECTING, &us->flags);
        up(&us->sema);
 
        /* Call the destructor routine, if it exists */
@@ -816,6 +819,49 @@ static void dissociate_dev(struct us_data *us)
        usb_set_intfdata(us->pusb_intf, NULL);
 }
 
+/* First stage of disconnect processing: stop all commands and remove
+ * the host */
+static void quiesce_and_remove_host(struct us_data *us)
+{
+       /* Prevent new USB transfers, stop the current command, and
+        * interrupt a SCSI-scan or device-reset delay */
+       set_bit(US_FLIDX_DISCONNECTING, &us->flags);
+       usb_stor_stop_transport(us);
+       wake_up(&us->delay_wait);
+
+       /* It doesn't matter if the SCSI-scanning thread is still running.
+        * The thread will exit when it sees the DISCONNECTING flag. */
+
+       /* Wait for the current command to finish, then remove the host */
+       down(&us->dev_semaphore);
+       up(&us->dev_semaphore);
+
+       /* queuecommand won't accept any new commands and the control
+        * thread won't execute a previously-queued command.  If there
+        * is such a command pending, complete it with an error. */
+       if (us->srb) {
+               us->srb->result = DID_NO_CONNECT << 16;
+               scsi_lock(us_to_host(us));
+               us->srb->scsi_done(us->srb);
+               us->srb = NULL;
+               scsi_unlock(us_to_host(us));
+       }
+
+       /* Now we own no commands so it's safe to remove the SCSI host */
+       scsi_remove_host(us_to_host(us));
+}
+
+/* Second stage of disconnect processing: deallocate all resources */
+static void release_everything(struct us_data *us)
+{
+       usb_stor_release_resources(us);
+       dissociate_dev(us);
+
+       /* Drop our reference to the host; the SCSI core will free it
+        * (and "us" along with it) when the refcount becomes 0. */
+       scsi_host_put(us_to_host(us));
+}
+
 /* Thread to carry out delayed SCSI-device scanning */
 static int usb_stor_scan_thread(void * __us)
 {
@@ -956,7 +1002,7 @@ static int storage_probe(struct usb_interface *intf,
        if (result < 0) {
                printk(KERN_WARNING USB_STORAGE 
                       "Unable to start the device-scanning thread\n");
-               scsi_remove_host(host);
+               quiesce_and_remove_host(us);
                goto BadDevice;
        }
        atomic_inc(&total_threads);
@@ -969,10 +1015,7 @@ static int storage_probe(struct usb_interface *intf,
        /* We come here if there are any problems */
 BadDevice:
        US_DEBUGP("storage_probe() failed\n");
-       set_bit(US_FLIDX_DISCONNECTING, &us->flags);
-       usb_stor_release_resources(us);
-       dissociate_dev(us);
-       scsi_host_put(host);
+       release_everything(us);
        return result;
 }
 
@@ -982,28 +1025,8 @@ static void storage_disconnect(struct usb_interface *intf)
        struct us_data *us = usb_get_intfdata(intf);
 
        US_DEBUGP("storage_disconnect() called\n");
-
-       /* Prevent new USB transfers, stop the current command, and
-        * interrupt a SCSI-scan or device-reset delay */
-       set_bit(US_FLIDX_DISCONNECTING, &us->flags);
-       usb_stor_stop_transport(us);
-       wake_up(&us->delay_wait);
-
-       /* It doesn't matter if the SCSI-scanning thread is still running.
-        * The thread will exit when it sees the DISCONNECTING flag. */
-
-       /* Wait for the current command to finish, then remove the host */
-       down(&us->dev_semaphore);
-       up(&us->dev_semaphore);
-       scsi_remove_host(us_to_host(us));
-
-       /* Wait for everything to become idle and release all our resources */
-       usb_stor_release_resources(us);
-       dissociate_dev(us);
-
-       /* Drop our reference to the host; the SCSI core will free it
-        * (and "us" along with it) when the refcount becomes 0. */
-       scsi_host_put(us_to_host(us));
+       quiesce_and_remove_host(us);
+       release_everything(us);
 }
 
 /***********************************************************************
index 625b7aa98074112080590a3e104f8288b9f85021..a195adae57b6ebc26d9100446c490c03f2f77256 100644 (file)
@@ -158,6 +158,7 @@ struct us_data {
 
        /* SCSI interfaces */
        struct scsi_cmnd        *srb;            /* current srb         */
+       unsigned int            tag;             /* current dCBWTag     */
 
        /* thread information */
        int                     pid;             /* control thread       */
index 52b16850a54efe399ce7ba520a1624b6c1459045..30f80c23f934bb0a76719232f492153fc7cca00a 100644 (file)
@@ -1473,10 +1473,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        par->Chipset = (pd->vendor << 16) | pd->device;
        printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
 
-#ifdef CONFIG_PCI_NAMES
-       printk(KERN_INFO PFX "%s\n", pd->pretty_name);
-#endif
-
        if (par->Architecture == 0) {
                printk(KERN_ERR PFX "unknown NV_ARCH\n");
                goto err_out_free_base0;
index ae297e222681d73fc4e283a60fa439fe88fa6d30..3e9f96e9237d8cd3fc45080c0aa5b83219a79a7d 100644 (file)
@@ -1936,10 +1936,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
        default_par->Chipset = (pd->vendor << 16) | pd->device;
        printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
        
-#ifdef CONFIG_PCI_NAMES
-       printk(KERN_INFO PFX "%s\n", pd->pretty_name);
-#endif
-
        if(default_par->riva.Architecture == 0) {
                printk(KERN_ERR PFX "unknown NV_ARCH\n");
                ret=-ENODEV;
index 711b90903e7b64277b76b8654e331deb304d270e..9a1e00dd3e02a45363911ce7ee04e3a680b87796 100644 (file)
@@ -54,4 +54,20 @@ config W1_SMEM
          Say Y here if you want to connect 1-wire
          simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
 
+config W1_DS2433
+       tristate "4kb EEPROM family support (DS2433)"
+       depends on W1
+       help
+         Say Y here if you want to use a 1-wire
+         4kb EEPROM family device (DS2433).
+
+config W1_DS2433_CRC
+       bool "Protect DS2433 data with a CRC16"
+       depends on W1_DS2433
+       select CRC16
+       help
+         Say Y here to protect DS2433 data with a CRC16.
+         Each block has 30 bytes of data and a two byte CRC16.
+         Full block writes are only allowed if the CRC is valid.
+
 endmenu
index 80725c348e704fe185d441aa6c6747747b6e3250..01fb54391470e78cc60959028528d3a7ac2b2971 100644 (file)
@@ -6,6 +6,10 @@ ifneq ($(CONFIG_NET), y)
 EXTRA_CFLAGS   += -DNETLINK_DISABLED
 endif
 
+ifeq ($(CONFIG_W1_DS2433_CRC), y)
+EXTRA_CFLAGS   += -DCONFIG_W1_F23_CRC
+endif
+
 obj-$(CONFIG_W1)       += wire.o
 wire-objs              := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o
 
@@ -13,8 +17,9 @@ obj-$(CONFIG_W1_MATROX)               += matrox_w1.o
 obj-$(CONFIG_W1_THERM)         += w1_therm.o
 obj-$(CONFIG_W1_SMEM)          += w1_smem.o
 
-obj-$(CONFIG_W1_DS9490)                += ds9490r.o 
+obj-$(CONFIG_W1_DS9490)                += ds9490r.o
 ds9490r-objs    := dscore.o
 
 obj-$(CONFIG_W1_DS9490_BRIDGE) += ds_w1_bridge.o
 
+obj-$(CONFIG_W1_DS2433)                += w1_ds2433.o
index 7bddd8ac7d7f7a615c3fe5e71b1078e244875719..a79d16d5666ff557dadc3b2e7bb895641e6b0fe1 100644 (file)
@@ -1,8 +1,8 @@
 /*
- *     ds_w1_bridge.c
+ *     ds_w1_bridge.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -25,7 +25,7 @@
 #include "../w1/w1.h"
 #include "../w1/w1_int.h"
 #include "dscore.h"
-       
+
 static struct ds_device *ds_dev;
 static struct w1_bus_master *ds_bus_master;
 
@@ -120,7 +120,7 @@ static u8 ds9490r_reset(unsigned long data)
 static int __devinit ds_w1_init(void)
 {
        int err;
-       
+
        ds_bus_master = kmalloc(sizeof(*ds_bus_master), GFP_KERNEL);
        if (!ds_bus_master) {
                printk(KERN_ERR "Failed to allocate DS9490R USB<->W1 bus_master structure.\n");
@@ -136,14 +136,14 @@ static int __devinit ds_w1_init(void)
 
        memset(ds_bus_master, 0, sizeof(*ds_bus_master));
 
-       ds_bus_master->data             = (unsigned long)ds_dev;
-       ds_bus_master->touch_bit        = &ds9490r_touch_bit;
-       ds_bus_master->read_bit         = &ds9490r_read_bit;
-       ds_bus_master->write_bit        = &ds9490r_write_bit;
-       ds_bus_master->read_byte        = &ds9490r_read_byte;
-       ds_bus_master->write_byte       = &ds9490r_write_byte;
-       ds_bus_master->read_block       = &ds9490r_read_block;
-       ds_bus_master->write_block      = &ds9490r_write_block;
+       ds_bus_master->data             = (unsigned long)ds_dev;
+       ds_bus_master->touch_bit        = &ds9490r_touch_bit;
+       ds_bus_master->read_bit         = &ds9490r_read_bit;
+       ds_bus_master->write_bit        = &ds9490r_write_bit;
+       ds_bus_master->read_byte        = &ds9490r_read_byte;
+       ds_bus_master->write_byte       = &ds9490r_write_byte;
+       ds_bus_master->read_block       = &ds9490r_read_block;
+       ds_bus_master->write_block      = &ds9490r_write_block;
        ds_bus_master->reset_bus        = &ds9490r_reset;
 
        err = w1_add_master_device(ds_bus_master);
index eee6644d33d6e60ee89e5eb0cffe8e84ae6c9d38..15fb250451e59a0628029819dfebbfc62d7fede9 100644 (file)
@@ -1,8 +1,8 @@
 /*
- *     dscore.c
+ *     dscore.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -32,19 +32,16 @@ static struct usb_device_id ds_id_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, ds_id_table);
 
-int ds_probe(struct usb_interface *, const struct usb_device_id *);
-void ds_disconnect(struct usb_interface *);
+static int ds_probe(struct usb_interface *, const struct usb_device_id *);
+static void ds_disconnect(struct usb_interface *);
 
 int ds_touch_bit(struct ds_device *, u8, u8 *);
 int ds_read_byte(struct ds_device *, u8 *);
 int ds_read_bit(struct ds_device *, u8 *);
 int ds_write_byte(struct ds_device *, u8);
 int ds_write_bit(struct ds_device *, u8);
-int ds_start_pulse(struct ds_device *, int);
-int ds_set_speed(struct ds_device *, int);
+static int ds_start_pulse(struct ds_device *, int);
 int ds_reset(struct ds_device *, struct ds_status *);
-int ds_detect(struct ds_device *, struct ds_status *);
-int ds_stop_pulse(struct ds_device *, int);
 struct ds_device * ds_get_device(void);
 void ds_put_device(struct ds_device *);
 
@@ -79,11 +76,11 @@ void ds_put_device(struct ds_device *dev)
 static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
 {
        int err;
-       
-       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), 
+
+       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
                        CONTROL_CMD, 0x40, value, index, NULL, 0, 1000);
        if (err < 0) {
-               printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", 
+               printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",
                                value, index, err);
                return err;
        }
@@ -94,11 +91,11 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
 static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
 {
        int err;
-       
-       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), 
+
+       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
                        MODE_CMD, 0x40, value, index, NULL, 0, 1000);
        if (err < 0) {
-               printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", 
+               printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",
                                value, index, err);
                return err;
        }
@@ -109,11 +106,11 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
 static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
 {
        int err;
-       
-       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), 
+
+       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
                        COMM_CMD, 0x40, value, index, NULL, 0, 1000);
        if (err < 0) {
-               printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", 
+               printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",
                                value, index, err);
                return err;
        }
@@ -126,19 +123,20 @@ static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int of
        printk("%45s: %8x\n", str, buf[off]);
 }
 
-int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, unsigned char *buf, int size)
+static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
+                                unsigned char *buf, int size)
 {
        int count, err;
-               
+
        memset(st, 0, sizeof(st));
-       
+
        count = 0;
        err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100);
        if (err < 0) {
                printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err);
                return err;
        }
-       
+
        if (count >= sizeof(*st))
                memcpy(st, buf, sizeof(*st));
 
@@ -149,13 +147,13 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
 {
        unsigned char buf[64];
        int count, err = 0, i;
-       
+
        memcpy(st, buf, sizeof(*st));
-               
+
        count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
        if (count < 0)
                return err;
-       
+
        printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
        for (i=0; i<count; ++i)
                printk("%02x ", buf[i]);
@@ -199,7 +197,7 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
                        return err;
        }
 #endif
-       
+
        return err;
 }
 
@@ -207,9 +205,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
 {
        int count, err;
        struct ds_status st;
-       
+
        count = 0;
-       err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), 
+       err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
                                buf, size, &count, 1000);
        if (err < 0) {
                printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
@@ -234,7 +232,7 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
 static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
 {
        int count, err;
-       
+
        count = 0;
        err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
        if (err < 0) {
@@ -245,12 +243,14 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
        return err;
 }
 
+#if 0
+
 int ds_stop_pulse(struct ds_device *dev, int limit)
 {
        struct ds_status st;
        int count = 0, err = 0;
        u8 buf[0x20];
-       
+
        do {
                err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
                if (err)
@@ -275,7 +275,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
 int ds_detect(struct ds_device *dev, struct ds_status *st)
 {
        int err;
-       
+
        err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
        if (err)
                return err;
@@ -283,11 +283,11 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
        err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);
        if (err)
                return err;
-       
+
        err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);
        if (err)
                return err;
-       
+
        err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);
        if (err)
                return err;
@@ -297,7 +297,9 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
        return err;
 }
 
-int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+#endif  /*  0  */
+
+static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
 {
        u8 buf[0x20];
        int err, count = 0;
@@ -305,7 +307,7 @@ int ds_wait_status(struct ds_device *dev, struct ds_status *st)
        do {
                err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
 #if 0
-               if (err >= 0) { 
+               if (err >= 0) {
                        int i;
                        printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
                        for (i=0; i<err; ++i)
@@ -319,10 +321,8 @@ int ds_wait_status(struct ds_device *dev, struct ds_status *st)
        if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {
                ds_recv_status(dev, st);
                return -1;
-       }
-       else {
+       } else
                return 0;
-       }
 }
 
 int ds_reset(struct ds_device *dev, struct ds_status *st)
@@ -345,6 +345,7 @@ int ds_reset(struct ds_device *dev, struct ds_status *st)
        return 0;
 }
 
+#if 0
 int ds_set_speed(struct ds_device *dev, int speed)
 {
        int err;
@@ -356,20 +357,21 @@ int ds_set_speed(struct ds_device *dev, int speed)
                speed = SPEED_FLEXIBLE;
 
        speed &= 0xff;
-       
+
        err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);
        if (err)
                return err;
 
        return err;
 }
+#endif  /*  0  */
 
-int ds_start_pulse(struct ds_device *dev, int delay)
+static int ds_start_pulse(struct ds_device *dev, int delay)
 {
        int err;
        u8 del = 1 + (u8)(delay >> 4);
        struct ds_status st;
-       
+
 #if 0
        err = ds_stop_pulse(dev, 10);
        if (err)
@@ -390,7 +392,7 @@ int ds_start_pulse(struct ds_device *dev, int delay)
        mdelay(delay);
 
        ds_wait_status(dev, &st);
-       
+
        return err;
 }
 
@@ -400,7 +402,7 @@ int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
        struct ds_status st;
        u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
        u16 cmd;
-       
+
        err = ds_send_control(dev, value, 0);
        if (err)
                return err;
@@ -430,7 +432,7 @@ int ds_write_bit(struct ds_device *dev, u8 bit)
 {
        int err;
        struct ds_status st;
-       
+
        err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0);
        if (err)
                return err;
@@ -445,7 +447,7 @@ int ds_write_byte(struct ds_device *dev, u8 byte)
        int err;
        struct ds_status st;
        u8 rbyte;
-       
+
        err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte);
        if (err)
                return err;
@@ -453,11 +455,11 @@ int ds_write_byte(struct ds_device *dev, u8 byte)
        err = ds_wait_status(dev, &st);
        if (err)
                return err;
-               
+
        err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
        if (err < 0)
                return err;
-       
+
        ds_start_pulse(dev, PULLUP_PULSE_DURATION);
 
        return !(byte == rbyte);
@@ -470,11 +472,11 @@ int ds_read_bit(struct ds_device *dev, u8 *bit)
        err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
        if (err)
                return err;
-       
+
        err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0);
        if (err)
                return err;
-       
+
        err = ds_recv_data(dev, bit, sizeof(*bit));
        if (err < 0)
                return err;
@@ -492,7 +494,7 @@ int ds_read_byte(struct ds_device *dev, u8 *byte)
                return err;
 
        ds_wait_status(dev, &st);
-       
+
        err = ds_recv_data(dev, byte, sizeof(*byte));
        if (err < 0)
                return err;
@@ -509,17 +511,17 @@ int ds_read_block(struct ds_device *dev, u8 *buf, int len)
                return -E2BIG;
 
        memset(buf, 0xFF, len);
-       
+
        err = ds_send_data(dev, buf, len);
        if (err < 0)
                return err;
-       
+
        err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
        if (err)
                return err;
 
        ds_wait_status(dev, &st);
-       
+
        memset(buf, 0x00, len);
        err = ds_recv_data(dev, buf, len);
 
@@ -530,11 +532,11 @@ int ds_write_block(struct ds_device *dev, u8 *buf, int len)
 {
        int err;
        struct ds_status st;
-       
+
        err = ds_send_data(dev, buf, len);
        if (err < 0)
                return err;
-       
+
        ds_wait_status(dev, &st);
 
        err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
@@ -548,10 +550,12 @@ int ds_write_block(struct ds_device *dev, u8 *buf, int len)
                return err;
 
        ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-       
+
        return !(err == len);
 }
 
+#if 0
+
 int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search)
 {
        int err;
@@ -559,11 +563,11 @@ int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int condi
        struct ds_status st;
 
        memset(buf, 0, sizeof(buf));
-       
+
        err = ds_send_data(ds_dev, (unsigned char *)&init, 8);
        if (err)
                return err;
-       
+
        ds_wait_status(ds_dev, &st);
 
        value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS;
@@ -589,7 +593,7 @@ int ds_match_access(struct ds_device *dev, u64 init)
        err = ds_send_data(dev, (unsigned char *)&init, sizeof(init));
        if (err)
                return err;
-       
+
        ds_wait_status(dev, &st);
 
        err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055);
@@ -609,11 +613,11 @@ int ds_set_path(struct ds_device *dev, u64 init)
 
        memcpy(buf, &init, 8);
        buf[8] = BRANCH_MAIN;
-       
+
        err = ds_send_data(dev, buf, sizeof(buf));
        if (err)
                return err;
-       
+
        ds_wait_status(dev, &st);
 
        err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0);
@@ -625,7 +629,10 @@ int ds_set_path(struct ds_device *dev, u64 init)
        return 0;
 }
 
-int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
+#endif  /*  0  */
+
+static int ds_probe(struct usb_interface *intf,
+                   const struct usb_device_id *udev_id)
 {
        struct usb_device *udev = interface_to_usbdev(intf);
        struct usb_endpoint_descriptor *endpoint;
@@ -653,7 +660,7 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
                printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err);
                return err;
        }
-       
+
        iface_desc = &intf->altsetting[0];
        if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
                printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints);
@@ -662,37 +669,37 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
 
        atomic_set(&ds_dev->refcnt, 0);
        memset(ds_dev->ep, 0, sizeof(ds_dev->ep));
-       
+
        /*
-        * This loop doesn'd show control 0 endpoint, 
+        * This loop doesn'd show control 0 endpoint,
         * so we will fill only 1-3 endpoints entry.
         */
        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
                endpoint = &iface_desc->endpoint[i].desc;
 
                ds_dev->ep[i+1] = endpoint->bEndpointAddress;
-               
+
                printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
                        i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
                        (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
                        endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
        }
-       
+
 #if 0
        {
                int err, i;
                u64 buf[3];
                u64 init=0xb30000002078ee81ull;
                struct ds_status st;
-               
+
                ds_reset(ds_dev, &st);
                err = ds_search(ds_dev, init, buf, 3, 0);
                if (err < 0)
                        return err;
                for (i=0; i<err; ++i)
                        printk("%d: %llx\n", i, buf[i]);
-               
-               printk("Resetting...\n");       
+
+               printk("Resetting...\n");
                ds_reset(ds_dev, &st);
                printk("Setting path for %llx.\n", init);
                err = ds_set_path(ds_dev, init);
@@ -707,12 +714,12 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
                err = ds_search(ds_dev, init, buf, 3, 0);
 
                printk("ds_search() returned %d\n", err);
-               
+
                if (err < 0)
                        return err;
                for (i=0; i<err; ++i)
                        printk("%d: %llx\n", i, buf[i]);
-               
+
                return 0;
        }
 #endif
@@ -720,10 +727,10 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
        return 0;
 }
 
-void ds_disconnect(struct usb_interface *intf)
+static void ds_disconnect(struct usb_interface *intf)
 {
        struct ds_device *dev;
-       
+
        dev = usb_get_intfdata(intf);
        usb_set_intfdata(intf, NULL);
 
@@ -740,7 +747,7 @@ void ds_disconnect(struct usb_interface *intf)
        ds_dev = NULL;
 }
 
-int ds_init(void)
+static int ds_init(void)
 {
        int err;
 
@@ -753,7 +760,7 @@ int ds_init(void)
        return 0;
 }
 
-void ds_fini(void)
+static void ds_fini(void)
 {
        usb_deregister(&ds_driver);
 }
@@ -776,8 +783,8 @@ EXPORT_SYMBOL(ds_get_device);
 EXPORT_SYMBOL(ds_put_device);
 
 /*
- * This functions can be used for EEPROM programming, 
- * when driver will be included into mainline this will 
+ * This functions can be used for EEPROM programming,
+ * when driver will be included into mainline this will
  * require uncommenting.
  */
 #if 0
index 9c767ef4ac2488e9fc1d90d84da357a746057144..6cf5671d6ebea601dbd6d83a172bed0cd4e738a8 100644 (file)
@@ -1,8 +1,8 @@
 /*
- *     dscore.h
+ *     dscore.h
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
 
 struct ds_device
 {
-       struct usb_device       *udev;
+       struct usb_device       *udev;
        struct usb_interface    *intf;
 
        int                     ep[NUM_EP];
@@ -156,11 +156,7 @@ int ds_read_byte(struct ds_device *, u8 *);
 int ds_read_bit(struct ds_device *, u8 *);
 int ds_write_byte(struct ds_device *, u8);
 int ds_write_bit(struct ds_device *, u8);
-int ds_start_pulse(struct ds_device *, int);
-int ds_set_speed(struct ds_device *, int);
 int ds_reset(struct ds_device *, struct ds_status *);
-int ds_detect(struct ds_device *, struct ds_status *);
-int ds_stop_pulse(struct ds_device *, int);
 struct ds_device * ds_get_device(void);
 void ds_put_device(struct ds_device *);
 int ds_write_block(struct ds_device *, u8 *, int);
index 0bbf029b1ef1658f99b537fa690a10186275b486..1b6b74c116a911c3f34c34ad86357cfe3a948dc5 100644 (file)
@@ -45,10 +45,12 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
 
 static int w1_timeout = 10;
+static int w1_control_timeout = 1;
 int w1_max_slave_count = 10;
 int w1_max_slave_ttl = 10;
 
 module_param_named(timeout, w1_timeout, int, 0);
+module_param_named(control_timeout, w1_control_timeout, int, 0);
 module_param_named(max_slave_count, w1_max_slave_count, int, 0);
 module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
 
@@ -59,19 +61,6 @@ static pid_t control_thread;
 static int control_needs_exit;
 static DECLARE_COMPLETION(w1_control_complete);
 
-/* stuff for the default family */
-static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-       return(sprintf(buf, "%s\n", sl->name));
-}
-static struct w1_family_ops w1_default_fops = {
-       .rname = &w1_famdefault_read_name,
-};
-static struct w1_family w1_default_family = {
-       .fops = &w1_default_fops,
-};
-
 static int w1_master_match(struct device *dev, struct device_driver *drv)
 {
        return 1;
@@ -82,73 +71,116 @@ static int w1_master_probe(struct device *dev)
        return -ENODEV;
 }
 
-static int w1_master_remove(struct device *dev)
-{
-       return 0;
-}
-
 static void w1_master_release(struct device *dev)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
 
-       complete(&md->dev_released);
+       dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name);
+
+       if (md->nls && md->nls->sk_socket)
+               sock_release(md->nls->sk_socket);
+       memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
+       kfree(md);
 }
 
 static void w1_slave_release(struct device *dev)
 {
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+       struct w1_slave *sl = dev_to_w1_slave(dev);
+
+       dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
+
+       while (atomic_read(&sl->refcnt)) {
+               dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
+                               sl->name, atomic_read(&sl->refcnt));
+               if (msleep_interruptible(1000))
+                       flush_signals(current);
+       }
+
+       w1_family_put(sl->family);
+       sl->master->slave_count--;
 
-       complete(&sl->dev_released);
+       complete(&sl->released);
 }
 
-static ssize_t w1_default_read_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       return sprintf(buf, "No family registered.\n");
+       struct w1_slave *sl = dev_to_w1_slave(dev);
+
+       return sprintf(buf, "%s\n", sl->name);
 }
 
-static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off,
-                    size_t count)
+static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
-       return sprintf(buf, "No family registered.\n");
+       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+
+       atomic_inc(&sl->refcnt);
+       if (off > 8) {
+               count = 0;
+       } else {
+               if (off + count > 8)
+                       count = 8 - off;
+
+               memcpy(buf, (u8 *)&sl->reg_num, count);
+       }
+       atomic_dec(&sl->refcnt);
+
+       return count;
 }
 
-static struct device_attribute w1_slave_attribute =
-       __ATTR(name, S_IRUGO, w1_default_read_name, NULL);
-
-static struct bin_attribute w1_slave_bin_attribute = {
-       .attr = {
-               .name = "w1_slave",
-               .mode = S_IRUGO,
-               .owner = THIS_MODULE,
-       },
-       .size = W1_SLAVE_DATA_SIZE,
-       .read = &w1_default_read_bin,
+static struct device_attribute w1_slave_attr_name =
+       __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
+
+static struct bin_attribute w1_slave_attr_bin_id = {
+      .attr = {
+              .name = "id",
+              .mode = S_IRUGO,
+              .owner = THIS_MODULE,
+      },
+      .size = 8,
+      .read = w1_slave_read_id,
 };
 
+/* Default family */
+static struct w1_family w1_default_family;
+
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
 
 static struct bus_type w1_bus_type = {
        .name = "w1",
        .match = w1_master_match,
+       .hotplug = w1_hotplug,
 };
 
-struct device_driver w1_driver = {
-       .name = "w1_driver",
+struct device_driver w1_master_driver = {
+       .name = "w1_master_driver",
        .bus = &w1_bus_type,
        .probe = w1_master_probe,
-       .remove = w1_master_remove,
 };
 
-struct device w1_device = {
+struct device w1_master_device = {
        .parent = NULL,
        .bus = &w1_bus_type,
        .bus_id = "w1 bus master",
-       .driver = &w1_driver,
+       .driver = &w1_master_driver,
        .release = &w1_master_release
 };
 
+struct device_driver w1_slave_driver = {
+       .name = "w1_slave_driver",
+       .bus = &w1_bus_type,
+};
+
+struct device w1_slave_device = {
+       .parent = NULL,
+       .bus = &w1_bus_type,
+       .bus_id = "w1 bus slave",
+       .driver = &w1_slave_driver,
+       .release = &w1_slave_release
+};
+
 static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        ssize_t count;
 
        if (down_interruptible (&md->mutex))
@@ -165,7 +197,7 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
                                                struct device_attribute *attr,
                                                const char * buf, size_t count)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
 
        if (down_interruptible (&md->mutex))
                return -EBUSY;
@@ -181,7 +213,7 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
                                               struct device_attribute *attr,
                                               char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        ssize_t count;
 
        if (down_interruptible (&md->mutex))
@@ -196,7 +228,7 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
 
 static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        ssize_t count;
 
        if (down_interruptible(&md->mutex))
@@ -217,7 +249,7 @@ static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct devic
 
 static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        ssize_t count;
 
        if (down_interruptible(&md->mutex))
@@ -231,7 +263,7 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, stru
 
 static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        ssize_t count;
 
        if (down_interruptible(&md->mutex))
@@ -245,7 +277,7 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct devi
 
 static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        ssize_t count;
 
        if (down_interruptible(&md->mutex))
@@ -259,7 +291,7 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
 
 static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct w1_master *md = container_of(dev, struct w1_master, dev);
+       struct w1_master *md = dev_to_w1_master(dev);
        int c = PAGE_SIZE;
 
        if (down_interruptible(&md->mutex))
@@ -329,12 +361,55 @@ void w1_destroy_master_attributes(struct w1_master *master)
        sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
 }
 
+#ifdef CONFIG_HOTPLUG
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+{
+       struct w1_master *md = NULL;
+       struct w1_slave *sl = NULL;
+       char *event_owner, *name;
+       int err, cur_index=0, cur_len=0;
+
+       if (dev->driver == &w1_master_driver) {
+               md = container_of(dev, struct w1_master, dev);
+               event_owner = "master";
+               name = md->name;
+       } else if (dev->driver == &w1_slave_driver) {
+               sl = container_of(dev, struct w1_slave, dev);
+               event_owner = "slave";
+               name = sl->name;
+       } else {
+               dev_dbg(dev, "Unknown hotplug event.\n");
+               return -EINVAL;
+       }
+
+       dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id);
+
+       if (dev->driver != &w1_slave_driver || !sl)
+               return 0;
+
+       err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
+       if (err)
+               return err;
+
+       err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
+       if (err)
+               return err;
+
+       return 0;
+};
+#else
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+{
+       return 0;
+}
+#endif
+
 static int __w1_attach_slave_device(struct w1_slave *sl)
 {
        int err;
 
        sl->dev.parent = &sl->master->dev;
-       sl->dev.driver = sl->master->driver;
+       sl->dev.driver = &w1_slave_driver;
        sl->dev.bus = &w1_bus_type;
        sl->dev.release = &w1_slave_release;
 
@@ -347,8 +422,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
                 (unsigned int) sl->reg_num.family,
                 (unsigned long long) sl->reg_num.id);
 
-       dev_dbg(&sl->dev, "%s: registering %s.\n", __func__,
-               &sl->dev.bus_id[0]);
+       dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]);
 
        err = device_register(&sl->dev);
        if (err < 0) {
@@ -358,36 +432,44 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
                return err;
        }
 
-       memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin));
-       memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name));
-
-       sl->attr_bin.read = sl->family->fops->rbin;
-       sl->attr_name.show = sl->family->fops->rname;
+       /* Create "name" entry */
+       err = device_create_file(&sl->dev, &w1_slave_attr_name);
+       if (err < 0) {
+               dev_err(&sl->dev,
+                       "sysfs file creation for [%s] failed. err=%d\n",
+                       sl->dev.bus_id, err);
+               goto out_unreg;
+       }
 
-       err = device_create_file(&sl->dev, &sl->attr_name);
+       /* Create "id" entry */
+       err = sysfs_create_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
        if (err < 0) {
                dev_err(&sl->dev,
                        "sysfs file creation for [%s] failed. err=%d\n",
                        sl->dev.bus_id, err);
-               device_unregister(&sl->dev);
-               return err;
+               goto out_rem1;
        }
 
-       if ( sl->attr_bin.read ) {
-               err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);
-               if (err < 0) {
-                       dev_err(&sl->dev,
-                               "sysfs file creation for [%s] failed. err=%d\n",
-                               sl->dev.bus_id, err);
-                       device_remove_file(&sl->dev, &sl->attr_name);
-                       device_unregister(&sl->dev);
-                       return err;
-               }
+       /* if the family driver needs to initialize something... */
+       if (sl->family->fops && sl->family->fops->add_slave &&
+           ((err = sl->family->fops->add_slave(sl)) < 0)) {
+               dev_err(&sl->dev,
+                       "sysfs file creation for [%s] failed. err=%d\n",
+                       sl->dev.bus_id, err);
+               goto out_rem2;
        }
 
        list_add_tail(&sl->w1_slave_entry, &sl->master->slist);
 
        return 0;
+
+out_rem2:
+       sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+out_rem1:
+       device_remove_file(&sl->dev, &w1_slave_attr_name);
+out_unreg:
+       device_unregister(&sl->dev);
+       return err;
 }
 
 static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
@@ -413,7 +495,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
 
        memcpy(&sl->reg_num, rn, sizeof(sl->reg_num));
        atomic_set(&sl->refcnt, 0);
-       init_completion(&sl->dev_released);
+       init_completion(&sl->released);
 
        spin_lock(&w1_flock);
        f = w1_family_registered(rn->family);
@@ -452,28 +534,23 @@ static void w1_slave_detach(struct w1_slave *sl)
 {
        struct w1_netlink_msg msg;
 
-       dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);
-
-       while (atomic_read(&sl->refcnt)) {
-               printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
-                               sl->name, atomic_read(&sl->refcnt));
+       dev_dbg(&sl->dev, "%s: detaching %s [%p].\n", __func__, sl->name, sl);
 
-               if (msleep_interruptible(1000))
-                       flush_signals(current);
-       }
-
-       if ( sl->attr_bin.read ) {
-               sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
-       }
-       device_remove_file(&sl->dev, &sl->attr_name);
-       device_unregister(&sl->dev);
-       w1_family_put(sl->family);
+       list_del(&sl->w1_slave_entry);
 
-       sl->master->slave_count--;
+       if (sl->family->fops && sl->family->fops->remove_slave)
+               sl->family->fops->remove_slave(sl);
 
        memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
        msg.type = W1_SLAVE_REMOVE;
        w1_netlink_send(sl->master, &msg);
+
+       sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+       device_remove_file(&sl->dev, &w1_slave_attr_name);
+       device_unregister(&sl->dev);
+
+       wait_for_completion(&sl->released);
+       kfree(sl);
 }
 
 static struct w1_master *w1_search_master(unsigned long data)
@@ -500,14 +577,13 @@ void w1_reconnect_slaves(struct w1_family *f)
 
        spin_lock_bh(&w1_mlock);
        list_for_each_entry(dev, &w1_masters, w1_master_entry) {
-               dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
+               dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
                                dev->name, f->fid);
                set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
        }
        spin_unlock_bh(&w1_mlock);
 }
 
-
 static void w1_slave_found(unsigned long data, u64 rn)
 {
        int slave_count;
@@ -646,7 +722,7 @@ static int w1_control(void *data)
                have_to_wait = 0;
 
                try_to_freeze();
-               msleep_interruptible(w1_timeout * 1000);
+               msleep_interruptible(w1_control_timeout * 1000);
 
                if (signal_pending(current))
                        flush_signals(current);
@@ -679,33 +755,30 @@ static int w1_control(void *data)
                                list_del(&dev->w1_master_entry);
                                spin_unlock_bh(&w1_mlock);
 
+                               down(&dev->mutex);
                                list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
-                                       list_del(&sl->w1_slave_entry);
-
                                        w1_slave_detach(sl);
-                                       kfree(sl);
                                }
                                w1_destroy_master_attributes(dev);
+                               up(&dev->mutex);
                                atomic_dec(&dev->refcnt);
                                continue;
                        }
 
                        if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
-                               dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
+                               dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
                                down(&dev->mutex);
-                               list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
+                               list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
                                        if (sl->family->fid == W1_FAMILY_DEFAULT) {
                                                struct w1_reg_num rn;
-                                               list_del(&sl->w1_slave_entry);
-                                               w1_slave_detach(sl);
 
                                                memcpy(&rn, &sl->reg_num, sizeof(rn));
-
-                                               kfree(sl);
+                                               w1_slave_detach(sl);
 
                                                w1_attach_slave_device(dev, &rn);
                                        }
                                }
+                               dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
                                clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
                                up(&dev->mutex);
                        }
@@ -749,10 +822,7 @@ int w1_process(void *data)
 
                list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
                        if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
-                               list_del (&sl->w1_slave_entry);
-
-                               w1_slave_detach (sl);
-                               kfree (sl);
+                               w1_slave_detach(sl);
 
                                dev->slave_count--;
                        } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
@@ -783,7 +853,7 @@ static int w1_init(void)
                goto err_out_exit_init;
        }
 
-       retval = driver_register(&w1_driver);
+       retval = driver_register(&w1_master_driver);
        if (retval) {
                printk(KERN_ERR
                        "Failed to register master driver. err=%d.\n",
@@ -791,18 +861,29 @@ static int w1_init(void)
                goto err_out_bus_unregister;
        }
 
+       retval = driver_register(&w1_slave_driver);
+       if (retval) {
+               printk(KERN_ERR
+                       "Failed to register master driver. err=%d.\n",
+                       retval);
+               goto err_out_master_unregister;
+       }
+
        control_thread = kernel_thread(&w1_control, NULL, 0);
        if (control_thread < 0) {
                printk(KERN_ERR "Failed to create control thread. err=%d\n",
                        control_thread);
                retval = control_thread;
-               goto err_out_driver_unregister;
+               goto err_out_slave_unregister;
        }
 
        return 0;
 
-err_out_driver_unregister:
-       driver_unregister(&w1_driver);
+err_out_slave_unregister:
+       driver_unregister(&w1_slave_driver);
+
+err_out_master_unregister:
+       driver_unregister(&w1_master_driver);
 
 err_out_bus_unregister:
        bus_unregister(&w1_bus_type);
@@ -821,7 +902,8 @@ static void w1_fini(void)
        control_needs_exit = 1;
        wait_for_completion(&w1_control_complete);
 
-       driver_unregister(&w1_driver);
+       driver_unregister(&w1_slave_driver);
+       driver_unregister(&w1_master_driver);
        bus_unregister(&w1_bus_type);
 }
 
index 4f0a986e33e3f6332a688c35c1c2923ac1530ccd..d8900780c3bf1fbcfbf1933a3d42b1267c1b02e0 100644 (file)
@@ -75,11 +75,9 @@ struct w1_slave
 
        struct w1_master        *master;
        struct w1_family        *family;
+       void                    *family_data;
        struct device           dev;
-       struct completion       dev_released;
-
-       struct bin_attribute    attr_bin;
-       struct device_attribute attr_name;
+       struct completion       released;
 };
 
 typedef void (* w1_slave_found_callback)(unsigned long, u64);
@@ -179,7 +177,6 @@ struct w1_master
 
        struct device_driver    *driver;
        struct device           dev;
-       struct completion       dev_released;
        struct completion       dev_exited;
 
        struct w1_bus_master    *bus_master;
@@ -191,6 +188,21 @@ struct w1_master
 int w1_create_master_attributes(struct w1_master *);
 void w1_search(struct w1_master *dev, w1_slave_found_callback cb);
 
+static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
+{
+       return container_of(dev, struct w1_slave, dev);
+}
+
+static inline struct w1_slave* kobj_to_w1_slave(struct kobject *kobj)
+{
+       return dev_to_w1_slave(container_of(kobj, struct device, kobj));
+}
+
+static inline struct w1_master* dev_to_w1_master(struct device *dev)
+{
+       return container_of(dev, struct w1_master, dev);
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* __W1_H */
diff --git a/drivers/w1/w1_ds2433.c b/drivers/w1/w1_ds2433.c
new file mode 100644 (file)
index 0000000..b7c24b3
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ *     w1_ds2433.c - w1 family 23 (DS2433) driver
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#ifdef CONFIG_W1_F23_CRC
+#include <linux/crc16.h>
+#endif
+
+#include "w1.h"
+#include "w1_io.h"
+#include "w1_int.h"
+#include "w1_family.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("w1 family 23 driver for DS2433, 4kb EEPROM");
+
+#define W1_EEPROM_SIZE         512
+#define W1_PAGE_COUNT          16
+#define W1_PAGE_SIZE           32
+#define W1_PAGE_BITS           5
+#define W1_PAGE_MASK           0x1F
+
+#define W1_F23_TIME            300
+
+#define W1_F23_READ_EEPROM     0xF0
+#define W1_F23_WRITE_SCRATCH   0x0F
+#define W1_F23_READ_SCRATCH    0xAA
+#define W1_F23_COPY_SCRATCH    0x55
+
+struct w1_f23_data {
+       u8      memory[W1_EEPROM_SIZE];
+       u32     validcrc;
+};
+
+/**
+ * Check the file size bounds and adjusts count as needed.
+ * This would not be needed if the file size didn't reset to 0 after a write.
+ */
+static inline size_t w1_f23_fix_count(loff_t off, size_t count, size_t size)
+{
+       if (off > size)
+               return 0;
+
+       if ((off + count) > size)
+               return (size - off);
+
+       return count;
+}
+
+#ifdef CONFIG_W1_F23_CRC
+static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
+                               int block)
+{
+       u8      wrbuf[3];
+       int     off = block * W1_PAGE_SIZE;
+
+       if (data->validcrc & (1 << block))
+               return 0;
+
+       if (w1_reset_select_slave(sl)) {
+               data->validcrc = 0;
+               return -EIO;
+       }
+
+       wrbuf[0] = W1_F23_READ_EEPROM;
+       wrbuf[1] = off & 0xff;
+       wrbuf[2] = off >> 8;
+       w1_write_block(sl->master, wrbuf, 3);
+       w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
+
+       /* cache the block if the CRC is valid */
+       if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
+               data->validcrc |= (1 << block);
+
+       return 0;
+}
+#endif /* CONFIG_W1_F23_CRC */
+
+static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
+                              size_t count)
+{
+       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+#ifdef CONFIG_W1_F23_CRC
+       struct w1_f23_data *data = sl->family_data;
+       int i, min_page, max_page;
+#else
+       u8 wrbuf[3];
+#endif
+
+       if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
+               return 0;
+
+       atomic_inc(&sl->refcnt);
+       if (down_interruptible(&sl->master->mutex)) {
+               count = 0;
+               goto out_dec;
+       }
+
+#ifdef CONFIG_W1_F23_CRC
+
+       min_page = (off >> W1_PAGE_BITS);
+       max_page = (off + count - 1) >> W1_PAGE_BITS;
+       for (i = min_page; i <= max_page; i++) {
+               if (w1_f23_refresh_block(sl, data, i)) {
+                       count = -EIO;
+                       goto out_up;
+               }
+       }
+       memcpy(buf, &data->memory[off], count);
+
+#else  /* CONFIG_W1_F23_CRC */
+
+       /* read directly from the EEPROM */
+       if (w1_reset_select_slave(sl)) {
+               count = -EIO;
+               goto out_up;
+       }
+
+       wrbuf[0] = W1_F23_READ_EEPROM;
+       wrbuf[1] = off & 0xff;
+       wrbuf[2] = off >> 8;
+       w1_write_block(sl->master, wrbuf, 3);
+       w1_read_block(sl->master, buf, count);
+
+#endif /* CONFIG_W1_F23_CRC */
+
+out_up:
+       up(&sl->master->mutex);
+out_dec:
+       atomic_dec(&sl->refcnt);
+
+       return count;
+}
+
+/**
+ * Writes to the scratchpad and reads it back for verification.
+ * Then copies the scratchpad to EEPROM.
+ * The data must be on one page.
+ * The master must be locked.
+ *
+ * @param sl   The slave structure
+ * @param addr Address for the write
+ * @param len   length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK))
+ * @param data The data to write
+ * @return     0=Success -1=failure
+ */
+static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
+{
+       u8 wrbuf[4];
+       u8 rdbuf[W1_PAGE_SIZE + 3];
+       u8 es = (addr + len - 1) & 0x1f;
+
+       /* Write the data to the scratchpad */
+       if (w1_reset_select_slave(sl))
+               return -1;
+
+       wrbuf[0] = W1_F23_WRITE_SCRATCH;
+       wrbuf[1] = addr & 0xff;
+       wrbuf[2] = addr >> 8;
+
+       w1_write_block(sl->master, wrbuf, 3);
+       w1_write_block(sl->master, data, len);
+
+       /* Read the scratchpad and verify */
+       if (w1_reset_select_slave(sl))
+               return -1;
+
+       w1_write_8(sl->master, W1_F23_READ_SCRATCH);
+       w1_read_block(sl->master, rdbuf, len + 3);
+
+       /* Compare what was read against the data written */
+       if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
+           (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0))
+               return -1;
+
+       /* Copy the scratchpad to EEPROM */
+       if (w1_reset_select_slave(sl))
+               return -1;
+
+       wrbuf[0] = W1_F23_COPY_SCRATCH;
+       wrbuf[3] = es;
+       w1_write_block(sl->master, wrbuf, 4);
+
+       /* Sleep for 5 ms to wait for the write to complete */
+       msleep(5);
+
+       /* Reset the bus to wake up the EEPROM (this may not be needed) */
+       w1_reset_bus(sl->master);
+
+       return 0;
+}
+
+static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
+                               size_t count)
+{
+       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+       int addr, len, idx;
+
+       if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
+               return 0;
+
+#ifdef CONFIG_W1_F23_CRC
+       /* can only write full blocks in cached mode */
+       if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
+               dev_err(&sl->dev, "invalid offset/count off=%d cnt=%d\n",
+                       (int)off, count);
+               return -EINVAL;
+       }
+
+       /* make sure the block CRCs are valid */
+       for (idx = 0; idx < count; idx += W1_PAGE_SIZE) {
+               if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE) != CRC16_VALID) {
+                       dev_err(&sl->dev, "bad CRC at offset %d\n", (int)off);
+                       return -EINVAL;
+               }
+       }
+#endif /* CONFIG_W1_F23_CRC */
+
+       atomic_inc(&sl->refcnt);
+       if (down_interruptible(&sl->master->mutex)) {
+               count = 0;
+               goto out_dec;
+       }
+
+       /* Can only write data to one page at a time */
+       idx = 0;
+       while (idx < count) {
+               addr = off + idx;
+               len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK);
+               if (len > (count - idx))
+                       len = count - idx;
+
+               if (w1_f23_write(sl, addr, len, &buf[idx]) < 0) {
+                       count = -EIO;
+                       goto out_up;
+               }
+               idx += len;
+       }
+
+out_up:
+       up(&sl->master->mutex);
+out_dec:
+       atomic_dec(&sl->refcnt);
+
+       return count;
+}
+
+static struct bin_attribute w1_f23_bin_attr = {
+       .attr = {
+               .name = "eeprom",
+               .mode = S_IRUGO | S_IWUSR,
+               .owner = THIS_MODULE,
+       },
+       .size = W1_EEPROM_SIZE,
+       .read = w1_f23_read_bin,
+       .write = w1_f23_write_bin,
+};
+
+static int w1_f23_add_slave(struct w1_slave *sl)
+{
+       int err;
+#ifdef CONFIG_W1_F23_CRC
+       struct w1_f23_data *data;
+
+       data = kmalloc(sizeof(struct w1_f23_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       memset(data, 0, sizeof(struct w1_f23_data));
+       sl->family_data = data;
+
+#endif /* CONFIG_W1_F23_CRC */
+
+       err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
+
+#ifdef CONFIG_W1_F23_CRC
+       if (err)
+               kfree(data);
+#endif /* CONFIG_W1_F23_CRC */
+
+       return err;
+}
+
+static void w1_f23_remove_slave(struct w1_slave *sl)
+{
+#ifdef CONFIG_W1_F23_CRC
+       if (sl->family_data) {
+               kfree(sl->family_data);
+               sl->family_data = NULL;
+       }
+#endif /* CONFIG_W1_F23_CRC */
+       sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
+}
+
+static struct w1_family_ops w1_f23_fops = {
+       .add_slave      = w1_f23_add_slave,
+       .remove_slave   = w1_f23_remove_slave,
+};
+
+static struct w1_family w1_family_23 = {
+       .fid = W1_EEPROM_DS2433,
+       .fops = &w1_f23_fops,
+};
+
+static int __init w1_f23_init(void)
+{
+       return w1_register_family(&w1_family_23);
+}
+
+static void __exit w1_f23_fini(void)
+{
+       w1_unregister_family(&w1_family_23);
+}
+
+module_init(w1_f23_init);
+module_exit(w1_f23_fini);
index 02eee57d3c0cd2c46e394faf1617251944778e42..88c517a4c178fa7ed9f884aed5dd55d465c401e3 100644 (file)
@@ -29,23 +29,12 @@ DEFINE_SPINLOCK(w1_flock);
 static LIST_HEAD(w1_families);
 extern void w1_reconnect_slaves(struct w1_family *f);
 
-static int w1_check_family(struct w1_family *f)
-{
-       if (!f->fops->rname || !f->fops->rbin)
-               return -EINVAL;
-
-       return 0;
-}
-
 int w1_register_family(struct w1_family *newf)
 {
        struct list_head *ent, *n;
        struct w1_family *f;
        int ret = 0;
 
-       if (w1_check_family(newf))
-               return -EINVAL;
-
        spin_lock(&w1_flock);
        list_for_each_safe(ent, n, &w1_families) {
                f = list_entry(ent, struct w1_family, family_entry);
index b26da01bbc384c3b8b8fd627735e63e4d9cba96b..2ca0489c716a1f8083125cfecf3d3c0bfc31945c 100644 (file)
 #define W1_FAMILY_SMEM_81      0x81
 #define W1_THERM_DS18S20       0x10
 #define W1_THERM_DS1822        0x22
+#define W1_EEPROM_DS2433       0x23
 #define W1_THERM_DS18B20       0x28
 
 #define MAXNAMELEN             32
 
+struct w1_slave;
+
 struct w1_family_ops
 {
-       ssize_t (* rname)(struct device *, struct device_attribute *, char *);
-       ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);
+       int  (* add_slave)(struct w1_slave *);
+       void (* remove_slave)(struct w1_slave *);
 };
 
 struct w1_family
index 498ad505fa5f94360309063f7a72ec715ef75dd2..c3f67eafc7ec85f35a8bf696f6f9fe941d9d178d 100644 (file)
@@ -29,9 +29,9 @@
 
 static u32 w1_ids = 1;
 
-extern struct device_driver w1_driver;
+extern struct device_driver w1_master_driver;
 extern struct bus_type w1_bus_type;
-extern struct device w1_device;
+extern struct device w1_master_device;
 extern int w1_max_slave_count;
 extern int w1_max_slave_ttl;
 extern struct list_head w1_masters;
@@ -76,7 +76,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
        INIT_LIST_HEAD(&dev->slist);
        init_MUTEX(&dev->mutex);
 
-       init_completion(&dev->dev_released);
        init_completion(&dev->dev_exited);
 
        memcpy(&dev->dev, device, sizeof(struct device));
@@ -88,17 +87,14 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
 
        dev->groups = 1;
        dev->seq = 1;
-       dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
-       if (!dev->nls) {
-               printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
-                       NETLINK_NFLOG, dev->dev.bus_id);
-       }
+       dev_init_netlink(dev);
 
        err = device_register(&dev->dev);
        if (err) {
                printk(KERN_ERR "Failed to register master device. err=%d\n", err);
-               if (dev->nls && dev->nls->sk_socket)
-                       sock_release(dev->nls->sk_socket);
+
+               dev_fini_netlink(dev);
+
                memset(dev, 0, sizeof(struct w1_master));
                kfree(dev);
                dev = NULL;
@@ -107,13 +103,9 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
        return dev;
 }
 
-static void w1_free_dev(struct w1_master *dev)
+void w1_free_dev(struct w1_master *dev)
 {
        device_unregister(&dev->dev);
-       if (dev->nls && dev->nls->sk_socket)
-               sock_release(dev->nls->sk_socket);
-       memset(dev, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
-       kfree(dev);
 }
 
 int w1_add_master_device(struct w1_bus_master *master)
@@ -129,7 +121,7 @@ int w1_add_master_device(struct w1_bus_master *master)
                return(-EINVAL);
         }
 
-       dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);
+       dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
        if (!dev)
                return -ENOMEM;
 
@@ -188,7 +180,7 @@ void __w1_remove_master_device(struct w1_master *dev)
                         __func__, dev->kpid);
 
        while (atomic_read(&dev->refcnt)) {
-               printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
+               dev_dbg(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
                                dev->name, atomic_read(&dev->refcnt));
 
                if (msleep_interruptible(1000))
index 00f032220173863c3603dbc0d5f66ca005f9adb0..e2a043354ddfa3040fdc10c17350efb4c8fc653d 100644 (file)
@@ -277,6 +277,29 @@ void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
                w1_search(dev, cb);
 }
 
+/**
+ * Resets the bus and then selects the slave by sending either a skip rom
+ * or a rom match.
+ * The w1 master lock must be held.
+ *
+ * @param sl   the slave to select
+ * @return     0=success, anything else=error
+ */
+int w1_reset_select_slave(struct w1_slave *sl)
+{
+       if (w1_reset_bus(sl->master))
+               return -1;
+
+       if (sl->master->slave_count == 1)
+               w1_write_8(sl->master, W1_SKIP_ROM);
+       else {
+               u8 match[9] = {W1_MATCH_ROM, };
+               memcpy(&match[1], (u8 *)&sl->reg_num, 8);
+               w1_write_block(sl->master, match, 9);
+       }
+       return 0;
+}
+
 EXPORT_SYMBOL(w1_touch_bit);
 EXPORT_SYMBOL(w1_write_8);
 EXPORT_SYMBOL(w1_read_8);
@@ -286,3 +309,4 @@ EXPORT_SYMBOL(w1_delay);
 EXPORT_SYMBOL(w1_read_block);
 EXPORT_SYMBOL(w1_write_block);
 EXPORT_SYMBOL(w1_search_devices);
+EXPORT_SYMBOL(w1_reset_select_slave);
index af5829778aaa1fe9c72148386c97555066d39ed5..232860184a29ed62ae4a6166441b2c182cbabd97 100644 (file)
@@ -34,5 +34,6 @@ u8 w1_calc_crc8(u8 *, int);
 void w1_write_block(struct w1_master *, const u8 *, int);
 u8 w1_read_block(struct w1_master *, u8 *, int);
 void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
+int w1_reset_select_slave(struct w1_slave *sl);
 
 #endif /* __W1_IO_H */
index e7b774423dd65c56fce07dc13ca0017e713fb6f3..328645da79727f8eee095bce9c7d4d7047841d55 100644 (file)
@@ -57,10 +57,36 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
 nlmsg_failure:
        return;
 }
+
+int dev_init_netlink(struct w1_master *dev)
+{
+       dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
+       if (!dev->nls) {
+               printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
+                       NETLINK_W1, dev->dev.bus_id);
+       }
+
+       return 0;
+}
+
+void dev_fini_netlink(struct w1_master *dev)
+{
+       if (dev->nls && dev->nls->sk_socket)
+               sock_release(dev->nls->sk_socket);
+}
 #else
 #warning Netlink support is disabled. Please compile with NET support enabled.
 
 void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
 {
 }
+
+int dev_init_netlink(struct w1_master *dev)
+{
+       return 0;
+}
+
+void dev_fini_netlink(struct w1_master *dev)
+{
+}
 #endif
index 8615756946dfa988891d81ecc6be5b94d8ee496a..eb0c8b3152c8868059bcc01a3c8bb872fe3b15b3 100644 (file)
@@ -52,6 +52,8 @@ struct w1_netlink_msg
 #ifdef __KERNEL__
 
 void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *);
+int dev_init_netlink(struct w1_master *dev);
+void dev_fini_netlink(struct w1_master *dev);
 
 #endif /* __KERNEL__ */
 #endif /* __W1_NETLINK_H */
index 70d2d469963cfe8e57be5b242c31ae1bec525a69..e3209d0aca9b6f0832f296a7a0dde6c45175ff0b 100644 (file)
@@ -36,61 +36,12 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family.");
 
-static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *);
-static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
-
-static struct w1_family_ops w1_smem_fops = {
-       .rname = &w1_smem_read_name,
-       .rbin = &w1_smem_read_bin,
-};
-
-static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
-       return sprintf(buf, "%s\n", sl->name);
-}
-
-static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
-{
-       struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
-                                          struct w1_slave, dev);
-       int i;
-
-       atomic_inc(&sl->refcnt);
-       if (down_interruptible(&sl->master->mutex)) {
-               count = 0;
-               goto out_dec;
-       }
-
-       if (off > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       if (off + count > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       for (i = 0; i < 8; ++i)
-               count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
-       count += sprintf(buf + count, "\n");
-
-out:
-       up(&sl->master->mutex);
-out_dec:
-       atomic_dec(&sl->refcnt);
-
-       return count;
-}
-
 static struct w1_family w1_smem_family_01 = {
        .fid = W1_FAMILY_SMEM_01,
-       .fops = &w1_smem_fops,
 };
 
 static struct w1_family w1_smem_family_81 = {
        .fid = W1_FAMILY_SMEM_81,
-       .fops = &w1_smem_fops,
 };
 
 static int __init w1_smem_init(void)
index 165526c9360ad5a99a642e5e91c92ac762b24b0c..4577df3cfc4839e8537ed22618f02381a1b1b079 100644 (file)
@@ -42,12 +42,31 @@ static u8 bad_roms[][9] = {
                                {}
                        };
 
-static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *);
 static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
 
+static struct bin_attribute w1_therm_bin_attr = {
+       .attr = {
+               .name = "w1_slave",
+               .mode = S_IRUGO,
+               .owner = THIS_MODULE,
+       },
+       .size = W1_SLAVE_DATA_SIZE,
+       .read = w1_therm_read_bin,
+};
+
+static int w1_therm_add_slave(struct w1_slave *sl)
+{
+       return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+}
+
+static void w1_therm_remove_slave(struct w1_slave *sl)
+{
+       sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+}
+
 static struct w1_family_ops w1_therm_fops = {
-       .rname = &w1_therm_read_name,
-       .rbin = &w1_therm_read_bin,
+       .add_slave      = w1_therm_add_slave,
+       .remove_slave   = w1_therm_remove_slave,
 };
 
 static struct w1_family w1_therm_family_DS18S20 = {
@@ -59,6 +78,7 @@ static struct w1_family w1_therm_family_DS18B20 = {
        .fid = W1_THERM_DS18B20,
        .fops = &w1_therm_fops,
 };
+
 static struct w1_family w1_therm_family_DS1822 = {
        .fid = W1_THERM_DS1822,
        .fops = &w1_therm_fops,
@@ -90,13 +110,6 @@ static struct w1_therm_family_converter w1_therm_families[] = {
        },
 };
 
-static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
-       return sprintf(buf, "%s\n", sl->name);
-}
-
 static inline int w1_DS18B20_convert_temp(u8 rom[9])
 {
        int t = (rom[1] << 8) | rom[0];
@@ -148,8 +161,7 @@ static int w1_therm_check_rom(u8 rom[9])
 
 static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
-       struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
-                                          struct w1_slave, dev);
+       struct w1_slave *sl = kobj_to_w1_slave(kobj);
        struct w1_master *dev = sl->master;
        u8 rom[9], crc, verdict;
        int i, max_trying = 10;
@@ -178,15 +190,10 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
        crc = 0;
 
        while (max_trying--) {
-               if (!w1_reset_bus (dev)) {
+               if (!w1_reset_select_slave(sl)) {
                        int count = 0;
-                       u8 match[9] = {W1_MATCH_ROM, };
                        unsigned int tm = 750;
 
-                       memcpy(&match[1], (u64 *) & sl->reg_num, 8);
-
-                       w1_write_block(dev, match, 9);
-
                        w1_write_8(dev, W1_CONVERT_TEMP);
 
                        while (tm) {
@@ -195,8 +202,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
                                        flush_signals(current);
                        }
 
-                       if (!w1_reset_bus (dev)) {
-                               w1_write_block(dev, match, 9);
+                       if (!w1_reset_select_slave(sl)) {
 
                                w1_write_8(dev, W1_READ_SCRATCHPAD);
                                if ((count = w1_read_block(dev, rom, 9)) != 9) {
@@ -207,7 +213,6 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
 
                                if (rom[8] == crc && rom[0])
                                        verdict = 1;
-
                        }
                }
 
index f681e675b823c80448e3e4f6cf618bb4585d61ff..4e115f368d5fdd966a52cfc18d195724f2e03482 100644 (file)
@@ -254,6 +254,19 @@ extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
 extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                                    struct pci_bus_region *region);
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
 static inline int pci_proc_domain(struct pci_bus *bus)
index 72b04d846a231bb473e4986f05276f6d399ff2fe..cf35721cfa453f4a853520fce7e42b3e6298a5f3 100644 (file)
 
 #ifndef __ASSEMBLY__
 
-#if 0
-# define __REG(x)      (*((volatile u32 *)io_p2v(x)))
-#else
-/*
- * This __REG() version gives the same results as the one above,  except
- * that we are fooling gcc somehow so it generates far better and smaller
- * assembly code for access to contigous registers.  It's a shame that gcc
- * doesn't guess this by itself.
- */
-#include <asm/types.h>
-typedef struct { volatile u32 offset[4096]; } __regbase;
-# define __REGP(x)     ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
-# define __REG(x)      __REGP(io_p2v(x))
-#endif
+# define __REG(x)      (*((volatile unsigned long *)io_p2v(x)))
 
 /* With indexed regs we don't want to feed the index through io_p2v()
    especially if it is a variable, otherwise horrible code will result. */
-# define __REG2(x,y)     (*(volatile u32 *)((u32)&__REG(x) + (y)))
+# define __REG2(x,y)   \
+       (*(volatile unsigned long *)((unsigned long)&__REG(x) + (y)))
 
 # define __PREG(x)     (io_v2p((u32)&(x)))
 
diff --git a/include/asm-arm/arch-pxa/i2c.h b/include/asm-arm/arch-pxa/i2c.h
new file mode 100644 (file)
index 0000000..46ec224
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  i2c_pxa.h
+ *
+ *  Copyright (C) 2002 Intrinsyc Software 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.
+ *
+ */
+#ifndef _I2C_PXA_H_
+#define _I2C_PXA_H_
+
+#if 0
+#define DEF_TIMEOUT             3
+#else
+/* need a longer timeout if we're dealing with the fact we may well be
+ * looking at a multi-master environment
+*/
+#define DEF_TIMEOUT             32
+#endif
+
+#define BUS_ERROR               (-EREMOTEIO)
+#define XFER_NAKED              (-ECONNREFUSED)
+#define I2C_RETRY               (-2000) /* an error has occurred retry transmit */
+
+/* ICR initialize bit values
+*
+*  15. FM       0 (100 Khz operation)
+*  14. UR       0 (No unit reset)
+*  13. SADIE    0 (Disables the unit from interrupting on slave addresses
+*                                       matching its slave address)
+*  12. ALDIE    0 (Disables the unit from interrupt when it loses arbitration
+*                                       in master mode)
+*  11. SSDIE    0 (Disables interrupts from a slave stop detected, in slave mode)
+*  10. BEIE     1 (Enable interrupts from detected bus errors, no ACK sent)
+*  9.  IRFIE    1 (Enable interrupts from full buffer received)
+*  8.  ITEIE    1 (Enables the I2C unit to interrupt when transmit buffer empty)
+*  7.  GCD      1 (Disables i2c unit response to general call messages as a slave)
+*  6.  IUE      0 (Disable unit until we change settings)
+*  5.  SCLE     1 (Enables the i2c clock output for master mode (drives SCL)
+*  4.  MA       0 (Only send stop with the ICR stop bit)
+*  3.  TB       0 (We are not transmitting a byte initially)
+*  2.  ACKNAK   0 (Send an ACK after the unit receives a byte)
+*  1.  STOP     0 (Do not send a STOP)
+*  0.  START    0 (Do not send a START)
+*
+*/
+#define I2C_ICR_INIT   (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+
+/* I2C status register init values
+ *
+ * 10. BED      1 (Clear bus error detected)
+ * 9.  SAD      1 (Clear slave address detected)
+ * 7.  IRF      1 (Clear IDBR Receive Full)
+ * 6.  ITE      1 (Clear IDBR Transmit Empty)
+ * 5.  ALD      1 (Clear Arbitration Loss Detected)
+ * 4.  SSD      1 (Clear Slave Stop Detected)
+ */
+#define I2C_ISR_INIT   0x7FF  /* status register init */
+
+struct i2c_slave_client;
+
+struct i2c_pxa_platform_data {
+       unsigned int            slave_addr;
+       struct i2c_slave_client *slave;
+};
+
+extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
+#endif
index 9718063a211959472bce3f7990cbdd5e8257948b..88c17dd02ed2dc21366f02bd0ccbfa98ce966b67 100644 (file)
@@ -9,6 +9,7 @@ struct mmc_host;
 
 struct pxamci_platform_data {
        unsigned int ocr_mask;                  /* available voltages */
+       unsigned long detect_delay;             /* delay in jiffies before detecting cards after interrupt */
        int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *);
        int (*get_ro)(struct device *);
        void (*setpower)(struct device *, unsigned int);
index 10c62db3436247accb5c32e8ad9dc0589565533b..19c3b1e186bb6f8774704f138f10cb814fce3af4 100644 (file)
    ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
 
 #ifndef __ASSEMBLY__
-#include <asm/types.h>
 
-#if 0
-# define __REG(x)      (*((volatile u32 *)io_p2v(x)))
-#else
-/*
- * This __REG() version gives the same results as the one above,  except
- * that we are fooling gcc somehow so it generates far better and smaller
- * assembly code for access to contigous registers.  It's a shame that gcc
- * doesn't guess this by itself.
- */
-typedef struct { volatile u32 offset[4096]; } __regbase;
-# define __REGP(x)     ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
-# define __REG(x)      __REGP(io_p2v(x))
-#endif
-
-# define __PREG(x)     (io_v2p((u32)&(x)))
+# define __REG(x)      (*((volatile unsigned long *)io_p2v(x)))
+# define __PREG(x)     (io_v2p((unsigned long)&(x)))
 
 #else
 
index 035cdcff43d233e8566e5ed0ce3e6b04514be4d9..e81baff4f54b3293d18290088af1e1ac1f65fabe 100644 (file)
@@ -256,7 +256,7 @@ extern void dmac_flush_range(unsigned long, unsigned long);
  * Convert calls to our calling convention.
  */
 #define flush_cache_all()              __cpuc_flush_kern_all()
-
+#ifndef CONFIG_CPU_CACHE_VIPT
 static inline void flush_cache_mm(struct mm_struct *mm)
 {
        if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
@@ -279,6 +279,11 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned l
                __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
        }
 }
+#else
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
+#endif
 
 /*
  * flush_cache_user_range is used when we want to ensure that the
index 38ea5899a580a9500c7e9a3d49fdffd25b119c8e..ead3ced38cb8f4aa2b20cae06d982291f5dbeb6a 100644 (file)
@@ -64,6 +64,19 @@ extern void
 pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                        struct pci_bus_region *region);
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
index ee1d8b5d8168fa99ad3b60be15a9a8b5aa17cbc2..c36a77d3bf44473b603b9c7d2a4749521f708a79 100644 (file)
@@ -30,6 +30,19 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
        res->end = region->end;
 }
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 #define pcibios_scan_all_fns(a, b)     0
 
 #ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
index a429fe225b07b4fb85de63f623640c6b2355f23e..20f98f1751a19677795035356972993d8aa24709 100644 (file)
@@ -80,12 +80,9 @@ extern int iosapic_remove (unsigned int gsi_base);
 #endif /* CONFIG_HOTPLUG */
 extern int gsi_to_vector (unsigned int gsi);
 extern int gsi_to_irq (unsigned int gsi);
-extern void iosapic_enable_intr (unsigned int vector);
 extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
                                  unsigned long trigger);
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 extern void iosapic_unregister_intr (unsigned int irq);
-#endif
 extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
                                      unsigned long polarity,
                                      unsigned long trigger);
@@ -97,7 +94,6 @@ extern int __init iosapic_register_platform_intr (u32 int_type,
                                           unsigned long trigger);
 extern unsigned int iosapic_version (char __iomem *addr);
 
-extern void iosapic_pci_fixup (int);
 #ifdef CONFIG_NUMA
 extern void __devinit map_iosapic_to_node (unsigned int, int);
 #endif
index cd984d08fd15b09f27cdc28c4698b38d7bd57ddc..dbe86c0bbce5f896f25e4934228ac2c36228227a 100644 (file)
@@ -35,8 +35,4 @@ extern void disable_irq_nosync (unsigned int);
 extern void enable_irq (unsigned int);
 extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
 
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
 #endif /* _ASM_IA64_IRQ_H */
index dba9f220be715b7273f474de70fa1e8338576d44..ef616fd4cb1b2ada194f79f8ab42bbe46232d5cb 100644 (file)
@@ -156,6 +156,19 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev,
 extern void pcibios_bus_to_resource(struct pci_dev *dev,
                struct resource *res, struct pci_bus_region *region);
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 #define pcibios_scan_all_fns(a, b)     0
 
 #endif /* _ASM_IA64_PCI_H */
index 16f32cc80c40ccd9a61be98b0687cdc9f4cba4ef..1df3f666a28e05eeae35824587cdf25497aae017 100644 (file)
@@ -22,7 +22,7 @@
 #define        MCF_MBAR2       0x80000000
 #define        MCF_IPSBAR      0x40000000
 
-#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
 #undef MCF_MBAR
 #define        MCF_MBAR        MCF_IPSBAR
 #endif
@@ -54,6 +54,8 @@
 #define        MCF_CLK         54000000
 #elif defined(CONFIG_CLOCK_60MHz)
 #define        MCF_CLK         60000000
+#elif defined(CONFIG_CLOCK_62_5MHz)
+#define MCF_CLK                62500000
 #elif defined(CONFIG_CLOCK_64MHz)
 #define        MCF_CLK         64000000
 #elif defined(CONFIG_CLOCK_66MHz)
@@ -76,7 +78,7 @@
  *     One some ColdFire family members the bus clock (used by internal
  *     peripherals) is not the same as the CPU clock.
  */
-#if defined(CONFIG_M5249) || defined(CONFIG_M527x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x)
 #define        MCF_BUSCLK      (MCF_CLK / 2)
 #else
 #define        MCF_BUSCLK      MCF_CLK
diff --git a/include/asm-m68knommu/m523xsim.h b/include/asm-m68knommu/m523xsim.h
new file mode 100644 (file)
index 0000000..926cfb8
--- /dev/null
@@ -0,0 +1,46 @@
+/****************************************************************************/
+
+/*
+ *     m523xsim.h -- ColdFire 523x System Integration Module support.
+ *
+ *     (C) Copyright 2003-2005, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef        m523xsim_h
+#define        m523xsim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *     Define the 523x SIM register set addresses.
+ */
+#define        MCFICM_INTC0            0x0c00          /* Base for Interrupt Ctrl 0 */
+#define        MCFICM_INTC1            0x0d00          /* Base for Interrupt Ctrl 0 */
+#define        MCFINTC_IPRH            0x00            /* Interrupt pending 32-63 */
+#define        MCFINTC_IPRL            0x04            /* Interrupt pending 1-31 */
+#define        MCFINTC_IMRH            0x08            /* Interrupt mask 32-63 */
+#define        MCFINTC_IMRL            0x0c            /* Interrupt mask 1-31 */
+#define        MCFINTC_INTFRCH         0x10            /* Interrupt force 32-63 */
+#define        MCFINTC_INTFRCL         0x14            /* Interrupt force 1-31 */
+#define        MCFINTC_IRLR            0x18            /* */
+#define        MCFINTC_IACKL           0x19            /* */
+#define        MCFINTC_ICR0            0x40            /* Base ICR register */
+
+#define        MCFINT_VECBASE          64              /* Vector base number */
+#define        MCFINT_UART0            13              /* Interrupt number for UART0 */
+#define        MCFINT_PIT1             36              /* Interrupt number for PIT1 */
+#define MCFINT_QSPI            18              /* Interrupt number for QSPI */
+
+/*
+ *     SDRAM configuration registers.
+ */
+#define        MCFSIM_DCR              0x44            /* SDRAM control */
+#define        MCFSIM_DACR0            0x48            /* SDRAM base address 0 */
+#define        MCFSIM_DMR0             0x4c            /* SDRAM address mask 0 */
+#define        MCFSIM_DACR1            0x50            /* SDRAM base address 1 */
+#define        MCFSIM_DMR1             0x54            /* SDRAM address mask 1 */
+
+/****************************************************************************/
+#endif /* m523xsim_h */
index 522e513c2bc6e54decefdc12ca6314f88bfa63b2..b0c7736f7a99aaaaa07152c180eee2e06138ebe4 100644 (file)
 #include <linux/config.h>
 
 /*
- *     Include 5204, 5206/e, 5249, 5270/5271, 5272, 5280/5282, 5307 or
- *     5407 specific addresses.
+ *     Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
+ *     5307 or 5407 specific addresses.
  */
 #if defined(CONFIG_M5204)
 #include <asm/m5204sim.h>
 #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
 #include <asm/m5206sim.h>
+#elif defined(CONFIG_M523x)
+#include <asm/m523xsim.h>
 #elif defined(CONFIG_M5249)
 #include <asm/m5249sim.h>
 #elif defined(CONFIG_M527x)
index 54d4a85f4fdf301b2e2f722df28cd0f65c3ade6a..9c1210613bc78ef925efff098196020b8b8d0857 100644 (file)
@@ -29,7 +29,7 @@
 #define        MCFUART_BASE1           0x140           /* Base address of UART1 */
 #define        MCFUART_BASE2           0x180           /* Base address of UART2 */
 #endif
-#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
 #define MCFUART_BASE1          0x200           /* Base address of UART1 */
 #define MCFUART_BASE2          0x240           /* Base address of UART2 */
 #define MCFUART_BASE3          0x280           /* Base address of UART3 */
index 98d79a3d54fa9e5056fdae209a8dd9bba7c75668..d0b761f690b53233fc22dea146d7ffc8e4efe798 100644 (file)
@@ -257,6 +257,19 @@ extern void
 pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                        struct pci_bus_region *region);
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
index a811e440c97809272e0f9ab4a4f439249eeb66bf..9dd06cd40096aad23eec026983b41b7ed11664bd 100644 (file)
@@ -109,6 +109,19 @@ extern void
 pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                        struct pci_bus_region *region);
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 extern void pcibios_add_platform_entries(struct pci_dev *dev);
 
 struct file;
index 4d057452f59bbc92fb998aa54d21d624024da8e2..a88bbfc2696733bef9c138e593be95ed7a77aa8d 100644 (file)
@@ -138,6 +138,19 @@ extern void
 pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                        struct pci_bus_region *region);
 
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
 extern int
 unmap_bus_range(struct pci_bus *bus);
 
index a4ab0ec7143a0f08cbbf065bc23f93f475ba4a27..89bd71b1c0d80c869791bec7f267cff7109f4114 100644 (file)
@@ -269,6 +269,8 @@ extern void
 pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                        struct pci_bus_region *region);
 
+extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
index 5e94c05dc2fccf08d6d6fd4440adbb017fd41edf..b5417529f6f173dac37d17e900411d9c68ea7929 100644 (file)
@@ -28,13 +28,48 @@ enum sparc_cpu {
 #define ARCH_SUN4C_SUN4 0
 #define ARCH_SUN4 0
 
-extern void mb(void);
-extern void rmb(void);
-extern void wmb(void);
-extern void membar_storeload(void);
-extern void membar_storeload_storestore(void);
-extern void membar_storeload_loadload(void);
-extern void membar_storestore_loadstore(void);
+/* These are here in an effort to more fully work around Spitfire Errata
+ * #51.  Essentially, if a memory barrier occurs soon after a mispredicted
+ * branch, the chip can stop executing instructions until a trap occurs.
+ * Therefore, if interrupts are disabled, the chip can hang forever.
+ *
+ * It used to be believed that the memory barrier had to be right in the
+ * delay slot, but a case has been traced recently wherein the memory barrier
+ * was one instruction after the branch delay slot and the chip still hung.
+ * The offending sequence was the following in sym_wakeup_done() of the
+ * sym53c8xx_2 driver:
+ *
+ *     call    sym_ccb_from_dsa, 0
+ *      movge  %icc, 0, %l0
+ *     brz,pn  %o0, .LL1303
+ *      mov    %o0, %l2
+ *     membar  #LoadLoad
+ *
+ * The branch has to be mispredicted for the bug to occur.  Therefore, we put
+ * the memory barrier explicitly into a "branch always, predicted taken"
+ * delay slot to avoid the problem case.
+ */
+#define membar_safe(type) \
+do {   __asm__ __volatile__("ba,pt     %%xcc, 1f\n\t" \
+                            " membar   " type "\n" \
+                            "1:\n" \
+                            : : : "memory"); \
+} while (0)
+
+#define mb()   \
+       membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
+#define rmb()  \
+       membar_safe("#LoadLoad")
+#define wmb()  \
+       membar_safe("#StoreStore")
+#define membar_storeload() \
+       membar_safe("#StoreLoad")
+#define membar_storeload_storestore() \
+       membar_safe("#StoreLoad | #StoreStore")
+#define membar_storeload_loadload() \
+       membar_safe("#StoreLoad | #LoadLoad")
+#define membar_storestore_loadstore() \
+       membar_safe("#StoreStore | #LoadStore")
 
 #endif
 
diff --git a/include/linux/crc16.h b/include/linux/crc16.h
new file mode 100644 (file)
index 0000000..bdedf82
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *     crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16, as used with 1-wire devices:
+ *   Width 16
+ *   Poly  0x8005 (x^16 + x^15 + x^2 + 1)
+ *   Init  0
+ *
+ * For 1-wire devices, the CRC is stored inverted, LSB-first
+ *
+ * Example buffer with the CRC attached:
+ *   31 32 33 34 35 36 37 38 39 C2 44
+ *
+ * The CRC over a buffer with the CRC attached is 0xB001.
+ * So, if (crc16(0, buf, size) == 0xB001) then the buffer is valid.
+ *
+ * Refer to "Application Note 937: Book of iButton Standards" for details.
+ * http://www.maxim-ic.com/appnotes.cfm/appnote_number/937
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#ifndef __CRC16_H
+#define __CRC16_H
+
+#include <linux/types.h>
+
+#define CRC16_INIT             0
+#define CRC16_VALID            0xb001
+
+extern u16 const crc16_table[256];
+
+extern u16 crc16(u16 crc, const u8 *buffer, size_t len);
+
+static inline u16 crc16_byte(u16 crc, const u8 data)
+{
+       return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
+}
+
+#endif /* __CRC16_H */
+
diff --git a/include/linux/i2c-pxa.h b/include/linux/i2c-pxa.h
new file mode 100644 (file)
index 0000000..5f3eaf8
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef _LINUX_I2C_ALGO_PXA_H
+#define _LINUX_I2C_ALGO_PXA_H
+
+struct i2c_eeprom_emu_watcher {
+       void (*write)(void *, unsigned int addr, unsigned char newval);
+};
+
+struct i2c_eeprom_emu_watch {
+       struct list_head node;
+       unsigned int start;
+       unsigned int end;
+       struct i2c_eeprom_emu_watcher *ops;
+       void *data;
+};
+
+#define I2C_EEPROM_EMU_SIZE (256)
+
+struct i2c_eeprom_emu {
+       unsigned int size;
+       unsigned int ptr;
+       unsigned int seen_start;
+       struct list_head watch;
+
+       unsigned char bytes[I2C_EEPROM_EMU_SIZE];
+};
+
+typedef enum i2c_slave_event_e {
+       I2C_SLAVE_EVENT_START_READ,
+       I2C_SLAVE_EVENT_START_WRITE,
+       I2C_SLAVE_EVENT_STOP
+} i2c_slave_event_t;
+
+struct i2c_slave_client {
+       void *data;
+       void (*event)(void *ptr, i2c_slave_event_t event);
+       int  (*read) (void *ptr);
+       void (*write)(void *ptr, unsigned int val);
+};
+
+extern int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *, void *data,
+                                    unsigned int addr, unsigned int size,
+                                    struct i2c_eeprom_emu_watcher *);
+
+extern void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *, void *data, struct i2c_eeprom_emu_watcher *watcher);
+
+extern struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void);
+
+#endif /* _LINUX_I2C_ALGO_PXA_H */
index dcf5720ffcbb3419c524140bfbc02945c53f3e47..bd32b79d6295fe7cb4ff3239be932df09a63972b 100644 (file)
@@ -148,13 +148,13 @@ struct in6_flowlabel_req
  */
 
 #define IPV6_ADDRFORM          1
-#define IPV6_PKTINFO           2
-#define IPV6_HOPOPTS           3
-#define IPV6_DSTOPTS           4
-#define IPV6_RTHDR             5
-#define IPV6_PKTOPTIONS                6
+#define IPV6_2292PKTINFO       2
+#define IPV6_2292HOPOPTS       3
+#define IPV6_2292DSTOPTS       4
+#define IPV6_2292RTHDR         5
+#define IPV6_2292PKTOPTIONS    6
 #define IPV6_CHECKSUM          7
-#define IPV6_HOPLIMIT          8
+#define IPV6_2292HOPLIMIT      8
 #define IPV6_NEXTHOP           9
 #define IPV6_AUTHHDR           10      /* obsolete */
 #define IPV6_FLOWINFO          11
@@ -198,4 +198,28 @@ struct in6_flowlabel_req
  * MCAST_MSFILTER              48
  */
 
+/* RFC3542 advanced socket options (50-67) */
+#define IPV6_RECVPKTINFO       50
+#define IPV6_PKTINFO           51
+#if 0
+#define IPV6_RECVPATHMTU       52
+#define IPV6_PATHMTU           53
+#define IPV6_DONTFRAG          54
+#define IPV6_USE_MIN_MTU       55
+#endif
+#define IPV6_RECVHOPOPTS       56
+#define IPV6_HOPOPTS           57
+#if 0
+#define IPV6_RECVRTHDRDSTOPTS  58      /* Unused, see net/ipv6/datagram.c */
+#endif
+#define IPV6_RTHDRDSTOPTS      59
+#define IPV6_RECVRTHDR         60
+#define IPV6_RTHDR             61
+#define IPV6_RECVDSTOPTS       62
+#define IPV6_DSTOPTS           63
+#define IPV6_RECVHOPLIMIT      64
+#define IPV6_HOPLIMIT          65
+#define IPV6_RECVTCLASS                66
+#define IPV6_TCLASS            67
+
 #endif
index 3c7dbc6a0a707510ae0171c20dc5e9918ca673e0..6c5f7b39a4b0135fc479fed6979f267d681755f2 100644 (file)
@@ -189,6 +189,7 @@ struct inet6_skb_parm {
        __u16                   dst0;
        __u16                   srcrt;
        __u16                   dst1;
+       __u16                   lastopt;
 };
 
 #define IP6CB(skb)     ((struct inet6_skb_parm*)((skb)->cb))
@@ -234,14 +235,20 @@ struct ipv6_pinfo {
        /* pktoption flags */
        union {
                struct {
-                       __u8    srcrt:2,
+                       __u16   srcrt:2,
+                               osrcrt:2,
                                rxinfo:1,
+                               rxoinfo:1,
                                rxhlim:1,
+                               rxohlim:1,
                                hopopts:1,
+                               ohopopts:1,
                                dstopts:1,
-                                rxflow:1;
+                               odstopts:1,
+                                rxflow:1,
+                               rxtclass:1;
                } bits;
-               __u           all;
+               __u16           all;
        } rxopt;
 
        /* sockopt flags */
@@ -250,6 +257,7 @@ struct ipv6_pinfo {
                                sndflow:1,
                                pmtudisc:2,
                                ipv6only:1;
+       __u8                    tclass;
 
        __u32                   dst_cookie;
 
@@ -263,6 +271,7 @@ struct ipv6_pinfo {
                struct ipv6_txoptions *opt;
                struct rt6_info *rt;
                int hop_limit;
+               int tclass;
        } cork;
 };
 
index 94a46f38c5326f8a337c256e7ba6d209951e7a6b..58385ee1c0acc309aa862eab5f7b207110942f27 100644 (file)
@@ -155,6 +155,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
 
 extern void numa_default_policy(void);
 extern void numa_policy_init(void);
+extern struct mempolicy default_policy;
 
 #else
 
index 6014160d9c0665acc497ade8b1236f93f1f4637a..c1f021eddffa1663993d558a7c9dfb489e11e5fb 100644 (file)
@@ -109,6 +109,8 @@ struct mmc_host {
        struct mmc_card         *card_selected; /* the selected MMC card */
 
        struct work_struct      detect;
+
+       unsigned long           private[0] ____cacheline_aligned;
 };
 
 extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
@@ -116,14 +118,18 @@ extern int mmc_add_host(struct mmc_host *);
 extern void mmc_remove_host(struct mmc_host *);
 extern void mmc_free_host(struct mmc_host *);
 
-#define mmc_priv(x)    ((void *)((x) + 1))
+static inline void *mmc_priv(struct mmc_host *host)
+{
+       return (void *)host->private;
+}
+
 #define mmc_dev(x)     ((x)->dev)
 #define mmc_hostname(x)        ((x)->class_dev.class_id)
 
 extern int mmc_suspend_host(struct mmc_host *, pm_message_t);
 extern int mmc_resume_host(struct mmc_host *);
 
-extern void mmc_detect_change(struct mmc_host *);
+extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
 extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
 
 #endif
index bc4c40000c0d7350b1ca9e5ce3f97e917c89aa5b..6caaba0af46975f51b4a9ca7836fb31bc08dd192 100644 (file)
 
 #include <linux/mod_devicetable.h>
 
-/*
- * Under PCI, each device has 256 bytes of configuration address space,
- * of which the first 64 bytes are standardized as follows:
- */
-#define PCI_VENDOR_ID          0x00    /* 16 bits */
-#define PCI_DEVICE_ID          0x02    /* 16 bits */
-#define PCI_COMMAND            0x04    /* 16 bits */
-#define  PCI_COMMAND_IO                0x1     /* Enable response in I/O space */
-#define  PCI_COMMAND_MEMORY    0x2     /* Enable response in Memory space */
-#define  PCI_COMMAND_MASTER    0x4     /* Enable bus mastering */
-#define  PCI_COMMAND_SPECIAL   0x8     /* Enable response to special cycles */
-#define  PCI_COMMAND_INVALIDATE        0x10    /* Use memory write and invalidate */
-#define  PCI_COMMAND_VGA_PALETTE 0x20  /* Enable palette snooping */
-#define  PCI_COMMAND_PARITY    0x40    /* Enable parity checking */
-#define  PCI_COMMAND_WAIT      0x80    /* Enable address/data stepping */
-#define  PCI_COMMAND_SERR      0x100   /* Enable SERR */
-#define  PCI_COMMAND_FAST_BACK 0x200   /* Enable back-to-back writes */
-#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
-
-#define PCI_STATUS             0x06    /* 16 bits */
-#define  PCI_STATUS_CAP_LIST   0x10    /* Support Capability List */
-#define  PCI_STATUS_66MHZ      0x20    /* Support 66 Mhz PCI 2.1 bus */
-#define  PCI_STATUS_UDF                0x40    /* Support User Definable Features [obsolete] */
-#define  PCI_STATUS_FAST_BACK  0x80    /* Accept fast-back to back */
-#define  PCI_STATUS_PARITY     0x100   /* Detected parity error */
-#define  PCI_STATUS_DEVSEL_MASK        0x600   /* DEVSEL timing */
-#define  PCI_STATUS_DEVSEL_FAST        0x000   
-#define  PCI_STATUS_DEVSEL_MEDIUM 0x200
-#define  PCI_STATUS_DEVSEL_SLOW 0x400
-#define  PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
-#define  PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
-#define  PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
-#define  PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
-#define  PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
-
-#define PCI_CLASS_REVISION     0x08    /* High 24 bits are class, low 8
-                                          revision */
-#define PCI_REVISION_ID         0x08    /* Revision ID */
-#define PCI_CLASS_PROG          0x09    /* Reg. Level Programming Interface */
-#define PCI_CLASS_DEVICE        0x0a    /* Device class */
-
-#define PCI_CACHE_LINE_SIZE    0x0c    /* 8 bits */
-#define PCI_LATENCY_TIMER      0x0d    /* 8 bits */
-#define PCI_HEADER_TYPE                0x0e    /* 8 bits */
-#define  PCI_HEADER_TYPE_NORMAL        0
-#define  PCI_HEADER_TYPE_BRIDGE 1
-#define  PCI_HEADER_TYPE_CARDBUS 2
-
-#define PCI_BIST               0x0f    /* 8 bits */
-#define  PCI_BIST_CODE_MASK    0x0f    /* Return result */
-#define  PCI_BIST_START                0x40    /* 1 to start BIST, 2 secs or less */
-#define  PCI_BIST_CAPABLE      0x80    /* 1 if BIST capable */
-
-/*
- * Base addresses specify locations in memory or I/O space.
- * Decoded size can be determined by writing a value of 
- * 0xffffffff to the register, and reading it back.  Only 
- * 1 bits are decoded.
- */
-#define PCI_BASE_ADDRESS_0     0x10    /* 32 bits */
-#define PCI_BASE_ADDRESS_1     0x14    /* 32 bits [htype 0,1 only] */
-#define PCI_BASE_ADDRESS_2     0x18    /* 32 bits [htype 0 only] */
-#define PCI_BASE_ADDRESS_3     0x1c    /* 32 bits */
-#define PCI_BASE_ADDRESS_4     0x20    /* 32 bits */
-#define PCI_BASE_ADDRESS_5     0x24    /* 32 bits */
-#define  PCI_BASE_ADDRESS_SPACE        0x01    /* 0 = memory, 1 = I/O */
-#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
-#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
-#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
-#define  PCI_BASE_ADDRESS_MEM_TYPE_32  0x00    /* 32 bit address */
-#define  PCI_BASE_ADDRESS_MEM_TYPE_1M  0x02    /* Below 1M [obsolete] */
-#define  PCI_BASE_ADDRESS_MEM_TYPE_64  0x04    /* 64 bit address */
-#define  PCI_BASE_ADDRESS_MEM_PREFETCH 0x08    /* prefetchable? */
-#define  PCI_BASE_ADDRESS_MEM_MASK     (~0x0fUL)
-#define  PCI_BASE_ADDRESS_IO_MASK      (~0x03UL)
-/* bit 1 is reserved if address_space = 1 */
-
-/* Header type 0 (normal devices) */
-#define PCI_CARDBUS_CIS                0x28
-#define PCI_SUBSYSTEM_VENDOR_ID        0x2c
-#define PCI_SUBSYSTEM_ID       0x2e  
-#define PCI_ROM_ADDRESS                0x30    /* Bits 31..11 are address, 10..1 reserved */
-#define  PCI_ROM_ADDRESS_ENABLE        0x01
-#define PCI_ROM_ADDRESS_MASK   (~0x7ffUL)
-
-#define PCI_CAPABILITY_LIST    0x34    /* Offset of first capability list entry */
-
-/* 0x35-0x3b are reserved */
-#define PCI_INTERRUPT_LINE     0x3c    /* 8 bits */
-#define PCI_INTERRUPT_PIN      0x3d    /* 8 bits */
-#define PCI_MIN_GNT            0x3e    /* 8 bits */
-#define PCI_MAX_LAT            0x3f    /* 8 bits */
-
-/* Header type 1 (PCI-to-PCI bridges) */
-#define PCI_PRIMARY_BUS                0x18    /* Primary bus number */
-#define PCI_SECONDARY_BUS      0x19    /* Secondary bus number */
-#define PCI_SUBORDINATE_BUS    0x1a    /* Highest bus number behind the bridge */
-#define PCI_SEC_LATENCY_TIMER  0x1b    /* Latency timer for secondary interface */
-#define PCI_IO_BASE            0x1c    /* I/O range behind the bridge */
-#define PCI_IO_LIMIT           0x1d
-#define  PCI_IO_RANGE_TYPE_MASK        0x0fUL  /* I/O bridging type */
-#define  PCI_IO_RANGE_TYPE_16  0x00
-#define  PCI_IO_RANGE_TYPE_32  0x01
-#define  PCI_IO_RANGE_MASK     (~0x0fUL)
-#define PCI_SEC_STATUS         0x1e    /* Secondary status register, only bit 14 used */
-#define PCI_MEMORY_BASE                0x20    /* Memory range behind */
-#define PCI_MEMORY_LIMIT       0x22
-#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
-#define  PCI_MEMORY_RANGE_MASK (~0x0fUL)
-#define PCI_PREF_MEMORY_BASE   0x24    /* Prefetchable memory range behind */
-#define PCI_PREF_MEMORY_LIMIT  0x26
-#define  PCI_PREF_RANGE_TYPE_MASK 0x0fUL
-#define  PCI_PREF_RANGE_TYPE_32        0x00
-#define  PCI_PREF_RANGE_TYPE_64        0x01
-#define  PCI_PREF_RANGE_MASK   (~0x0fUL)
-#define PCI_PREF_BASE_UPPER32  0x28    /* Upper half of prefetchable memory range */
-#define PCI_PREF_LIMIT_UPPER32 0x2c
-#define PCI_IO_BASE_UPPER16    0x30    /* Upper half of I/O addresses */
-#define PCI_IO_LIMIT_UPPER16   0x32
-/* 0x34 same as for htype 0 */
-/* 0x35-0x3b is reserved */
-#define PCI_ROM_ADDRESS1       0x38    /* Same as PCI_ROM_ADDRESS, but for htype 1 */
-/* 0x3c-0x3d are same as for htype 0 */
-#define PCI_BRIDGE_CONTROL     0x3e
-#define  PCI_BRIDGE_CTL_PARITY 0x01    /* Enable parity detection on secondary interface */
-#define  PCI_BRIDGE_CTL_SERR   0x02    /* The same for SERR forwarding */
-#define  PCI_BRIDGE_CTL_NO_ISA 0x04    /* Disable bridging of ISA ports */
-#define  PCI_BRIDGE_CTL_VGA    0x08    /* Forward VGA addresses */
-#define  PCI_BRIDGE_CTL_MASTER_ABORT 0x20  /* Report master aborts */
-#define  PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
-#define  PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
-
-/* Header type 2 (CardBus bridges) */
-#define PCI_CB_CAPABILITY_LIST 0x14
-/* 0x15 reserved */
-#define PCI_CB_SEC_STATUS      0x16    /* Secondary status */
-#define PCI_CB_PRIMARY_BUS     0x18    /* PCI bus number */
-#define PCI_CB_CARD_BUS                0x19    /* CardBus bus number */
-#define PCI_CB_SUBORDINATE_BUS 0x1a    /* Subordinate bus number */
-#define PCI_CB_LATENCY_TIMER   0x1b    /* CardBus latency timer */
-#define PCI_CB_MEMORY_BASE_0   0x1c
-#define PCI_CB_MEMORY_LIMIT_0  0x20
-#define PCI_CB_MEMORY_BASE_1   0x24
-#define PCI_CB_MEMORY_LIMIT_1  0x28
-#define PCI_CB_IO_BASE_0       0x2c
-#define PCI_CB_IO_BASE_0_HI    0x2e
-#define PCI_CB_IO_LIMIT_0      0x30
-#define PCI_CB_IO_LIMIT_0_HI   0x32
-#define PCI_CB_IO_BASE_1       0x34
-#define PCI_CB_IO_BASE_1_HI    0x36
-#define PCI_CB_IO_LIMIT_1      0x38
-#define PCI_CB_IO_LIMIT_1_HI   0x3a
-#define  PCI_CB_IO_RANGE_MASK  (~0x03UL)
-/* 0x3c-0x3d are same as for htype 0 */
-#define PCI_CB_BRIDGE_CONTROL  0x3e
-#define  PCI_CB_BRIDGE_CTL_PARITY      0x01    /* Similar to standard bridge control register */
-#define  PCI_CB_BRIDGE_CTL_SERR                0x02
-#define  PCI_CB_BRIDGE_CTL_ISA         0x04
-#define  PCI_CB_BRIDGE_CTL_VGA         0x08
-#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT        0x20
-#define  PCI_CB_BRIDGE_CTL_CB_RESET    0x40    /* CardBus reset */
-#define  PCI_CB_BRIDGE_CTL_16BIT_INT   0x80    /* Enable interrupt for 16-bit cards */
-#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
-#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
-#define  PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
-#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
-#define PCI_CB_SUBSYSTEM_ID    0x42
-#define PCI_CB_LEGACY_MODE_BASE        0x44    /* 16-bit PC Card legacy mode base address (ExCa) */
-/* 0x48-0x7f reserved */
-
-/* Capability lists */
-
-#define PCI_CAP_LIST_ID                0       /* Capability ID */
-#define  PCI_CAP_ID_PM         0x01    /* Power Management */
-#define  PCI_CAP_ID_AGP                0x02    /* Accelerated Graphics Port */
-#define  PCI_CAP_ID_VPD                0x03    /* Vital Product Data */
-#define  PCI_CAP_ID_SLOTID     0x04    /* Slot Identification */
-#define  PCI_CAP_ID_MSI                0x05    /* Message Signalled Interrupts */
-#define  PCI_CAP_ID_CHSWP      0x06    /* CompactPCI HotSwap */
-#define  PCI_CAP_ID_PCIX       0x07    /* PCI-X */
-#define  PCI_CAP_ID_SHPC       0x0C    /* PCI Standard Hot-Plug Controller */
-#define  PCI_CAP_ID_EXP        0x10    /* PCI Express */
-#define  PCI_CAP_ID_MSIX       0x11    /* MSI-X */
-#define PCI_CAP_LIST_NEXT      1       /* Next capability in the list */
-#define PCI_CAP_FLAGS          2       /* Capability defined flags (16 bits) */
-#define PCI_CAP_SIZEOF         4
-
-/* Power Management Registers */
-
-#define PCI_PM_PMC              2       /* PM Capabilities Register */
-#define  PCI_PM_CAP_VER_MASK   0x0007  /* Version */
-#define  PCI_PM_CAP_PME_CLOCK  0x0008  /* PME clock required */
-#define  PCI_PM_CAP_RESERVED    0x0010  /* Reserved field */
-#define  PCI_PM_CAP_DSI                0x0020  /* Device specific initialization */
-#define  PCI_PM_CAP_AUX_POWER  0x01C0  /* Auxilliary power support mask */
-#define  PCI_PM_CAP_D1         0x0200  /* D1 power state support */
-#define  PCI_PM_CAP_D2         0x0400  /* D2 power state support */
-#define  PCI_PM_CAP_PME                0x0800  /* PME pin supported */
-#define  PCI_PM_CAP_PME_MASK    0xF800  /* PME Mask of all supported states */
-#define  PCI_PM_CAP_PME_D0      0x0800  /* PME# from D0 */
-#define  PCI_PM_CAP_PME_D1      0x1000  /* PME# from D1 */
-#define  PCI_PM_CAP_PME_D2      0x2000  /* PME# from D2 */
-#define  PCI_PM_CAP_PME_D3      0x4000  /* PME# from D3 (hot) */
-#define  PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
-#define PCI_PM_CTRL            4       /* PM control and status register */
-#define  PCI_PM_CTRL_STATE_MASK        0x0003  /* Current power state (D0 to D3) */
-#define  PCI_PM_CTRL_PME_ENABLE        0x0100  /* PME pin enable */
-#define  PCI_PM_CTRL_DATA_SEL_MASK     0x1e00  /* Data select (??) */
-#define  PCI_PM_CTRL_DATA_SCALE_MASK   0x6000  /* Data scale (??) */
-#define  PCI_PM_CTRL_PME_STATUS        0x8000  /* PME pin status */
-#define PCI_PM_PPB_EXTENSIONS  6       /* PPB support extensions (??) */
-#define  PCI_PM_PPB_B2_B3      0x40    /* Stop clock when in D3hot (??) */
-#define  PCI_PM_BPCC_ENABLE    0x80    /* Bus power/clock control enable (??) */
-#define PCI_PM_DATA_REGISTER   7       /* (??) */
-#define PCI_PM_SIZEOF          8
-
-/* AGP registers */
-
-#define PCI_AGP_VERSION                2       /* BCD version number */
-#define PCI_AGP_RFU            3       /* Rest of capability flags */
-#define PCI_AGP_STATUS         4       /* Status register */
-#define  PCI_AGP_STATUS_RQ_MASK        0xff000000      /* Maximum number of requests - 1 */
-#define  PCI_AGP_STATUS_SBA    0x0200  /* Sideband addressing supported */
-#define  PCI_AGP_STATUS_64BIT  0x0020  /* 64-bit addressing supported */
-#define  PCI_AGP_STATUS_FW     0x0010  /* FW transfers supported */
-#define  PCI_AGP_STATUS_RATE4  0x0004  /* 4x transfer rate supported */
-#define  PCI_AGP_STATUS_RATE2  0x0002  /* 2x transfer rate supported */
-#define  PCI_AGP_STATUS_RATE1  0x0001  /* 1x transfer rate supported */
-#define PCI_AGP_COMMAND                8       /* Control register */
-#define  PCI_AGP_COMMAND_RQ_MASK 0xff000000  /* Master: Maximum number of requests */
-#define  PCI_AGP_COMMAND_SBA   0x0200  /* Sideband addressing enabled */
-#define  PCI_AGP_COMMAND_AGP   0x0100  /* Allow processing of AGP transactions */
-#define  PCI_AGP_COMMAND_64BIT 0x0020  /* Allow processing of 64-bit addresses */
-#define  PCI_AGP_COMMAND_FW    0x0010  /* Force FW transfers */
-#define  PCI_AGP_COMMAND_RATE4 0x0004  /* Use 4x rate */
-#define  PCI_AGP_COMMAND_RATE2 0x0002  /* Use 2x rate */
-#define  PCI_AGP_COMMAND_RATE1 0x0001  /* Use 1x rate */
-#define PCI_AGP_SIZEOF         12
-
-/* Vital Product Data */
-
-#define PCI_VPD_ADDR           2       /* Address to access (15 bits!) */
-#define  PCI_VPD_ADDR_MASK     0x7fff  /* Address mask */
-#define  PCI_VPD_ADDR_F                0x8000  /* Write 0, 1 indicates completion */
-#define PCI_VPD_DATA           4       /* 32-bits of data returned here */
-
-/* Slot Identification */
-
-#define PCI_SID_ESR            2       /* Expansion Slot Register */
-#define  PCI_SID_ESR_NSLOTS    0x1f    /* Number of expansion slots available */
-#define  PCI_SID_ESR_FIC       0x20    /* First In Chassis Flag */
-#define PCI_SID_CHASSIS_NR     3       /* Chassis Number */
-
-/* Message Signalled Interrupts registers */
-
-#define PCI_MSI_FLAGS          2       /* Various flags */
-#define  PCI_MSI_FLAGS_64BIT   0x80    /* 64-bit addresses allowed */
-#define  PCI_MSI_FLAGS_QSIZE   0x70    /* Message queue size configured */
-#define  PCI_MSI_FLAGS_QMASK   0x0e    /* Maximum queue size available */
-#define  PCI_MSI_FLAGS_ENABLE  0x01    /* MSI feature enabled */
-#define  PCI_MSI_FLAGS_MASKBIT 0x100   /* 64-bit mask bits allowed */
-#define PCI_MSI_RFU            3       /* Rest of capability flags */
-#define PCI_MSI_ADDRESS_LO     4       /* Lower 32 bits */
-#define PCI_MSI_ADDRESS_HI     8       /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
-#define PCI_MSI_DATA_32                8       /* 16 bits of data for 32-bit devices */
-#define PCI_MSI_DATA_64                12      /* 16 bits of data for 64-bit devices */
-#define PCI_MSI_MASK_BIT       16      /* Mask bits register */
-
-/* CompactPCI Hotswap Register */
-
-#define PCI_CHSWP_CSR          2       /* Control and Status Register */
-#define  PCI_CHSWP_DHA         0x01    /* Device Hiding Arm */
-#define  PCI_CHSWP_EIM         0x02    /* ENUM# Signal Mask */
-#define  PCI_CHSWP_PIE         0x04    /* Pending Insert or Extract */
-#define  PCI_CHSWP_LOO         0x08    /* LED On / Off */
-#define  PCI_CHSWP_PI          0x30    /* Programming Interface */
-#define  PCI_CHSWP_EXT         0x40    /* ENUM# status - extraction */
-#define  PCI_CHSWP_INS         0x80    /* ENUM# status - insertion */
-
-/* PCI-X registers */
-
-#define PCI_X_CMD              2       /* Modes & Features */
-#define  PCI_X_CMD_DPERR_E     0x0001  /* Data Parity Error Recovery Enable */
-#define  PCI_X_CMD_ERO         0x0002  /* Enable Relaxed Ordering */
-#define  PCI_X_CMD_MAX_READ    0x000c  /* Max Memory Read Byte Count */
-#define  PCI_X_CMD_MAX_SPLIT   0x0070  /* Max Outstanding Split Transactions */
-#define  PCI_X_CMD_VERSION(x)  (((x) >> 12) & 3) /* Version */
-#define PCI_X_STATUS           4       /* PCI-X capabilities */
-#define  PCI_X_STATUS_DEVFN    0x000000ff      /* A copy of devfn */
-#define  PCI_X_STATUS_BUS      0x0000ff00      /* A copy of bus nr */
-#define  PCI_X_STATUS_64BIT    0x00010000      /* 64-bit device */
-#define  PCI_X_STATUS_133MHZ   0x00020000      /* 133 MHz capable */
-#define  PCI_X_STATUS_SPL_DISC 0x00040000      /* Split Completion Discarded */
-#define  PCI_X_STATUS_UNX_SPL  0x00080000      /* Unexpected Split Completion */
-#define  PCI_X_STATUS_COMPLEX  0x00100000      /* Device Complexity */
-#define  PCI_X_STATUS_MAX_READ 0x00600000      /* Designed Max Memory Read Count */
-#define  PCI_X_STATUS_MAX_SPLIT        0x03800000      /* Designed Max Outstanding Split Transactions */
-#define  PCI_X_STATUS_MAX_CUM  0x1c000000      /* Designed Max Cumulative Read Size */
-#define  PCI_X_STATUS_SPL_ERR  0x20000000      /* Rcvd Split Completion Error Msg */
-#define  PCI_X_STATUS_266MHZ   0x40000000      /* 266 MHz capable */
-#define  PCI_X_STATUS_533MHZ   0x80000000      /* 533 MHz capable */
-
-/* PCI Express capability registers */
-
-#define PCI_EXP_FLAGS          2       /* Capabilities register */
-#define PCI_EXP_FLAGS_VERS     0x000f  /* Capability version */
-#define PCI_EXP_FLAGS_TYPE     0x00f0  /* Device/Port type */
-#define  PCI_EXP_TYPE_ENDPOINT 0x0     /* Express Endpoint */
-#define  PCI_EXP_TYPE_LEG_END  0x1     /* Legacy Endpoint */
-#define  PCI_EXP_TYPE_ROOT_PORT 0x4    /* Root Port */
-#define  PCI_EXP_TYPE_UPSTREAM 0x5     /* Upstream Port */
-#define  PCI_EXP_TYPE_DOWNSTREAM 0x6   /* Downstream Port */
-#define  PCI_EXP_TYPE_PCI_BRIDGE 0x7   /* PCI/PCI-X Bridge */
-#define PCI_EXP_FLAGS_SLOT     0x0100  /* Slot implemented */
-#define PCI_EXP_FLAGS_IRQ      0x3e00  /* Interrupt message number */
-#define PCI_EXP_DEVCAP         4       /* Device capabilities */
-#define  PCI_EXP_DEVCAP_PAYLOAD        0x07    /* Max_Payload_Size */
-#define  PCI_EXP_DEVCAP_PHANTOM        0x18    /* Phantom functions */
-#define  PCI_EXP_DEVCAP_EXT_TAG        0x20    /* Extended tags */
-#define  PCI_EXP_DEVCAP_L0S    0x1c0   /* L0s Acceptable Latency */
-#define  PCI_EXP_DEVCAP_L1     0xe00   /* L1 Acceptable Latency */
-#define  PCI_EXP_DEVCAP_ATN_BUT        0x1000  /* Attention Button Present */
-#define  PCI_EXP_DEVCAP_ATN_IND        0x2000  /* Attention Indicator Present */
-#define  PCI_EXP_DEVCAP_PWR_IND        0x4000  /* Power Indicator Present */
-#define  PCI_EXP_DEVCAP_PWR_VAL        0x3fc0000 /* Slot Power Limit Value */
-#define  PCI_EXP_DEVCAP_PWR_SCL        0xc000000 /* Slot Power Limit Scale */
-#define PCI_EXP_DEVCTL         8       /* Device Control */
-#define  PCI_EXP_DEVCTL_CERE   0x0001  /* Correctable Error Reporting En. */
-#define  PCI_EXP_DEVCTL_NFERE  0x0002  /* Non-Fatal Error Reporting Enable */
-#define  PCI_EXP_DEVCTL_FERE   0x0004  /* Fatal Error Reporting Enable */
-#define  PCI_EXP_DEVCTL_URRE   0x0008  /* Unsupported Request Reporting En. */
-#define  PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
-#define  PCI_EXP_DEVCTL_PAYLOAD        0x00e0  /* Max_Payload_Size */
-#define  PCI_EXP_DEVCTL_EXT_TAG        0x0100  /* Extended Tag Field Enable */
-#define  PCI_EXP_DEVCTL_PHANTOM        0x0200  /* Phantom Functions Enable */
-#define  PCI_EXP_DEVCTL_AUX_PME        0x0400  /* Auxiliary Power PM Enable */
-#define  PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800  /* Enable No Snoop */
-#define  PCI_EXP_DEVCTL_READRQ 0x7000  /* Max_Read_Request_Size */
-#define PCI_EXP_DEVSTA         10      /* Device Status */
-#define  PCI_EXP_DEVSTA_CED    0x01    /* Correctable Error Detected */
-#define  PCI_EXP_DEVSTA_NFED   0x02    /* Non-Fatal Error Detected */
-#define  PCI_EXP_DEVSTA_FED    0x04    /* Fatal Error Detected */
-#define  PCI_EXP_DEVSTA_URD    0x08    /* Unsupported Request Detected */
-#define  PCI_EXP_DEVSTA_AUXPD  0x10    /* AUX Power Detected */
-#define  PCI_EXP_DEVSTA_TRPND  0x20    /* Transactions Pending */
-#define PCI_EXP_LNKCAP         12      /* Link Capabilities */
-#define PCI_EXP_LNKCTL         16      /* Link Control */
-#define PCI_EXP_LNKSTA         18      /* Link Status */
-#define PCI_EXP_SLTCAP         20      /* Slot Capabilities */
-#define PCI_EXP_SLTCTL         24      /* Slot Control */
-#define PCI_EXP_SLTSTA         26      /* Slot Status */
-#define PCI_EXP_RTCTL          28      /* Root Control */
-#define  PCI_EXP_RTCTL_SECEE   0x01    /* System Error on Correctable Error */
-#define  PCI_EXP_RTCTL_SENFEE  0x02    /* System Error on Non-Fatal Error */
-#define  PCI_EXP_RTCTL_SEFEE   0x04    /* System Error on Fatal Error */
-#define  PCI_EXP_RTCTL_PMEIE   0x08    /* PME Interrupt Enable */
-#define  PCI_EXP_RTCTL_CRSSVE  0x10    /* CRS Software Visibility Enable */
-#define PCI_EXP_RTCAP          30      /* Root Capabilities */
-#define PCI_EXP_RTSTA          32      /* Root Status */
-
-/* Extended Capabilities (PCI-X 2.0 and Express) */
-#define PCI_EXT_CAP_ID(header)         (header & 0x0000ffff)
-#define PCI_EXT_CAP_VER(header)                ((header >> 16) & 0xf)
-#define PCI_EXT_CAP_NEXT(header)       ((header >> 20) & 0xffc)
-
-#define PCI_EXT_CAP_ID_ERR     1
-#define PCI_EXT_CAP_ID_VC      2
-#define PCI_EXT_CAP_ID_DSN     3
-#define PCI_EXT_CAP_ID_PWR     4
-
-/* Advanced Error Reporting */
-#define PCI_ERR_UNCOR_STATUS   4       /* Uncorrectable Error Status */
-#define  PCI_ERR_UNC_TRAIN     0x00000001      /* Training */
-#define  PCI_ERR_UNC_DLP       0x00000010      /* Data Link Protocol */
-#define  PCI_ERR_UNC_POISON_TLP        0x00001000      /* Poisoned TLP */
-#define  PCI_ERR_UNC_FCP       0x00002000      /* Flow Control Protocol */
-#define  PCI_ERR_UNC_COMP_TIME 0x00004000      /* Completion Timeout */
-#define  PCI_ERR_UNC_COMP_ABORT        0x00008000      /* Completer Abort */
-#define  PCI_ERR_UNC_UNX_COMP  0x00010000      /* Unexpected Completion */
-#define  PCI_ERR_UNC_RX_OVER   0x00020000      /* Receiver Overflow */
-#define  PCI_ERR_UNC_MALF_TLP  0x00040000      /* Malformed TLP */
-#define  PCI_ERR_UNC_ECRC      0x00080000      /* ECRC Error Status */
-#define  PCI_ERR_UNC_UNSUP     0x00100000      /* Unsupported Request */
-#define PCI_ERR_UNCOR_MASK     8       /* Uncorrectable Error Mask */
-       /* Same bits as above */
-#define PCI_ERR_UNCOR_SEVER    12      /* Uncorrectable Error Severity */
-       /* Same bits as above */
-#define PCI_ERR_COR_STATUS     16      /* Correctable Error Status */
-#define  PCI_ERR_COR_RCVR      0x00000001      /* Receiver Error Status */
-#define  PCI_ERR_COR_BAD_TLP   0x00000040      /* Bad TLP Status */
-#define  PCI_ERR_COR_BAD_DLLP  0x00000080      /* Bad DLLP Status */
-#define  PCI_ERR_COR_REP_ROLL  0x00000100      /* REPLAY_NUM Rollover */
-#define  PCI_ERR_COR_REP_TIMER 0x00001000      /* Replay Timer Timeout */
-#define PCI_ERR_COR_MASK       20      /* Correctable Error Mask */
-       /* Same bits as above */
-#define PCI_ERR_CAP            24      /* Advanced Error Capabilities */
-#define  PCI_ERR_CAP_FEP(x)    ((x) & 31)      /* First Error Pointer */
-#define  PCI_ERR_CAP_ECRC_GENC 0x00000020      /* ECRC Generation Capable */
-#define  PCI_ERR_CAP_ECRC_GENE 0x00000040      /* ECRC Generation Enable */
-#define  PCI_ERR_CAP_ECRC_CHKC 0x00000080      /* ECRC Check Capable */
-#define  PCI_ERR_CAP_ECRC_CHKE 0x00000100      /* ECRC Check Enable */
-#define PCI_ERR_HEADER_LOG     28      /* Header Log Register (16 bytes) */
-#define PCI_ERR_ROOT_COMMAND   44      /* Root Error Command */
-#define PCI_ERR_ROOT_STATUS    48
-#define PCI_ERR_ROOT_COR_SRC   52
-#define PCI_ERR_ROOT_SRC       54
-
-/* Virtual Channel */
-#define PCI_VC_PORT_REG1       4
-#define PCI_VC_PORT_REG2       8
-#define PCI_VC_PORT_CTRL       12
-#define PCI_VC_PORT_STATUS     14
-#define PCI_VC_RES_CAP         16
-#define PCI_VC_RES_CTRL                20
-#define PCI_VC_RES_STATUS      26
-
-/* Power Budgeting */
-#define PCI_PWR_DSR            4       /* Data Select Register */
-#define PCI_PWR_DATA           8       /* Data Register */
-#define  PCI_PWR_DATA_BASE(x)  ((x) & 0xff)        /* Base Power */
-#define  PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3)    /* Data Scale */
-#define  PCI_PWR_DATA_PM_SUB(x)        (((x) >> 10) & 7)   /* PM Sub State */
-#define  PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
-#define  PCI_PWR_DATA_TYPE(x)  (((x) >> 15) & 7)   /* Type */
-#define  PCI_PWR_DATA_RAIL(x)  (((x) >> 18) & 7)   /* Power Rail */
-#define PCI_PWR_CAP            12      /* Capability */
-#define  PCI_PWR_CAP_BUDGET(x) ((x) & 1)       /* Included in system budget */
+/* Include the pci register defines */
+#include <linux/pci_regs.h>
 
 /* Include the ID list */
-
 #include <linux/pci_ids.h>
 
 /*
@@ -496,11 +70,12 @@ enum pci_mmap_state {
 
 typedef int __bitwise pci_power_t;
 
-#define PCI_D0 ((pci_power_t __force) 0)
-#define PCI_D1 ((pci_power_t __force) 1)
-#define PCI_D2 ((pci_power_t __force) 2)
+#define PCI_D0         ((pci_power_t __force) 0)
+#define PCI_D1         ((pci_power_t __force) 1)
+#define PCI_D2         ((pci_power_t __force) 2)
 #define PCI_D3hot      ((pci_power_t __force) 3)
 #define PCI_D3cold     ((pci_power_t __force) 4)
+#define PCI_UNKNOWN    ((pci_power_t __force) 5)
 #define PCI_POWER_ERROR        ((pci_power_t __force) -1)
 
 /*
@@ -562,11 +137,6 @@ struct pci_dev {
        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  255
-#define PCI_NAME_HALF  __stringify(43) /* less than half to handle slop */
-       char            pretty_name[PCI_NAME_SIZE];     /* pretty name for users to see */
-#endif
 };
 
 #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
@@ -582,15 +152,15 @@ struct pci_dev {
  *     7-10    bridges: address space assigned to buses behind the bridge
  */
 
-#define PCI_ROM_RESOURCE 6
-#define PCI_BRIDGE_RESOURCES 7
-#define PCI_NUM_RESOURCES 11
+#define PCI_ROM_RESOURCE       6
+#define PCI_BRIDGE_RESOURCES   7
+#define PCI_NUM_RESOURCES      11
 
 #ifndef PCI_BUS_NUM_RESOURCES
-#define PCI_BUS_NUM_RESOURCES 8
+#define PCI_BUS_NUM_RESOURCES  8
 #endif
-  
-#define PCI_REGION_FLAG_MASK 0x0fU     /* These bits of resource flags tell us the PCI region flags */
+
+#define PCI_REGION_FLAG_MASK   0x0fU   /* These bits of resource flags tell us the PCI region flags */
 
 struct pci_bus {
        struct list_head node;          /* node in list of buses */
@@ -699,7 +269,7 @@ struct pci_driver {
  * @dev_class_mask: the class mask for this device
  *
  * This macro is used to create a struct pci_device_id that matches a
- * specific PCI class.  The vendor, device, subvendor, and subdevice 
+ * specific PCI class.  The vendor, device, subvendor, and subdevice
  * fields will be set to PCI_ANY_ID.
  */
 #define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \
@@ -707,7 +277,7 @@ struct pci_driver {
        .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
        .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
 
-/* 
+/*
  * pci_module_init is obsolete, this stays here till we fix up all usages of it
  * in the tree.
  */
@@ -749,8 +319,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
 void pci_bus_add_device(struct pci_dev *dev);
-void pci_name_device(struct pci_dev *dev);
-char *pci_class_name(u32 class);
 void pci_read_bridge_bases(struct pci_bus *child);
 struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
 int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
@@ -815,9 +383,12 @@ void pci_set_master(struct pci_dev *dev);
 #define HAVE_PCI_SET_MWI
 int pci_set_mwi(struct pci_dev *dev);
 void pci_clear_mwi(struct pci_dev *dev);
+void pci_intx(struct pci_dev *dev, int enable);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
+void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
 int pci_assign_resource(struct pci_dev *dev, int i);
+void pci_restore_bars(struct pci_dev *dev);
 
 /* ROM control related routines */
 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size);
@@ -865,6 +436,9 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_
 const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
+void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+                 void *userdata);
+
 /* kmem_cache style wrapper around pci_alloc_consistent() */
 
 #include <linux/dmapool.h>
@@ -912,18 +486,26 @@ extern void pci_disable_msix(struct pci_dev *dev);
 extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
 #endif
 
-#endif /* CONFIG_PCI */
-
-/* Include architecture-dependent settings and functions */
+/*
+ * PCI domain support.  Sometimes called PCI segment (eg by ACPI),
+ * a PCI domain is defined to be a set of PCI busses which share
+ * configuration space.
+ */
+#ifndef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+       return 0;
+}
+#endif
 
-#include <asm/pci.h>
+#else /* CONFIG_PCI is not enabled */
 
 /*
  *  If the system does not have PCI, clearly these return errors.  Define
  *  these as simple inline functions to avoid hair in drivers.
  */
 
-#ifndef CONFIG_PCI
 #define _PCI_NOP(o,s,t) \
        static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \
                { return PCIBIOS_FUNC_NOT_SUPPORTED; }
@@ -974,21 +556,11 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en
 
 #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
 
-#else
+#endif /* CONFIG_PCI */
 
-/*
- * PCI domain support.  Sometimes called PCI segment (eg by ACPI),
- * a PCI domain is defined to be a set of PCI busses which share
- * configuration space.
- */
-#ifndef CONFIG_PCI_DOMAINS
-static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
-static inline int pci_proc_domain(struct pci_bus *bus)
-{
-       return 0;
-}
-#endif
-#endif /* !CONFIG_PCI */
+/* Include architecture-dependent settings and functions */
+
+#include <asm/pci.h>
 
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
@@ -1025,13 +597,6 @@ static inline char *pci_name(struct pci_dev *pdev)
        return pdev->dev.bus_id;
 }
 
-/* Some archs want to see the pretty pci name, so use this macro */
-#ifdef CONFIG_PCI_NAMES
-#define pci_pretty_name(dev) ((dev)->pretty_name)
-#else
-#define pci_pretty_name(dev) ""
-#endif
-
 
 /* Some archs don't want to expose struct resource to userland as-is
  * in sysfs and /proc
@@ -1067,7 +632,7 @@ enum pci_fixup_pass {
 
 /* Anonymous variables would be nice... */
 #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \
-       static struct pci_fixup __pci_fixup_##name __attribute_used__   \
+       static const struct pci_fixup __pci_fixup_##name __attribute_used__ \
        __attribute__((__section__(#section))) = { vendor, device, hook };
 #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook)                  \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,                     \
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
new file mode 100644 (file)
index 0000000..e2a089b
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ *     pci_regs.h
+ *
+ *     PCI standard defines
+ *     Copyright 1994, Drew Eckhardt
+ *     Copyright 1997--1999 Martin Mares <mj@ucw.cz>
+ *
+ *     For more information, please consult the following manuals (look at
+ *     http://www.pcisig.com/ for how to get them):
+ *
+ *     PCI BIOS Specification
+ *     PCI Local Bus Specification
+ *     PCI to PCI Bridge Specification
+ *     PCI System Design Guide
+ */
+
+#ifndef LINUX_PCI_REGS_H
+#define LINUX_PCI_REGS_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID          0x00    /* 16 bits */
+#define PCI_DEVICE_ID          0x02    /* 16 bits */
+#define PCI_COMMAND            0x04    /* 16 bits */
+#define  PCI_COMMAND_IO                0x1     /* Enable response in I/O space */
+#define  PCI_COMMAND_MEMORY    0x2     /* Enable response in Memory space */
+#define  PCI_COMMAND_MASTER    0x4     /* Enable bus mastering */
+#define  PCI_COMMAND_SPECIAL   0x8     /* Enable response to special cycles */
+#define  PCI_COMMAND_INVALIDATE        0x10    /* Use memory write and invalidate */
+#define  PCI_COMMAND_VGA_PALETTE 0x20  /* Enable palette snooping */
+#define  PCI_COMMAND_PARITY    0x40    /* Enable parity checking */
+#define  PCI_COMMAND_WAIT      0x80    /* Enable address/data stepping */
+#define  PCI_COMMAND_SERR      0x100   /* Enable SERR */
+#define  PCI_COMMAND_FAST_BACK 0x200   /* Enable back-to-back writes */
+#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
+
+#define PCI_STATUS             0x06    /* 16 bits */
+#define  PCI_STATUS_CAP_LIST   0x10    /* Support Capability List */
+#define  PCI_STATUS_66MHZ      0x20    /* Support 66 Mhz PCI 2.1 bus */
+#define  PCI_STATUS_UDF                0x40    /* Support User Definable Features [obsolete] */
+#define  PCI_STATUS_FAST_BACK  0x80    /* Accept fast-back to back */
+#define  PCI_STATUS_PARITY     0x100   /* Detected parity error */
+#define  PCI_STATUS_DEVSEL_MASK        0x600   /* DEVSEL timing */
+#define  PCI_STATUS_DEVSEL_FAST                0x000
+#define  PCI_STATUS_DEVSEL_MEDIUM      0x200
+#define  PCI_STATUS_DEVSEL_SLOW                0x400
+#define  PCI_STATUS_SIG_TARGET_ABORT   0x800 /* Set on target abort */
+#define  PCI_STATUS_REC_TARGET_ABORT   0x1000 /* Master ack of " */
+#define  PCI_STATUS_REC_MASTER_ABORT   0x2000 /* Set on master abort */
+#define  PCI_STATUS_SIG_SYSTEM_ERROR   0x4000 /* Set when we drive SERR */
+#define  PCI_STATUS_DETECTED_PARITY    0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION     0x08    /* High 24 bits are class, low 8 revision */
+#define PCI_REVISION_ID                0x08    /* Revision ID */
+#define PCI_CLASS_PROG         0x09    /* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE       0x0a    /* Device class */
+
+#define PCI_CACHE_LINE_SIZE    0x0c    /* 8 bits */
+#define PCI_LATENCY_TIMER      0x0d    /* 8 bits */
+#define PCI_HEADER_TYPE                0x0e    /* 8 bits */
+#define  PCI_HEADER_TYPE_NORMAL                0
+#define  PCI_HEADER_TYPE_BRIDGE                1
+#define  PCI_HEADER_TYPE_CARDBUS       2
+
+#define PCI_BIST               0x0f    /* 8 bits */
+#define  PCI_BIST_CODE_MASK    0x0f    /* Return result */
+#define  PCI_BIST_START                0x40    /* 1 to start BIST, 2 secs or less */
+#define  PCI_BIST_CAPABLE      0x80    /* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of
+ * 0xffffffff to the register, and reading it back.  Only
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0     0x10    /* 32 bits */
+#define PCI_BASE_ADDRESS_1     0x14    /* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2     0x18    /* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3     0x1c    /* 32 bits */
+#define PCI_BASE_ADDRESS_4     0x20    /* 32 bits */
+#define PCI_BASE_ADDRESS_5     0x24    /* 32 bits */
+#define  PCI_BASE_ADDRESS_SPACE                0x01    /* 0 = memory, 1 = I/O */
+#define  PCI_BASE_ADDRESS_SPACE_IO     0x01
+#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK        0x06
+#define  PCI_BASE_ADDRESS_MEM_TYPE_32  0x00    /* 32 bit address */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_1M  0x02    /* Below 1M [obsolete] */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_64  0x04    /* 64 bit address */
+#define  PCI_BASE_ADDRESS_MEM_PREFETCH 0x08    /* prefetchable? */
+#define  PCI_BASE_ADDRESS_MEM_MASK     (~0x0fUL)
+#define  PCI_BASE_ADDRESS_IO_MASK      (~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS                0x28
+#define PCI_SUBSYSTEM_VENDOR_ID        0x2c
+#define PCI_SUBSYSTEM_ID       0x2e
+#define PCI_ROM_ADDRESS                0x30    /* Bits 31..11 are address, 10..1 reserved */
+#define  PCI_ROM_ADDRESS_ENABLE        0x01
+#define PCI_ROM_ADDRESS_MASK   (~0x7ffUL)
+
+#define PCI_CAPABILITY_LIST    0x34    /* Offset of first capability list entry */
+
+/* 0x35-0x3b are reserved */
+#define PCI_INTERRUPT_LINE     0x3c    /* 8 bits */
+#define PCI_INTERRUPT_PIN      0x3d    /* 8 bits */
+#define PCI_MIN_GNT            0x3e    /* 8 bits */
+#define PCI_MAX_LAT            0x3f    /* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS                0x18    /* Primary bus number */
+#define PCI_SECONDARY_BUS      0x19    /* Secondary bus number */
+#define PCI_SUBORDINATE_BUS    0x1a    /* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER  0x1b    /* Latency timer for secondary interface */
+#define PCI_IO_BASE            0x1c    /* I/O range behind the bridge */
+#define PCI_IO_LIMIT           0x1d
+#define  PCI_IO_RANGE_TYPE_MASK        0x0fUL  /* I/O bridging type */
+#define  PCI_IO_RANGE_TYPE_16  0x00
+#define  PCI_IO_RANGE_TYPE_32  0x01
+#define  PCI_IO_RANGE_MASK     (~0x0fUL)
+#define PCI_SEC_STATUS         0x1e    /* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE                0x20    /* Memory range behind */
+#define PCI_MEMORY_LIMIT       0x22
+#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
+#define  PCI_MEMORY_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_MEMORY_BASE   0x24    /* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT  0x26
+#define  PCI_PREF_RANGE_TYPE_MASK 0x0fUL
+#define  PCI_PREF_RANGE_TYPE_32        0x00
+#define  PCI_PREF_RANGE_TYPE_64        0x01
+#define  PCI_PREF_RANGE_MASK   (~0x0fUL)
+#define PCI_PREF_BASE_UPPER32  0x28    /* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16    0x30    /* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16   0x32
+/* 0x34 same as for htype 0 */
+/* 0x35-0x3b is reserved */
+#define PCI_ROM_ADDRESS1       0x38    /* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL     0x3e
+#define  PCI_BRIDGE_CTL_PARITY 0x01    /* Enable parity detection on secondary interface */
+#define  PCI_BRIDGE_CTL_SERR   0x02    /* The same for SERR forwarding */
+#define  PCI_BRIDGE_CTL_NO_ISA 0x04    /* Disable bridging of ISA ports */
+#define  PCI_BRIDGE_CTL_VGA    0x08    /* Forward VGA addresses */
+#define  PCI_BRIDGE_CTL_MASTER_ABORT   0x20  /* Report master aborts */
+#define  PCI_BRIDGE_CTL_BUS_RESET      0x40    /* Secondary bus reset */
+#define  PCI_BRIDGE_CTL_FAST_BACK      0x80    /* Fast Back2Back enabled on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+#define PCI_CB_CAPABILITY_LIST 0x14
+/* 0x15 reserved */
+#define PCI_CB_SEC_STATUS      0x16    /* Secondary status */
+#define PCI_CB_PRIMARY_BUS     0x18    /* PCI bus number */
+#define PCI_CB_CARD_BUS                0x19    /* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS 0x1a    /* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER   0x1b    /* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0   0x1c
+#define PCI_CB_MEMORY_LIMIT_0  0x20
+#define PCI_CB_MEMORY_BASE_1   0x24
+#define PCI_CB_MEMORY_LIMIT_1  0x28
+#define PCI_CB_IO_BASE_0       0x2c
+#define PCI_CB_IO_BASE_0_HI    0x2e
+#define PCI_CB_IO_LIMIT_0      0x30
+#define PCI_CB_IO_LIMIT_0_HI   0x32
+#define PCI_CB_IO_BASE_1       0x34
+#define PCI_CB_IO_BASE_1_HI    0x36
+#define PCI_CB_IO_LIMIT_1      0x38
+#define PCI_CB_IO_LIMIT_1_HI   0x3a
+#define  PCI_CB_IO_RANGE_MASK  (~0x03UL)
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_CB_BRIDGE_CONTROL  0x3e
+#define  PCI_CB_BRIDGE_CTL_PARITY      0x01    /* Similar to standard bridge control register */
+#define  PCI_CB_BRIDGE_CTL_SERR                0x02
+#define  PCI_CB_BRIDGE_CTL_ISA         0x04
+#define  PCI_CB_BRIDGE_CTL_VGA         0x08
+#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT        0x20
+#define  PCI_CB_BRIDGE_CTL_CB_RESET    0x40    /* CardBus reset */
+#define  PCI_CB_BRIDGE_CTL_16BIT_INT   0x80    /* Enable interrupt for 16-bit cards */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define  PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID     0x40
+#define PCI_CB_SUBSYSTEM_ID            0x42
+#define PCI_CB_LEGACY_MODE_BASE                0x44    /* 16-bit PC Card legacy mode base address (ExCa) */
+/* 0x48-0x7f reserved */
+
+/* Capability lists */
+
+#define PCI_CAP_LIST_ID                0       /* Capability ID */
+#define  PCI_CAP_ID_PM         0x01    /* Power Management */
+#define  PCI_CAP_ID_AGP                0x02    /* Accelerated Graphics Port */
+#define  PCI_CAP_ID_VPD                0x03    /* Vital Product Data */
+#define  PCI_CAP_ID_SLOTID     0x04    /* Slot Identification */
+#define  PCI_CAP_ID_MSI                0x05    /* Message Signalled Interrupts */
+#define  PCI_CAP_ID_CHSWP      0x06    /* CompactPCI HotSwap */
+#define  PCI_CAP_ID_PCIX       0x07    /* PCI-X */
+#define  PCI_CAP_ID_SHPC       0x0C    /* PCI Standard Hot-Plug Controller */
+#define  PCI_CAP_ID_EXP        0x10    /* PCI Express */
+#define  PCI_CAP_ID_MSIX       0x11    /* MSI-X */
+#define PCI_CAP_LIST_NEXT      1       /* Next capability in the list */
+#define PCI_CAP_FLAGS          2       /* Capability defined flags (16 bits) */
+#define PCI_CAP_SIZEOF         4
+
+/* Power Management Registers */
+
+#define PCI_PM_PMC             2       /* PM Capabilities Register */
+#define  PCI_PM_CAP_VER_MASK   0x0007  /* Version */
+#define  PCI_PM_CAP_PME_CLOCK  0x0008  /* PME clock required */
+#define  PCI_PM_CAP_RESERVED    0x0010  /* Reserved field */
+#define  PCI_PM_CAP_DSI                0x0020  /* Device specific initialization */
+#define  PCI_PM_CAP_AUX_POWER  0x01C0  /* Auxilliary power support mask */
+#define  PCI_PM_CAP_D1         0x0200  /* D1 power state support */
+#define  PCI_PM_CAP_D2         0x0400  /* D2 power state support */
+#define  PCI_PM_CAP_PME                0x0800  /* PME pin supported */
+#define  PCI_PM_CAP_PME_MASK   0xF800  /* PME Mask of all supported states */
+#define  PCI_PM_CAP_PME_D0     0x0800  /* PME# from D0 */
+#define  PCI_PM_CAP_PME_D1     0x1000  /* PME# from D1 */
+#define  PCI_PM_CAP_PME_D2     0x2000  /* PME# from D2 */
+#define  PCI_PM_CAP_PME_D3     0x4000  /* PME# from D3 (hot) */
+#define  PCI_PM_CAP_PME_D3cold 0x8000  /* PME# from D3 (cold) */
+#define PCI_PM_CTRL            4       /* PM control and status register */
+#define  PCI_PM_CTRL_STATE_MASK        0x0003  /* Current power state (D0 to D3) */
+#define  PCI_PM_CTRL_NO_SOFT_RESET     0x0004  /* No reset for D3hot->D0 */
+#define  PCI_PM_CTRL_PME_ENABLE        0x0100  /* PME pin enable */
+#define  PCI_PM_CTRL_DATA_SEL_MASK     0x1e00  /* Data select (??) */
+#define  PCI_PM_CTRL_DATA_SCALE_MASK   0x6000  /* Data scale (??) */
+#define  PCI_PM_CTRL_PME_STATUS        0x8000  /* PME pin status */
+#define PCI_PM_PPB_EXTENSIONS  6       /* PPB support extensions (??) */
+#define  PCI_PM_PPB_B2_B3      0x40    /* Stop clock when in D3hot (??) */
+#define  PCI_PM_BPCC_ENABLE    0x80    /* Bus power/clock control enable (??) */
+#define PCI_PM_DATA_REGISTER   7       /* (??) */
+#define PCI_PM_SIZEOF          8
+
+/* AGP registers */
+
+#define PCI_AGP_VERSION                2       /* BCD version number */
+#define PCI_AGP_RFU            3       /* Rest of capability flags */
+#define PCI_AGP_STATUS         4       /* Status register */
+#define  PCI_AGP_STATUS_RQ_MASK        0xff000000      /* Maximum number of requests - 1 */
+#define  PCI_AGP_STATUS_SBA    0x0200  /* Sideband addressing supported */
+#define  PCI_AGP_STATUS_64BIT  0x0020  /* 64-bit addressing supported */
+#define  PCI_AGP_STATUS_FW     0x0010  /* FW transfers supported */
+#define  PCI_AGP_STATUS_RATE4  0x0004  /* 4x transfer rate supported */
+#define  PCI_AGP_STATUS_RATE2  0x0002  /* 2x transfer rate supported */
+#define  PCI_AGP_STATUS_RATE1  0x0001  /* 1x transfer rate supported */
+#define PCI_AGP_COMMAND                8       /* Control register */
+#define  PCI_AGP_COMMAND_RQ_MASK 0xff000000  /* Master: Maximum number of requests */
+#define  PCI_AGP_COMMAND_SBA   0x0200  /* Sideband addressing enabled */
+#define  PCI_AGP_COMMAND_AGP   0x0100  /* Allow processing of AGP transactions */
+#define  PCI_AGP_COMMAND_64BIT 0x0020  /* Allow processing of 64-bit addresses */
+#define  PCI_AGP_COMMAND_FW    0x0010  /* Force FW transfers */
+#define  PCI_AGP_COMMAND_RATE4 0x0004  /* Use 4x rate */
+#define  PCI_AGP_COMMAND_RATE2 0x0002  /* Use 2x rate */
+#define  PCI_AGP_COMMAND_RATE1 0x0001  /* Use 1x rate */
+#define PCI_AGP_SIZEOF         12
+
+/* Vital Product Data */
+
+#define PCI_VPD_ADDR           2       /* Address to access (15 bits!) */
+#define  PCI_VPD_ADDR_MASK     0x7fff  /* Address mask */
+#define  PCI_VPD_ADDR_F                0x8000  /* Write 0, 1 indicates completion */
+#define PCI_VPD_DATA           4       /* 32-bits of data returned here */
+
+/* Slot Identification */
+
+#define PCI_SID_ESR            2       /* Expansion Slot Register */
+#define  PCI_SID_ESR_NSLOTS    0x1f    /* Number of expansion slots available */
+#define  PCI_SID_ESR_FIC       0x20    /* First In Chassis Flag */
+#define PCI_SID_CHASSIS_NR     3       /* Chassis Number */
+
+/* Message Signalled Interrupts registers */
+
+#define PCI_MSI_FLAGS          2       /* Various flags */
+#define  PCI_MSI_FLAGS_64BIT   0x80    /* 64-bit addresses allowed */
+#define  PCI_MSI_FLAGS_QSIZE   0x70    /* Message queue size configured */
+#define  PCI_MSI_FLAGS_QMASK   0x0e    /* Maximum queue size available */
+#define  PCI_MSI_FLAGS_ENABLE  0x01    /* MSI feature enabled */
+#define  PCI_MSI_FLAGS_MASKBIT 0x100   /* 64-bit mask bits allowed */
+#define PCI_MSI_RFU            3       /* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO     4       /* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI     8       /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32                8       /* 16 bits of data for 32-bit devices */
+#define PCI_MSI_DATA_64                12      /* 16 bits of data for 64-bit devices */
+#define PCI_MSI_MASK_BIT       16      /* Mask bits register */
+
+/* CompactPCI Hotswap Register */
+
+#define PCI_CHSWP_CSR          2       /* Control and Status Register */
+#define  PCI_CHSWP_DHA         0x01    /* Device Hiding Arm */
+#define  PCI_CHSWP_EIM         0x02    /* ENUM# Signal Mask */
+#define  PCI_CHSWP_PIE         0x04    /* Pending Insert or Extract */
+#define  PCI_CHSWP_LOO         0x08    /* LED On / Off */
+#define  PCI_CHSWP_PI          0x30    /* Programming Interface */
+#define  PCI_CHSWP_EXT         0x40    /* ENUM# status - extraction */
+#define  PCI_CHSWP_INS         0x80    /* ENUM# status - insertion */
+
+/* PCI-X registers */
+
+#define PCI_X_CMD              2       /* Modes & Features */
+#define  PCI_X_CMD_DPERR_E     0x0001  /* Data Parity Error Recovery Enable */
+#define  PCI_X_CMD_ERO         0x0002  /* Enable Relaxed Ordering */
+#define  PCI_X_CMD_MAX_READ    0x000c  /* Max Memory Read Byte Count */
+#define  PCI_X_CMD_MAX_SPLIT   0x0070  /* Max Outstanding Split Transactions */
+#define  PCI_X_CMD_VERSION(x)  (((x) >> 12) & 3) /* Version */
+#define PCI_X_STATUS           4       /* PCI-X capabilities */
+#define  PCI_X_STATUS_DEVFN    0x000000ff      /* A copy of devfn */
+#define  PCI_X_STATUS_BUS      0x0000ff00      /* A copy of bus nr */
+#define  PCI_X_STATUS_64BIT    0x00010000      /* 64-bit device */
+#define  PCI_X_STATUS_133MHZ   0x00020000      /* 133 MHz capable */
+#define  PCI_X_STATUS_SPL_DISC 0x00040000      /* Split Completion Discarded */
+#define  PCI_X_STATUS_UNX_SPL  0x00080000      /* Unexpected Split Completion */
+#define  PCI_X_STATUS_COMPLEX  0x00100000      /* Device Complexity */
+#define  PCI_X_STATUS_MAX_READ 0x00600000      /* Designed Max Memory Read Count */
+#define  PCI_X_STATUS_MAX_SPLIT        0x03800000      /* Designed Max Outstanding Split Transactions */
+#define  PCI_X_STATUS_MAX_CUM  0x1c000000      /* Designed Max Cumulative Read Size */
+#define  PCI_X_STATUS_SPL_ERR  0x20000000      /* Rcvd Split Completion Error Msg */
+#define  PCI_X_STATUS_266MHZ   0x40000000      /* 266 MHz capable */
+#define  PCI_X_STATUS_533MHZ   0x80000000      /* 533 MHz capable */
+
+/* PCI Express capability registers */
+
+#define PCI_EXP_FLAGS          2       /* Capabilities register */
+#define PCI_EXP_FLAGS_VERS     0x000f  /* Capability version */
+#define PCI_EXP_FLAGS_TYPE     0x00f0  /* Device/Port type */
+#define  PCI_EXP_TYPE_ENDPOINT 0x0     /* Express Endpoint */
+#define  PCI_EXP_TYPE_LEG_END  0x1     /* Legacy Endpoint */
+#define  PCI_EXP_TYPE_ROOT_PORT 0x4    /* Root Port */
+#define  PCI_EXP_TYPE_UPSTREAM 0x5     /* Upstream Port */
+#define  PCI_EXP_TYPE_DOWNSTREAM 0x6   /* Downstream Port */
+#define  PCI_EXP_TYPE_PCI_BRIDGE 0x7   /* PCI/PCI-X Bridge */
+#define PCI_EXP_FLAGS_SLOT     0x0100  /* Slot implemented */
+#define PCI_EXP_FLAGS_IRQ      0x3e00  /* Interrupt message number */
+#define PCI_EXP_DEVCAP         4       /* Device capabilities */
+#define  PCI_EXP_DEVCAP_PAYLOAD        0x07    /* Max_Payload_Size */
+#define  PCI_EXP_DEVCAP_PHANTOM        0x18    /* Phantom functions */
+#define  PCI_EXP_DEVCAP_EXT_TAG        0x20    /* Extended tags */
+#define  PCI_EXP_DEVCAP_L0S    0x1c0   /* L0s Acceptable Latency */
+#define  PCI_EXP_DEVCAP_L1     0xe00   /* L1 Acceptable Latency */
+#define  PCI_EXP_DEVCAP_ATN_BUT        0x1000  /* Attention Button Present */
+#define  PCI_EXP_DEVCAP_ATN_IND        0x2000  /* Attention Indicator Present */
+#define  PCI_EXP_DEVCAP_PWR_IND        0x4000  /* Power Indicator Present */
+#define  PCI_EXP_DEVCAP_PWR_VAL        0x3fc0000 /* Slot Power Limit Value */
+#define  PCI_EXP_DEVCAP_PWR_SCL        0xc000000 /* Slot Power Limit Scale */
+#define PCI_EXP_DEVCTL         8       /* Device Control */
+#define  PCI_EXP_DEVCTL_CERE   0x0001  /* Correctable Error Reporting En. */
+#define  PCI_EXP_DEVCTL_NFERE  0x0002  /* Non-Fatal Error Reporting Enable */
+#define  PCI_EXP_DEVCTL_FERE   0x0004  /* Fatal Error Reporting Enable */
+#define  PCI_EXP_DEVCTL_URRE   0x0008  /* Unsupported Request Reporting En. */
+#define  PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
+#define  PCI_EXP_DEVCTL_PAYLOAD        0x00e0  /* Max_Payload_Size */
+#define  PCI_EXP_DEVCTL_EXT_TAG        0x0100  /* Extended Tag Field Enable */
+#define  PCI_EXP_DEVCTL_PHANTOM        0x0200  /* Phantom Functions Enable */
+#define  PCI_EXP_DEVCTL_AUX_PME        0x0400  /* Auxiliary Power PM Enable */
+#define  PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800  /* Enable No Snoop */
+#define  PCI_EXP_DEVCTL_READRQ 0x7000  /* Max_Read_Request_Size */
+#define PCI_EXP_DEVSTA         10      /* Device Status */
+#define  PCI_EXP_DEVSTA_CED    0x01    /* Correctable Error Detected */
+#define  PCI_EXP_DEVSTA_NFED   0x02    /* Non-Fatal Error Detected */
+#define  PCI_EXP_DEVSTA_FED    0x04    /* Fatal Error Detected */
+#define  PCI_EXP_DEVSTA_URD    0x08    /* Unsupported Request Detected */
+#define  PCI_EXP_DEVSTA_AUXPD  0x10    /* AUX Power Detected */
+#define  PCI_EXP_DEVSTA_TRPND  0x20    /* Transactions Pending */
+#define PCI_EXP_LNKCAP         12      /* Link Capabilities */
+#define PCI_EXP_LNKCTL         16      /* Link Control */
+#define PCI_EXP_LNKSTA         18      /* Link Status */
+#define PCI_EXP_SLTCAP         20      /* Slot Capabilities */
+#define PCI_EXP_SLTCTL         24      /* Slot Control */
+#define PCI_EXP_SLTSTA         26      /* Slot Status */
+#define PCI_EXP_RTCTL          28      /* Root Control */
+#define  PCI_EXP_RTCTL_SECEE   0x01    /* System Error on Correctable Error */
+#define  PCI_EXP_RTCTL_SENFEE  0x02    /* System Error on Non-Fatal Error */
+#define  PCI_EXP_RTCTL_SEFEE   0x04    /* System Error on Fatal Error */
+#define  PCI_EXP_RTCTL_PMEIE   0x08    /* PME Interrupt Enable */
+#define  PCI_EXP_RTCTL_CRSSVE  0x10    /* CRS Software Visibility Enable */
+#define PCI_EXP_RTCAP          30      /* Root Capabilities */
+#define PCI_EXP_RTSTA          32      /* Root Status */
+
+/* Extended Capabilities (PCI-X 2.0 and Express) */
+#define PCI_EXT_CAP_ID(header)         (header & 0x0000ffff)
+#define PCI_EXT_CAP_VER(header)                ((header >> 16) & 0xf)
+#define PCI_EXT_CAP_NEXT(header)       ((header >> 20) & 0xffc)
+
+#define PCI_EXT_CAP_ID_ERR     1
+#define PCI_EXT_CAP_ID_VC      2
+#define PCI_EXT_CAP_ID_DSN     3
+#define PCI_EXT_CAP_ID_PWR     4
+
+/* Advanced Error Reporting */
+#define PCI_ERR_UNCOR_STATUS   4       /* Uncorrectable Error Status */
+#define  PCI_ERR_UNC_TRAIN     0x00000001      /* Training */
+#define  PCI_ERR_UNC_DLP       0x00000010      /* Data Link Protocol */
+#define  PCI_ERR_UNC_POISON_TLP        0x00001000      /* Poisoned TLP */
+#define  PCI_ERR_UNC_FCP       0x00002000      /* Flow Control Protocol */
+#define  PCI_ERR_UNC_COMP_TIME 0x00004000      /* Completion Timeout */
+#define  PCI_ERR_UNC_COMP_ABORT        0x00008000      /* Completer Abort */
+#define  PCI_ERR_UNC_UNX_COMP  0x00010000      /* Unexpected Completion */
+#define  PCI_ERR_UNC_RX_OVER   0x00020000      /* Receiver Overflow */
+#define  PCI_ERR_UNC_MALF_TLP  0x00040000      /* Malformed TLP */
+#define  PCI_ERR_UNC_ECRC      0x00080000      /* ECRC Error Status */
+#define  PCI_ERR_UNC_UNSUP     0x00100000      /* Unsupported Request */
+#define PCI_ERR_UNCOR_MASK     8       /* Uncorrectable Error Mask */
+       /* Same bits as above */
+#define PCI_ERR_UNCOR_SEVER    12      /* Uncorrectable Error Severity */
+       /* Same bits as above */
+#define PCI_ERR_COR_STATUS     16      /* Correctable Error Status */
+#define  PCI_ERR_COR_RCVR      0x00000001      /* Receiver Error Status */
+#define  PCI_ERR_COR_BAD_TLP   0x00000040      /* Bad TLP Status */
+#define  PCI_ERR_COR_BAD_DLLP  0x00000080      /* Bad DLLP Status */
+#define  PCI_ERR_COR_REP_ROLL  0x00000100      /* REPLAY_NUM Rollover */
+#define  PCI_ERR_COR_REP_TIMER 0x00001000      /* Replay Timer Timeout */
+#define PCI_ERR_COR_MASK       20      /* Correctable Error Mask */
+       /* Same bits as above */
+#define PCI_ERR_CAP            24      /* Advanced Error Capabilities */
+#define  PCI_ERR_CAP_FEP(x)    ((x) & 31)      /* First Error Pointer */
+#define  PCI_ERR_CAP_ECRC_GENC 0x00000020      /* ECRC Generation Capable */
+#define  PCI_ERR_CAP_ECRC_GENE 0x00000040      /* ECRC Generation Enable */
+#define  PCI_ERR_CAP_ECRC_CHKC 0x00000080      /* ECRC Check Capable */
+#define  PCI_ERR_CAP_ECRC_CHKE 0x00000100      /* ECRC Check Enable */
+#define PCI_ERR_HEADER_LOG     28      /* Header Log Register (16 bytes) */
+#define PCI_ERR_ROOT_COMMAND   44      /* Root Error Command */
+#define PCI_ERR_ROOT_STATUS    48
+#define PCI_ERR_ROOT_COR_SRC   52
+#define PCI_ERR_ROOT_SRC       54
+
+/* Virtual Channel */
+#define PCI_VC_PORT_REG1       4
+#define PCI_VC_PORT_REG2       8
+#define PCI_VC_PORT_CTRL       12
+#define PCI_VC_PORT_STATUS     14
+#define PCI_VC_RES_CAP         16
+#define PCI_VC_RES_CTRL                20
+#define PCI_VC_RES_STATUS      26
+
+/* Power Budgeting */
+#define PCI_PWR_DSR            4       /* Data Select Register */
+#define PCI_PWR_DATA           8       /* Data Register */
+#define  PCI_PWR_DATA_BASE(x)  ((x) & 0xff)        /* Base Power */
+#define  PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3)    /* Data Scale */
+#define  PCI_PWR_DATA_PM_SUB(x)        (((x) >> 10) & 7)   /* PM Sub State */
+#define  PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
+#define  PCI_PWR_DATA_TYPE(x)  (((x) >> 15) & 7)   /* Type */
+#define  PCI_PWR_DATA_RAIL(x)  (((x) >> 18) & 7)   /* Power Rail */
+#define PCI_PWR_CAP            12      /* Capability */
+#define  PCI_PWR_CAP_BUDGET(x) ((x) & 1)       /* Included in system budget */
+
+#endif /* LINUX_PCI_REGS_H */
index d8a023d804d4606810e5f79b969cc2fad14c69e9..317a979b24de027c572683d458f7020838901783 100644 (file)
@@ -29,6 +29,21 @@ struct plat_serial8250_port {
        unsigned int    flags;          /* UPF_* flags */
 };
 
+/*
+ * Allocate 8250 platform device IDs.  Nothing is implied by
+ * the numbering here, except for the legacy entry being -1.
+ */
+enum {
+       PLAT8250_DEV_LEGACY = -1,
+       PLAT8250_DEV_PLATFORM,
+       PLAT8250_DEV_PLATFORM1,
+       PLAT8250_DEV_FOURPORT,
+       PLAT8250_DEV_ACCENT,
+       PLAT8250_DEV_BOCA,
+       PLAT8250_DEV_HUB6,
+       PLAT8250_DEV_MCA,
+};
+
 /*
  * This should be used by drivers which want to register
  * their own 8250 ports without registering their own
index da7da9c0ed1b50e1f8dac7c08b919c104c287e30..2741c0c55e83e1f486a7effc3772a63da8f4e3ed 100644 (file)
@@ -1167,7 +1167,7 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb,
 
 static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
 {
-       if (len >= skb->len)
+       if (likely(len >= skb->len))
                return 0;
        if (skb->ip_summed == CHECKSUM_HW)
                skb->ip_summed = CHECKSUM_NONE;
index 72463779299659bd338c0008edb0547c636ce5eb..4dbe580f9335833eb5fe78be9e241db64e5ef0fb 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/usb_ch9.h>
 
 #define USB_MAJOR                      180
+#define USB_DEVICE_MAJOR               189
 
 
 #ifdef __KERNEL__
@@ -349,6 +350,7 @@ struct usb_device {
        char *manufacturer;
        char *serial;                   /* static strings from the device */
        struct list_head filelist;
+       struct class_device *class_dev;
        struct dentry *usbfs_dentry;    /* usbfs dentry entry for the device */
 
        /*
@@ -614,7 +616,6 @@ extern int usb_disabled(void);
 #define URB_ISO_ASAP           0x0002  /* iso-only, urb->start_frame ignored */
 #define URB_NO_TRANSFER_DMA_MAP        0x0004  /* urb->transfer_dma valid on submit */
 #define URB_NO_SETUP_DMA_MAP   0x0008  /* urb->setup_dma valid on submit */
-#define URB_ASYNC_UNLINK       0x0010  /* usb_unlink_urb() returns asap */
 #define URB_NO_FSBR            0x0020  /* UHCI-specific */
 #define URB_ZERO_PACKET                0x0040  /* Finish bulk OUTs with short packet */
 #define URB_NO_INTERRUPT       0x0080  /* HINT: no non-error interrupt needed */
@@ -722,13 +723,7 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
  * Initialization:
  *
  * All URBs submitted must initialize the dev, pipe, transfer_flags (may be
- * zero), and complete fields.
- * The URB_ASYNC_UNLINK transfer flag affects later invocations of
- * the usb_unlink_urb() routine.  Note: Failure to set URB_ASYNC_UNLINK
- * with usb_unlink_urb() is deprecated.  For synchronous unlinks use
- * usb_kill_urb() instead.
- *
- * All URBs must also initialize 
+ * zero), and complete fields.  All URBs must also initialize
  * transfer_buffer and transfer_buffer_length.  They may provide the
  * URB_SHORT_NOT_OK transfer flag, indicating that short reads are
  * to be treated as errors; that flag is invalid for write requests.
index 5f5a9d9bd6c2ed77c132e8b8c2f0895340274200..436dd8a2b64ac67bea6d8d183be800a97c9ddc57 100644 (file)
@@ -7,36 +7,18 @@
 struct isp116x_platform_data {
        /* Enable internal resistors on downstream ports */
        unsigned sel15Kres:1;
-       /* Chip's internal clock won't be stopped in suspended state.
-          Setting/unsetting this bit takes effect only if
-          'remote_wakeup_enable' below is not set. */
-       unsigned clknotstop:1;
-       /* On-chip overcurrent protection */
+       /* On-chip overcurrent detection */
        unsigned oc_enable:1;
        /* INT output polarity */
        unsigned int_act_high:1;
        /* INT edge or level triggered */
        unsigned int_edge_triggered:1;
-       /* WAKEUP pin connected - NOT SUPPORTED  */
-       /* unsigned remote_wakeup_connected:1; */
-       /* Wakeup by devices on usb bus enabled */
+       /* Enable wakeup by devices on usb bus (e.g. wakeup
+          by attachment/detachment or by device activity
+          such as moving a mouse). When chosen, this option
+          prevents stopping internal clock, increasing
+          thereby power consumption in suspended state. */
        unsigned remote_wakeup_enable:1;
-       /* Switch or not to switch (keep always powered) */
-       unsigned no_power_switching:1;
-       /* Ganged port power switching (0) or individual port
-          power switching (1) */
-       unsigned power_switching_mode:1;
-       /* Given port_power, msec/2 after power on till power good */
-       u8 potpg;
-       /* Hardware reset set/clear. If implemented, this function must:
-          if set == 0,   deassert chip's HW reset pin
-          otherwise,     assert chip's HW reset pin       */
-       void (*reset) (struct device * dev, int set);
-       /* Hardware clock start/stop. If implemented, this function must:
-          if start == 0,    stop the external clock
-          otherwise,        start the external clock
-        */
-       void (*clock) (struct device * dev, int start);
        /* Inter-io delay (ns). The chip is picky about access timings; it
           expects at least:
           150ns delay between consecutive accesses to DATA_REG,
index 364b046e9f478b545316236d592bf29039c3fad2..227d3378decd8cf86d8467652f6e9ebc9e3daec5 100644 (file)
@@ -258,7 +258,7 @@ extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
 /* ax25_addr.c */
 extern ax25_address null_ax25_address;
 extern char *ax2asc(char *buf, ax25_address *);
-extern ax25_address *asc2ax(char *);
+extern void asc2ax(ax25_address *addr, char *callsign);
 extern int  ax25cmp(ax25_address *, ax25_address *);
 extern int  ax25digicmp(ax25_digi *, ax25_digi *);
 extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *);
index 482eb820f13af0c7c0b5197e45f434967738cc1b..290bab46d457c36dba511f49c69eda6d1998b998 100644 (file)
@@ -33,7 +33,8 @@ extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsi
 extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
 extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);
 extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
-extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *,
-               int);
+
+struct sock;
+extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
 
 #endif /* NET_COMPAT_H */
index 3203eaff4bd4b71dcdbd82fe5242c8cf22d8161c..65ec86678a08e34280fdd23e7e10f2c2cbb1494f 100644 (file)
@@ -233,6 +233,10 @@ extern int                         ip6_ra_control(struct sock *sk, int sel,
 extern int                     ipv6_parse_hopopts(struct sk_buff *skb, int);
 
 extern struct ipv6_txoptions *  ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
+extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
+                                                  int newtype,
+                                                  struct ipv6_opt_hdr __user *newopt,
+                                                  int newoptlen);
 
 extern int ip6_frag_nqueues;
 extern atomic_t ip6_frag_mem;
@@ -373,6 +377,7 @@ extern int                  ip6_append_data(struct sock *sk,
                                                int length,
                                                int transhdrlen,
                                                int hlimit,
+                                               int tclass,
                                                struct ipv6_txoptions *opt,
                                                struct flowi *fl,
                                                struct rt6_info *rt,
index 8b075ab7a26c1bbfe99500f6f0edf858e8dca7ad..4e86f2de6638cc5445baa85ba4b9f56a6e78f000 100644 (file)
@@ -37,7 +37,7 @@ extern int                    datagram_recv_ctl(struct sock *sk,
 extern int                     datagram_send_ctl(struct msghdr *msg,
                                                  struct flowi *fl,
                                                  struct ipv6_txoptions *opt,
-                                                 int *hlimit);
+                                                 int *hlimit, int *tclass);
 
 #define                LOOPBACK4_IPV6          __constant_htonl(0x7f000006)
 
index e43197efeb9c559a459cf199a9908a876eb3a976..3de93357f5ab1e05c370164e5e390eb7d0595f9f 100644 (file)
@@ -12,6 +12,14 @@ config CRC_CCITT
          the kernel tree does. Such modules that use library CRC-CCITT
          functions require M here.
 
+config CRC16
+       tristate "CRC16 functions"
+       help
+         This option is provided for the case where no in-kernel-tree
+         modules require CRC16 functions, but a module built outside
+         the kernel tree does. Such modules that use library CRC16
+         functions require M here.
+
 config CRC32
        tristate "CRC32 functions"
        default y
index 3e2bd0df23bb4c76d745bdee5b71b97a57dd4c8f..d9c38ba05e7bc2fcb3cbbca915bf43c51bd580fd 100644 (file)
@@ -23,11 +23,12 @@ lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
 
-ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 
+ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
   lib-y += dec_and_lock.o
 endif
 
 obj-$(CONFIG_CRC_CCITT)        += crc-ccitt.o
+obj-$(CONFIG_CRC16)    += crc16.o
 obj-$(CONFIG_CRC32)    += crc32.o
 obj-$(CONFIG_LIBCRC32C)        += libcrc32c.o
 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
diff --git a/lib/crc16.c b/lib/crc16.c
new file mode 100644 (file)
index 0000000..011fe57
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *      crc16.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc16.h>
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
+u16 const crc16_table[256] = {
+       0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+       0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+       0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+       0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+       0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+       0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+       0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+       0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+       0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+       0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+       0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+       0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+       0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+       0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+       0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+       0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+       0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+       0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+       0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+       0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+       0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+       0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+       0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+       0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+       0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+       0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+       0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+       0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+       0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+       0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+       0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+       0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+EXPORT_SYMBOL(crc16_table);
+
+/**
+ * Compute the CRC-16 for the data buffer
+ *
+ * @param crc     previous CRC value
+ * @param buffer  data pointer
+ * @param len     number of bytes in the buffer
+ * @return        the updated CRC value
+ */
+u16 crc16(u16 crc, u8 const *buffer, size_t len)
+{
+       while (len--)
+               crc = crc16_byte(crc, *buffer++);
+       return crc;
+}
+EXPORT_SYMBOL(crc16);
+
+MODULE_DESCRIPTION("CRC16 calculations");
+MODULE_LICENSE("GPL");
+
index 13492d66b7c809ff603f6c996f5ea1aafbe51a34..afa06e184d88a93311708bdfb1e15077859e29c4 100644 (file)
@@ -88,7 +88,7 @@ static kmem_cache_t *sn_cache;
    policied. */
 static int policy_zone;
 
-static struct mempolicy default_policy = {
+struct mempolicy default_policy = {
        .refcnt = ATOMIC_INIT(1), /* never free it */
        .policy = MPOL_DEFAULT,
 };
index dca179daf4150d3202e290709e611e13505dbd7d..0164a155b8c492b2ef6918d3b8010d7150126119 100644 (file)
@@ -67,37 +67,34 @@ char *ax2asc(char *buf, ax25_address *a)
 /*
  *     ascii -> ax25 conversion
  */
-ax25_address *asc2ax(char *callsign)
+void asc2ax(ax25_address *addr, char *callsign)
 {
-       static ax25_address addr;
        char *s;
        int n;
 
        for (s = callsign, n = 0; n < 6; n++) {
                if (*s != '\0' && *s != '-')
-                       addr.ax25_call[n] = *s++;
+                       addr->ax25_call[n] = *s++;
                else
-                       addr.ax25_call[n] = ' ';
-               addr.ax25_call[n] <<= 1;
-               addr.ax25_call[n] &= 0xFE;
+                       addr->ax25_call[n] = ' ';
+               addr->ax25_call[n] <<= 1;
+               addr->ax25_call[n] &= 0xFE;
        }
 
        if (*s++ == '\0') {
-               addr.ax25_call[6] = 0x00;
-               return &addr;
+               addr->ax25_call[6] = 0x00;
+               return;
        }
 
-       addr.ax25_call[6] = *s++ - '0';
+       addr->ax25_call[6] = *s++ - '0';
 
        if (*s != '\0') {
-               addr.ax25_call[6] *= 10;
-               addr.ax25_call[6] += *s++ - '0';
+               addr->ax25_call[6] *= 10;
+               addr->ax25_call[6] += *s++ - '0';
        }
 
-       addr.ax25_call[6] <<= 1;
-       addr.ax25_call[6] &= 0x1E;
-
-       return &addr;
+       addr->ax25_call[6] <<= 1;
+       addr->ax25_call[6] &= 0x1E;
 }
 
 /*
index 2b5cf9c51309b3bf7f05a504a1ab6ea2d21b534a..bb7246683b7421cb40c81f7d605ad5e6c584eb47 100644 (file)
@@ -104,12 +104,28 @@ out:
 static struct ip_conntrack_helper helper = {
        .name                   = "netbios-ns",
        .tuple = {
-               .src.u.udp.port = __constant_htons(137),
-               .dst.protonum   = IPPROTO_UDP,
+               .src = {
+                       .u = {
+                               .udp = {
+                                       .port   = __constant_htons(137),
+                               }
+                       }
+               },
+               .dst = {
+                       .protonum       = IPPROTO_UDP,
+               },
        },
        .mask = {
-               .src.u.udp.port = 0xFFFF,
-               .dst.protonum   = 0xFF,
+               .src = {
+                       .u = {
+                               .udp = {
+                                       .port   = 0xFFFF,
+                               }
+                       }
+               },
+               .dst = {
+                       .protonum       = 0xFF,
+               },
        },
        .max_expected           = 1,
        .me                     = THIS_MODULE,
index f115a84a4ac628ba5a41883eab33c127ce797f40..f057025a719e0af770f41ef05e653d1c58553cc8 100644 (file)
@@ -92,10 +92,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
        fl.fl_ip_sport = tcph->dest;
        fl.fl_ip_dport = tcph->source;
 
-       if (xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0)) {
-               dst_release(&rt->u.dst);
-               rt = NULL;
-       }
+       xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
 
        return rt;
 }
index 8c0b14e3beecc761e08c684cea964720fd2b2b97..8549f26e2495089c8987fd4c241b9ae002a74393 100644 (file)
@@ -1760,6 +1760,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
                goto cleanup;
        }
 
+       atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
        if (res->fi->fib_nhs > 1)
@@ -1820,7 +1821,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
        err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
        if (err)
                return err;
-       atomic_set(&rth->u.dst.__refcnt, 1);
 
        /* put it into the cache */
        hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
@@ -1834,8 +1834,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
                                   u32 daddr, u32 saddr, u32 tos)
 {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       struct rtable* rth = NULL;
-       unsigned char hop, hopcount, lasthop;
+       struct rtable* rth = NULL, *rtres;
+       unsigned char hop, hopcount;
        int err = -EINVAL;
        unsigned int hash;
 
@@ -1844,8 +1844,6 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
        else
                hopcount = 1;
 
-       lasthop = hopcount - 1;
-
        /* distinguish between multipath and singlepath */
        if (hopcount < 2)
                return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
@@ -1855,6 +1853,10 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
        for (hop = 0; hop < hopcount; hop++) {
                res->nh_sel = hop;
 
+               /* put reference to previous result */
+               if (hop)
+                       ip_rt_put(rtres);
+
                /* create a routing cache entry */
                err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
                                      &rth);
@@ -1863,7 +1865,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
 
                /* put it into the cache */
                hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
-               err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
+               err = rt_intern_hash(hash, rth, &rtres);
                if (err)
                        return err;
 
@@ -1873,13 +1875,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
                                     FIB_RES_NETMASK(*res),
                                     res->prefixlen,
                                     &FIB_RES_NH(*res));
-
-               /* only for the last hop the reference count is handled
-                * outside
-                */
-               if (hop == lasthop)
-                       atomic_set(&(skb->dst->__refcnt), 1);
        }
+       skb->dst = &rtres->u.dst;
        return err;
 #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
        return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
@@ -2208,6 +2205,7 @@ static inline int __mkroute_output(struct rtable **result,
                goto cleanup;
        }               
 
+       atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
        if (res->fi) {
@@ -2290,8 +2288,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
        if (err == 0) {
                u32 tos = RT_FL_TOS(oldflp);
 
-               atomic_set(&rth->u.dst.__refcnt, 1);
-               
                hash = rt_hash_code(oldflp->fl4_dst, 
                                    oldflp->fl4_src ^ (oldflp->oif << 5), tos);
                err = rt_intern_hash(hash, rth, rp);
@@ -2326,6 +2322,10 @@ static inline int ip_mkroute_output(struct rtable** rp,
                        dev2nexthop = FIB_RES_DEV(*res);
                        dev_hold(dev2nexthop);
 
+                       /* put reference to previous result */
+                       if (hop)
+                               ip_rt_put(*rp);
+
                        err = __mkroute_output(&rth, res, fl, oldflp,
                                               dev2nexthop, flags);
 
@@ -2350,7 +2350,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
                        if (err != 0)
                                return err;
                }
-               atomic_set(&(*rp)->u.dst.__refcnt, 1);
                return err;
        } else {
                return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
index 6094db5e11be798631ff7699396f551314374ee2..15e1134da1b2af9e8aba4e110078455d4739894a 100644 (file)
@@ -499,7 +499,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
        /* If this packet has been sent out already, we must
         * adjust the various packet counters.
         */
-       if (after(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
+       if (!before(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
                int diff = old_factor - tcp_skb_pcount(skb) -
                        tcp_skb_pcount(buff);
 
index e5beca7de86c4b67e7455172ac66f6a7ad54ad49..e0bd1013cb0d0053c3d4b0f5fe0bbd2befa9ad48 100644 (file)
@@ -1141,7 +1141,7 @@ int udp_rcv(struct sk_buff *skb)
        if (ulen > len || ulen < sizeof(*uh))
                goto short_packet;
 
-       if (pskb_trim(skb, ulen))
+       if (pskb_trim_rcsum(skb, ulen))
                goto short_packet;
 
        if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
index 01468fab3d3db103388f17d960d46e2f44f4e2f6..cc518405b3e1efc29b87aea3cadb4e0c6d60068f 100644 (file)
@@ -175,10 +175,8 @@ ipv4_connected:
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-               dst_release(dst);
+       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
                goto out;
-       }
 
        /* source address lookup done in ip6_dst_lookup */
 
@@ -390,32 +388,101 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
                put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
        }
 
+       if (np->rxopt.bits.rxtclass) {
+               int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff;
+               put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
+       }
+
        if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
                u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
                put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
        }
+
+       /* HbH is allowed only once */
        if (np->rxopt.bits.hopopts && opt->hop) {
                u8 *ptr = skb->nh.raw + opt->hop;
                put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
        }
-       if (np->rxopt.bits.dstopts && opt->dst0) {
+
+       if (opt->lastopt &&
+           (np->rxopt.bits.dstopts || np->rxopt.bits.srcrt)) {
+               /*
+                * Silly enough, but we need to reparse in order to
+                * report extension headers (except for HbH)
+                * in order.
+                *
+                * Also note that IPV6_RECVRTHDRDSTOPTS is NOT 
+                * (and WILL NOT be) defined because
+                * IPV6_RECVDSTOPTS is more generic. --yoshfuji
+                */
+               unsigned int off = sizeof(struct ipv6hdr);
+               u8 nexthdr = skb->nh.ipv6h->nexthdr;
+
+               while (off <= opt->lastopt) {
+                       unsigned len;
+                       u8 *ptr = skb->nh.raw + off;
+
+                       switch(nexthdr) {
+                       case IPPROTO_DSTOPTS:
+                               nexthdr = ptr[0];
+                               len = (ptr[1] + 1) << 3;
+                               if (np->rxopt.bits.dstopts)
+                                       put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
+                               break;
+                       case IPPROTO_ROUTING:
+                               nexthdr = ptr[0];
+                               len = (ptr[1] + 1) << 3;
+                               if (np->rxopt.bits.srcrt)
+                                       put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
+                               break;
+                       case IPPROTO_AH:
+                               nexthdr = ptr[0];
+                               len = (ptr[1] + 1) << 2;
+                               break;
+                       default:
+                               nexthdr = ptr[0];
+                               len = (ptr[1] + 1) << 3;
+                               break;
+                       }
+
+                       off += len;
+               }
+       }
+
+       /* socket options in old style */
+       if (np->rxopt.bits.rxoinfo) {
+               struct in6_pktinfo src_info;
+
+               src_info.ipi6_ifindex = opt->iif;
+               ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
+               put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
+       }
+       if (np->rxopt.bits.rxohlim) {
+               int hlim = skb->nh.ipv6h->hop_limit;
+               put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
+       }
+       if (np->rxopt.bits.ohopopts && opt->hop) {
+               u8 *ptr = skb->nh.raw + opt->hop;
+               put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
+       }
+       if (np->rxopt.bits.odstopts && opt->dst0) {
                u8 *ptr = skb->nh.raw + opt->dst0;
-               put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+               put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
        }
-       if (np->rxopt.bits.srcrt && opt->srcrt) {
+       if (np->rxopt.bits.osrcrt && opt->srcrt) {
                struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
-               put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
+               put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
        }
-       if (np->rxopt.bits.dstopts && opt->dst1) {
+       if (np->rxopt.bits.odstopts && opt->dst1) {
                u8 *ptr = skb->nh.raw + opt->dst1;
-               put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+               put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
        }
        return 0;
 }
 
 int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                      struct ipv6_txoptions *opt,
-                     int *hlimit)
+                     int *hlimit, int *tclass)
 {
        struct in6_pktinfo *src_info;
        struct cmsghdr *cmsg;
@@ -438,6 +505,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
 
                switch (cmsg->cmsg_type) {
                case IPV6_PKTINFO:
+               case IPV6_2292PKTINFO:
                        if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
                                err = -EINVAL;
                                goto exit_f;
@@ -492,6 +560,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
                        break;
 
+               case IPV6_2292HOPOPTS:
                case IPV6_HOPOPTS:
                         if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
                                err = -EINVAL;
@@ -512,7 +581,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        opt->hopopt = hdr;
                        break;
 
-               case IPV6_DSTOPTS:
+               case IPV6_2292DSTOPTS:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
                                err = -EINVAL;
                                goto exit_f;
@@ -536,6 +605,33 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        opt->dst1opt = hdr;
                        break;
 
+               case IPV6_DSTOPTS:
+               case IPV6_RTHDRDSTOPTS:
+                       if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
+                               err = -EINVAL;
+                               goto exit_f;
+                       }
+
+                       hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
+                       len = ((hdr->hdrlen + 1) << 3);
+                       if (cmsg->cmsg_len < CMSG_LEN(len)) {
+                               err = -EINVAL;
+                               goto exit_f;
+                       }
+                       if (!capable(CAP_NET_RAW)) {
+                               err = -EPERM;
+                               goto exit_f;
+                       }
+                       if (cmsg->cmsg_type == IPV6_DSTOPTS) {
+                               opt->opt_flen += len;
+                               opt->dst1opt = hdr;
+                       } else {
+                               opt->opt_nflen += len;
+                               opt->dst0opt = hdr;
+                       }
+                       break;
+
+               case IPV6_2292RTHDR:
                case IPV6_RTHDR:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
                                err = -EINVAL;
@@ -568,7 +664,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        opt->opt_nflen += len;
                        opt->srcrt = rthdr;
 
-                       if (opt->dst1opt) {
+                       if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {
                                int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);
 
                                opt->opt_nflen += dsthdrlen;
@@ -579,6 +675,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
 
                        break;
 
+               case IPV6_2292HOPLIMIT:
                case IPV6_HOPLIMIT:
                        if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
                                err = -EINVAL;
@@ -588,6 +685,24 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        *hlimit = *(int *)CMSG_DATA(cmsg);
                        break;
 
+               case IPV6_TCLASS:
+                   {
+                       int tc;
+
+                       err = -EINVAL;
+                       if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+                               goto exit_f;
+                       }
+
+                       tc = *(int *)CMSG_DATA(cmsg);
+                       if (tc < 0 || tc > 0xff)
+                               goto exit_f;
+
+                       err = 0;
+                       *tclass = tc;
+
+                       break;
+                   }
                default:
                        LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
                                       cmsg->cmsg_type);
index 5be6da2584eec540d38d554b068b0d6ad5ebd910..47122728212ab570b5eef20d45117bd33419fbc0 100644 (file)
@@ -164,6 +164,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
                return -1;
        }
 
+       opt->lastopt = skb->h.raw - skb->nh.raw;
        opt->dst1 = skb->h.raw - skb->nh.raw;
 
        if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
@@ -243,6 +244,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
 
 looped_back:
        if (hdr->segments_left == 0) {
+               opt->lastopt = skb->h.raw - skb->nh.raw;
                opt->srcrt = skb->h.raw - skb->nh.raw;
                skb->h.raw += (hdr->hdrlen + 1) << 3;
                opt->dst0 = opt->dst1;
@@ -459,11 +461,10 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
                IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
                goto drop;
        }
-       if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
-               __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
-               if (skb->ip_summed == CHECKSUM_HW)
-                       skb->ip_summed = CHECKSUM_NONE;
-       }
+
+       if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
+               goto drop;
+
        return 1;
 
 drop:
@@ -539,10 +540,15 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
                          u8 *proto,
                          struct in6_addr **daddr)
 {
-       if (opt->srcrt)
+       if (opt->srcrt) {
                ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
-       if (opt->dst0opt)
-               ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+               /*
+                * IPV6_RTHDRDSTOPTS is ignored
+                * unless IPV6_RTHDR is set (RFC3542).
+                */
+               if (opt->dst0opt)
+                       ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+       }
        if (opt->hopopt)
                ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
 }
@@ -573,3 +579,97 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
        }
        return opt2;
 }
+
+static int ipv6_renew_option(void *ohdr,
+                            struct ipv6_opt_hdr __user *newopt, int newoptlen,
+                            int inherit,
+                            struct ipv6_opt_hdr **hdr,
+                            char **p)
+{
+       if (inherit) {
+               if (ohdr) {
+                       memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
+                       *hdr = (struct ipv6_opt_hdr *)*p;
+                       *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
+               }
+       } else {
+               if (newopt) {
+                       if (copy_from_user(*p, newopt, newoptlen))
+                               return -EFAULT;
+                       *hdr = (struct ipv6_opt_hdr *)*p;
+                       if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
+                               return -EINVAL;
+                       *p += CMSG_ALIGN(newoptlen);
+               }
+       }
+       return 0;
+}
+
+struct ipv6_txoptions *
+ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
+                  int newtype,
+                  struct ipv6_opt_hdr __user *newopt, int newoptlen)
+{
+       int tot_len = 0;
+       char *p;
+       struct ipv6_txoptions *opt2;
+       int err;
+
+       if (newtype != IPV6_HOPOPTS && opt->hopopt)
+               tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
+       if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
+               tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
+       if (newtype != IPV6_RTHDR && opt->srcrt)
+               tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
+       if (newtype != IPV6_DSTOPTS && opt->dst1opt)
+               tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
+       if (newopt && newoptlen)
+               tot_len += CMSG_ALIGN(newoptlen);
+
+       if (!tot_len)
+               return NULL;
+
+       opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
+       if (!opt2)
+               return ERR_PTR(-ENOBUFS);
+
+       memset(opt2, 0, tot_len);
+
+       opt2->tot_len = tot_len;
+       p = (char *)(opt2 + 1);
+
+       err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
+                               newtype != IPV6_HOPOPTS,
+                               &opt2->hopopt, &p);
+       if (err)
+               goto out;
+
+       err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
+                               newtype != IPV6_RTHDRDSTOPTS,
+                               &opt2->dst0opt, &p);
+       if (err)
+               goto out;
+
+       err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
+                               newtype != IPV6_RTHDR,
+                               (struct ipv6_opt_hdr **)opt2->srcrt, &p);
+       if (err)
+               goto out;
+
+       err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
+                               newtype != IPV6_DSTOPTS,
+                               &opt2->dst1opt, &p);
+       if (err)
+               goto out;
+
+       opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
+                         (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
+                         (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
+       opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
+
+       return opt2;
+out:
+       sock_kfree_s(sk, p, tot_len);
+       return ERR_PTR(err);
+}
+
index fa8f1bb0aa52926d4fe1808cedb81a611fbf2885..b7185fb3377ce08105d46e34741cea01b85610a7 100644 (file)
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        int iif = 0;
        int addr_type = 0;
        int len;
-       int hlimit;
+       int hlimit, tclass;
        int err = 0;
 
        if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -374,7 +374,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        if (err)
                goto out;
        if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
-               goto out_dst_release;
+               goto out;
 
        if (ipv6_addr_is_multicast(&fl.fl6_dst))
                hlimit = np->mcast_hops;
@@ -385,6 +385,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        if (hlimit < 0)
                hlimit = ipv6_get_hoplimit(dst->dev);
 
+       tclass = np->cork.tclass;
+       if (tclass < 0)
+               tclass = 0;
+
        msg.skb = skb;
        msg.offset = skb->nh.raw - skb->data;
 
@@ -400,7 +404,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        err = ip6_append_data(sk, icmpv6_getfrag, &msg,
                              len + sizeof(struct icmp6hdr),
                              sizeof(struct icmp6hdr),
-                             hlimit, NULL, &fl, (struct rt6_info*)dst,
+                             hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
                              MSG_DONTWAIT);
        if (err) {
                ip6_flush_pending_frames(sk);
@@ -434,6 +438,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        struct dst_entry *dst;
        int err = 0;
        int hlimit;
+       int tclass;
 
        saddr = &skb->nh.ipv6h->daddr;
 
@@ -464,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        if (err)
                goto out;
        if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
-               goto out_dst_release;
+               goto out;
 
        if (ipv6_addr_is_multicast(&fl.fl6_dst))
                hlimit = np->mcast_hops;
@@ -475,13 +480,17 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        if (hlimit < 0)
                hlimit = ipv6_get_hoplimit(dst->dev);
 
+       tclass = np->cork.tclass;
+       if (tclass < 0)
+               tclass = 0;
+
        idev = in6_dev_get(skb->dev);
 
        msg.skb = skb;
        msg.offset = 0;
 
        err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
-                               sizeof(struct icmp6hdr), hlimit, NULL, &fl,
+                               sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
                                (struct rt6_info*)dst, MSG_DONTWAIT);
 
        if (err) {
@@ -496,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 out_put: 
        if (likely(idev != NULL))
                in6_dev_put(idev);
-out_dst_release:
        dst_release(dst);
 out: 
        icmpv6_xmit_unlock();
index b6c73da5ff358b5c8b803ce489e46b28a0bd5611..a7db762de14a989049f9a817a16730bd1e1f02b9 100644 (file)
@@ -225,16 +225,20 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
                                         struct ip6_flowlabel * fl,
                                         struct ipv6_txoptions * fopt)
 {
-       struct ipv6_txoptions * fl_opt = fl->opt;
+       struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
 
-       if (fopt == NULL || fopt->opt_flen == 0)
-               return fl_opt;
+       if (fopt == NULL || fopt->opt_flen == 0) {
+               if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
+                       return fl_opt;
+       }
 
        if (fl_opt != NULL) {
                opt_space->hopopt = fl_opt->hopopt;
-               opt_space->dst0opt = fl_opt->dst0opt;
+               opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
                opt_space->srcrt = fl_opt->srcrt;
                opt_space->opt_nflen = fl_opt->opt_nflen;
+               if (fl_opt->dst0opt && !fl_opt->srcrt)
+                       opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
        } else {
                if (fopt->opt_nflen == 0)
                        return fopt;
@@ -310,7 +314,7 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *
                msg.msg_control = (void*)(fl->opt+1);
                flowi.oif = 0;
 
-               err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+               err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
                if (err)
                        goto done;
                err = -EINVAL;
index 01ef94f7c7f1ce5dfd899703d287be308376a83c..2f589f24c09397fa58cffe9d54ec866b02e78598 100644 (file)
@@ -166,7 +166,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        struct ipv6hdr *hdr;
        u8  proto = fl->proto;
        int seg_len = skb->len;
-       int hlimit;
+       int hlimit, tclass;
        u32 mtu;
 
        if (opt) {
@@ -202,7 +202,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
         *      Fill in the IPv6 header
         */
 
-       *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
        hlimit = -1;
        if (np)
                hlimit = np->hop_limit;
@@ -211,6 +210,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        if (hlimit < 0)
                hlimit = ipv6_get_hoplimit(dst->dev);
 
+       tclass = -1;
+       if (np)
+               tclass = np->tclass;
+       if (tclass < 0)
+               tclass = 0;
+
+       *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
+
        hdr->payload_len = htons(seg_len);
        hdr->nexthdr = proto;
        hdr->hop_limit = hlimit;
@@ -762,10 +769,11 @@ out_err_release:
        return err;
 }
 
-int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
-                   void *from, int length, int transhdrlen,
-                   int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt,
-                   unsigned int flags)
+int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+       int offset, int len, int odd, struct sk_buff *skb),
+       void *from, int length, int transhdrlen,
+       int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
+       struct rt6_info *rt, unsigned int flags)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -803,6 +811,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
                np->cork.rt = rt;
                inet->cork.fl = *fl;
                np->cork.hop_limit = hlimit;
+               np->cork.tclass = tclass;
                inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path);
                if (dst_allfrag(rt->u.dst.path))
                        inet->cork.flags |= IPCORK_ALLFRAG;
@@ -1084,7 +1093,8 @@ int ip6_push_pending_frames(struct sock *sk)
 
        skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr));
        
-       *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
+       *(u32*)hdr = fl->fl6_flowlabel |
+                    htonl(0x60000000 | ((int)np->cork.tclass << 20));
 
        if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
                hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
index 09613729404cfaa6b7dc7e7ee13e33f0aa300111..cf94372d1af39980b108f3161fd8d94837e0f94c 100644 (file)
@@ -673,11 +673,12 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if ((dst = ip6_tnl_dst_check(t)) != NULL)
                dst_hold(dst);
-       else
+       else {
                dst = ip6_route_output(NULL, &fl);
 
-       if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
-               goto tx_err_link_failure;
+               if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
+                       goto tx_err_link_failure;
+       }
 
        tdev = dst->dev;
 
index 76466af8331e8c117b12f75b0a6740a5f9a590c5..8567873d0dd85fabd972537eccce7d79d8107611 100644 (file)
@@ -210,39 +210,139 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
                retv = 0;
                break;
 
-       case IPV6_PKTINFO:
+       case IPV6_RECVPKTINFO:
                np->rxopt.bits.rxinfo = valbool;
                retv = 0;
                break;
+               
+       case IPV6_2292PKTINFO:
+               np->rxopt.bits.rxoinfo = valbool;
+               retv = 0;
+               break;
 
-       case IPV6_HOPLIMIT:
+       case IPV6_RECVHOPLIMIT:
                np->rxopt.bits.rxhlim = valbool;
                retv = 0;
                break;
 
-       case IPV6_RTHDR:
+       case IPV6_2292HOPLIMIT:
+               np->rxopt.bits.rxohlim = valbool;
+               retv = 0;
+               break;
+
+       case IPV6_RECVRTHDR:
                if (val < 0 || val > 2)
                        goto e_inval;
                np->rxopt.bits.srcrt = val;
                retv = 0;
                break;
 
-       case IPV6_HOPOPTS:
+       case IPV6_2292RTHDR:
+               if (val < 0 || val > 2)
+                       goto e_inval;
+               np->rxopt.bits.osrcrt = val;
+               retv = 0;
+               break;
+
+       case IPV6_RECVHOPOPTS:
                np->rxopt.bits.hopopts = valbool;
                retv = 0;
                break;
 
-       case IPV6_DSTOPTS:
+       case IPV6_2292HOPOPTS:
+               np->rxopt.bits.ohopopts = valbool;
+               retv = 0;
+               break;
+
+       case IPV6_RECVDSTOPTS:
                np->rxopt.bits.dstopts = valbool;
                retv = 0;
                break;
 
+       case IPV6_2292DSTOPTS:
+               np->rxopt.bits.odstopts = valbool;
+               retv = 0;
+               break;
+
+       case IPV6_TCLASS:
+               if (val < 0 || val > 0xff)
+                       goto e_inval;
+               np->tclass = val;
+               retv = 0;
+               break;
+               
+       case IPV6_RECVTCLASS:
+               np->rxopt.bits.rxtclass = valbool;
+               retv = 0;
+               break;
+
        case IPV6_FLOWINFO:
                np->rxopt.bits.rxflow = valbool;
                retv = 0;
                break;
 
-       case IPV6_PKTOPTIONS:
+       case IPV6_HOPOPTS:
+       case IPV6_RTHDRDSTOPTS:
+       case IPV6_RTHDR:
+       case IPV6_DSTOPTS:
+       {
+               struct ipv6_txoptions *opt;
+               if (optlen == 0)
+                       optval = 0;
+
+               /* hop-by-hop / destination options are privileged option */
+               retv = -EPERM;
+               if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
+                       break;
+
+               retv = -EINVAL;
+               if (optlen & 0x7 || optlen > 8 * 255)
+                       break;
+
+               opt = ipv6_renew_options(sk, np->opt, optname,
+                                        (struct ipv6_opt_hdr __user *)optval,
+                                        optlen);
+               if (IS_ERR(opt)) {
+                       retv = PTR_ERR(opt);
+                       break;
+               }
+
+               /* routing header option needs extra check */
+               if (optname == IPV6_RTHDR && opt->srcrt) {
+                       struct ipv6_rt_hdr *rthdr = opt->srcrt;
+                       if (rthdr->type)
+                               goto sticky_done;
+                       if ((rthdr->hdrlen & 1) ||
+                           (rthdr->hdrlen >> 1) != rthdr->segments_left)
+                               goto sticky_done;
+               }
+
+               retv = 0;
+               if (sk->sk_type == SOCK_STREAM) {
+                       if (opt) {
+                               struct tcp_sock *tp = tcp_sk(sk);
+                               if (!((1 << sk->sk_state) &
+                                     (TCPF_LISTEN | TCPF_CLOSE))
+                                   && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
+                                       tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
+                                       tcp_sync_mss(sk, tp->pmtu_cookie);
+                               }
+                       }
+                       opt = xchg(&np->opt, opt);
+                       sk_dst_reset(sk);
+               } else {
+                       write_lock(&sk->sk_dst_lock);
+                       opt = xchg(&np->opt, opt);
+                       write_unlock(&sk->sk_dst_lock);
+                       sk_dst_reset(sk);
+               }
+sticky_done:
+               if (opt)
+                       sock_kfree_s(sk, opt, opt->tot_len);
+               break;
+       }
+
+       case IPV6_2292PKTOPTIONS:
        {
                struct ipv6_txoptions *opt = NULL;
                struct msghdr msg;
@@ -276,7 +376,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
                msg.msg_controllen = optlen;
                msg.msg_control = (void*)(opt+1);
 
-               retv = datagram_send_ctl(&msg, &fl, opt, &junk);
+               retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
                if (retv)
                        goto done;
 update:
@@ -529,6 +629,17 @@ e_inval:
        return -EINVAL;
 }
 
+int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
+                          char __user *optval, int len)
+{
+       if (!hdr)
+               return 0;
+       len = min_t(int, len, ipv6_optlen(hdr));
+       if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
+               return -EFAULT;
+       return len;
+}
+
 int ipv6_getsockopt(struct sock *sk, int level, int optname,
                    char __user *optval, int __user *optlen)
 {
@@ -567,7 +678,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
                return err;
        }
 
-       case IPV6_PKTOPTIONS:
+       case IPV6_2292PKTOPTIONS:
        {
                struct msghdr msg;
                struct sk_buff *skb;
@@ -601,6 +712,16 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
                                int hlim = np->mcast_hops;
                                put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
                        }
+                       if (np->rxopt.bits.rxoinfo) {
+                               struct in6_pktinfo src_info;
+                               src_info.ipi6_ifindex = np->mcast_oif;
+                               ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
+                               put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
+                       }
+                       if (np->rxopt.bits.rxohlim) {
+                               int hlim = np->mcast_hops;
+                               put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
+                       }
                }
                len -= msg.msg_controllen;
                return put_user(len, optlen);
@@ -625,26 +746,67 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
                val = np->ipv6only;
                break;
 
-       case IPV6_PKTINFO:
+       case IPV6_RECVPKTINFO:
                val = np->rxopt.bits.rxinfo;
                break;
 
-       case IPV6_HOPLIMIT:
+       case IPV6_2292PKTINFO:
+               val = np->rxopt.bits.rxoinfo;
+               break;
+
+       case IPV6_RECVHOPLIMIT:
                val = np->rxopt.bits.rxhlim;
                break;
 
-       case IPV6_RTHDR:
+       case IPV6_2292HOPLIMIT:
+               val = np->rxopt.bits.rxohlim;
+               break;
+
+       case IPV6_RECVRTHDR:
                val = np->rxopt.bits.srcrt;
                break;
 
+       case IPV6_2292RTHDR:
+               val = np->rxopt.bits.osrcrt;
+               break;
+
        case IPV6_HOPOPTS:
+       case IPV6_RTHDRDSTOPTS:
+       case IPV6_RTHDR:
+       case IPV6_DSTOPTS:
+       {
+
+               lock_sock(sk);
+               len = ipv6_getsockopt_sticky(sk, np->opt->hopopt,
+                                            optval, len);
+               release_sock(sk);
+               return put_user(len, optlen);
+       }
+
+       case IPV6_RECVHOPOPTS:
                val = np->rxopt.bits.hopopts;
                break;
 
-       case IPV6_DSTOPTS:
+       case IPV6_2292HOPOPTS:
+               val = np->rxopt.bits.ohopopts;
+               break;
+
+       case IPV6_RECVDSTOPTS:
                val = np->rxopt.bits.dstopts;
                break;
 
+       case IPV6_2292DSTOPTS:
+               val = np->rxopt.bits.odstopts;
+               break;
+
+       case IPV6_TCLASS:
+               val = np->tclass;
+               break;
+
+       case IPV6_RECVTCLASS:
+               val = np->rxopt.bits.rxtclass;
+               break;
+
        case IPV6_FLOWINFO:
                val = np->rxopt.bits.rxflow;
                break;
index a7eae30f4554b86ed9d035f0fa1863fab073a115..555a31347eda60577aef1b098a4120964ed4cc6e 100644 (file)
@@ -447,10 +447,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
                return;
 
        err = xfrm_lookup(&dst, &fl, NULL, 0);
-       if (err < 0) {
-               dst_release(dst);
+       if (err < 0)
                return;
-       }
 
        if (inc_opt) {
                if (dev->addr_len)
@@ -539,10 +537,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
                return;
 
        err = xfrm_lookup(&dst, &fl, NULL, 0);
-       if (err < 0) {
-               dst_release(dst);
+       if (err < 0)
                return;
-       }
 
        len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
        send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
@@ -616,10 +612,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
                return;
 
        err = xfrm_lookup(&dst, &fl, NULL, 0);
-       if (err < 0) {
-               dst_release(dst);
+       if (err < 0)
                return;
-       }
 
        len = sizeof(struct icmp6hdr);
        if (dev->addr_len)
@@ -1353,10 +1347,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                return;
 
        err = xfrm_lookup(&dst, &fl, NULL, 0);
-       if (err) {
-               dst_release(dst);
+       if (err)
                return;
-       }
 
        rt = (struct rt6_info *) dst;
 
index 14316c3ebde41642816fa12cd15021b0fa1ad049..b03e87adca93c149ef2fbf6f5d22677e0c224f65 100644 (file)
@@ -100,11 +100,8 @@ static void send_reset(struct sk_buff *oldskb)
        dst = ip6_route_output(NULL, &fl);
        if (dst == NULL)
                return;
-       if (dst->error ||
-           xfrm_lookup(&dst, &fl, NULL, 0)) {
-               dst_release(dst);
+       if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
                return;
-       }
 
        hh_len = (dst->dev->hard_header_len + 15)&~15;
        nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
index ed3a76b30fd932db9153b0fd31ea405ff97cc15a..5aa3691c578d3a0198aced9809b996a0569f1562 100644 (file)
@@ -655,6 +655,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        struct flowi fl;
        int addr_len = msg->msg_namelen;
        int hlimit = -1;
+       int tclass = -1;
        u16 proto;
        int err;
 
@@ -740,7 +741,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(struct ipv6_txoptions);
 
-               err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+               err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
@@ -755,8 +756,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        }
        if (opt == NULL)
                opt = np->opt;
-       if (flowlabel)
-               opt = fl6_merge_options(&opt_space, flowlabel, opt);
+       opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
        fl.proto = proto;
        rawv6_probe_proto_opt(&fl, msg);
@@ -782,10 +782,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-               dst_release(dst);
+       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
                goto out;
-       }
 
        if (hlimit < 0) {
                if (ipv6_addr_is_multicast(&fl.fl6_dst))
@@ -798,6 +796,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
                        hlimit = ipv6_get_hoplimit(dst->dev);
        }
 
+       if (tclass < 0) {
+               tclass = np->cork.tclass;
+               if (tclass < 0)
+                       tclass = 0;
+       }
+
        if (msg->msg_flags&MSG_CONFIRM)
                goto do_confirm;
 
@@ -806,8 +810,9 @@ back_from_confirm:
                err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags);
        } else {
                lock_sock(sk);
-               err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0,
-                                       hlimit, opt, &fl, (struct rt6_info*)dst, msg->msg_flags);
+               err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
+                       len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
+                       msg->msg_flags);
 
                if (err)
                        ip6_flush_pending_frames(sk);
index 9d9e04344c777c8bd331b7b1f5e566fae38351e4..e4fe9ee484ddab3d0f0fee7e0153e8de4f14c4be 100644 (file)
@@ -479,12 +479,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
        /* Point into the IP datagram 'data' part. */
        if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
                goto err;
-       if (end-offset < skb->len) {
-               if (pskb_trim(skb, end - offset))
-                       goto err;
-               if (skb->ip_summed != CHECKSUM_UNNECESSARY)
-                       skb->ip_summed = CHECKSUM_NONE;
-       }
+       
+       if (pskb_trim_rcsum(skb, end - offset))
+               goto err;
 
        /* Find out which fragments are in front and at the back of us
         * in the chain of fragments so far.  We must know where to put
index 794734f1d230b3b5a5449eb013f4d0545bcb7871..80643e6b346b97b36466fb23099898de5d7ebda3 100644 (file)
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-               dst_release(dst);
+       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
                goto failure;
-       }
 
        if (saddr == NULL) {
                saddr = &fl.fl6_src;
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
        if (dst == NULL) {
                opt = np->opt;
                if (opt == NULL &&
-                   np->rxopt.bits.srcrt == 2 &&
+                   np->rxopt.bits.osrcrt == 2 &&
                    treq->pktopts) {
                        struct sk_buff *pktopts = treq->pktopts;
                        struct inet6_skb_parm *rxopt = IP6CB(pktopts);
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
        }
 
 done:
-       dst_release(dst);
         if (opt && opt != np->opt)
                sock_kfree_s(sk, opt, opt->tot_len);
        return err;
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
        struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (np->rxopt.all) {
-               if ((opt->hop && np->rxopt.bits.hopopts) ||
-                   ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) &&
-                    np->rxopt.bits.rxflow) ||
-                   (opt->srcrt && np->rxopt.bits.srcrt) ||
-                   ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts))
+               if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
+                   ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
+                   (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
+                   ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
                        return 1;
        }
        return 0;
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
        /* sk = NULL, but it is safe for now. RST socket required. */
        if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
 
-               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
-                       dst_release(buff->dst);
+               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
                        return;
-               }
 
                ip6_xmit(NULL, buff, &fl, NULL, 0);
                TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
@@ -1068,10 +1062,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
        fl.fl_ip_sport = t1->source;
 
        if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
-               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
-                       dst_release(buff->dst);
+               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
                        return;
-               }
                ip6_xmit(NULL, buff, &fl, NULL, 0);
                TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
                return;
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        TCP_ECN_create_request(req, skb->h.th);
        treq->pktopts = NULL;
        if (ipv6_opt_accepted(sk, skb) ||
-           np->rxopt.bits.rxinfo ||
-           np->rxopt.bits.rxhlim) {
+           np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+           np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
                atomic_inc(&skb->users);
                treq->pktopts = skb;
        }
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        if (sk_acceptq_is_full(sk))
                goto out_overflow;
 
-       if (np->rxopt.bits.srcrt == 2 &&
+       if (np->rxopt.bits.osrcrt == 2 &&
            opt == NULL && treq->pktopts) {
                struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
                if (rxopt->srcrt)
@@ -1544,9 +1536,9 @@ ipv6_pktoptions:
        tp = tcp_sk(sk);
        if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
            !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
-               if (np->rxopt.bits.rxinfo)
+               if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
                        np->mcast_oif = inet6_iif(opt_skb);
-               if (np->rxopt.bits.rxhlim)
+               if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
                        np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
                if (ipv6_opt_accepted(sk, opt_skb)) {
                        skb_set_owner_r(opt_skb, sk);
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk)
 
                if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
                        sk->sk_err_soft = -err;
-                       dst_release(dst);
                        return err;
                }
 
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
 
                if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
                        sk->sk_route_caps = 0;
-                       dst_release(dst);
                        return err;
                }
 
index 390d750449ce6f801dd3ed906dd68fa7bcc20126..69b146843a20215a7c816a5b07e37788b5bf12c7 100644 (file)
@@ -483,7 +483,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
        }
 
        if (ulen < skb->len) {
-               if (__pskb_trim(skb, ulen))
+               if (pskb_trim_rcsum(skb, ulen))
                        goto discard;
                saddr = &skb->nh.ipv6h->saddr;
                daddr = &skb->nh.ipv6h->daddr;
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        int addr_len = msg->msg_namelen;
        int ulen = len;
        int hlimit = -1;
+       int tclass = -1;
        int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
        int err;
 
@@ -758,7 +759,7 @@ do_udp_sendmsg:
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(*opt);
 
-               err = datagram_send_ctl(msg, fl, opt, &hlimit);
+               err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
@@ -773,8 +774,7 @@ do_udp_sendmsg:
        }
        if (opt == NULL)
                opt = np->opt;
-       if (flowlabel)
-               opt = fl6_merge_options(&opt_space, flowlabel, opt);
+       opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
        fl->proto = IPPROTO_UDP;
        ipv6_addr_copy(&fl->fl6_dst, daddr);
@@ -799,10 +799,8 @@ do_udp_sendmsg:
        if (final_p)
                ipv6_addr_copy(&fl->fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
-               dst_release(dst);
+       if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
                goto out;
-       }
 
        if (hlimit < 0) {
                if (ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -815,6 +813,12 @@ do_udp_sendmsg:
                        hlimit = ipv6_get_hoplimit(dst->dev);
        }
 
+       if (tclass < 0) {
+               tclass = np->tclass;
+               if (tclass < 0)
+                       tclass = 0;
+       }
+
        if (msg->msg_flags&MSG_CONFIRM)
                goto do_confirm;
 back_from_confirm:
@@ -834,9 +838,10 @@ back_from_confirm:
 
 do_append_data:
        up->len += ulen;
-       err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr),
-                             hlimit, opt, fl, (struct rt6_info*)dst,
-                             corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
+       err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
+               sizeof(struct udphdr), hlimit, tclass, opt, fl,
+               (struct rt6_info*)dst,
+               corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
        if (err)
                udp_v6_flush_pending_frames(sk);
        else if (!corkreq)
index 02891ce2db37b3ee52c118f9fcb4ca876ccc18ff..36a77944622b8bd59bf51cdf424919712db5ddef 100644 (file)
@@ -337,13 +337,13 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
                                memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
                                memcpy(callsign, p + 12,   l - 10);
                                callsign[l - 10] = '\0';
-                               facilities->source_call = *asc2ax(callsign);
+                               asc2ax(&facilities->source_call, callsign);
                        }
                        if (*p == FAC_CCITT_SRC_NSAP) {
                                memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
                                memcpy(callsign, p + 12, l - 10);
                                callsign[l - 10] = '\0';
-                               facilities->dest_call = *asc2ax(callsign);
+                               asc2ax(&facilities->dest_call, callsign);
                        }
                        p   += l + 2;
                        n   += l + 2;
index 83c8135e17641dd19bd5fdb204dff3096bdd2eeb..fda737d77edcb6c274efdd3433ff6af9e1134d1e 100644 (file)
@@ -765,8 +765,8 @@ restart:
        switch (policy->action) {
        case XFRM_POLICY_BLOCK:
                /* Prohibit the flow */
-               xfrm_pol_put(policy);
-               return -EPERM;
+               err = -EPERM;
+               goto error;
 
        case XFRM_POLICY_ALLOW:
                if (policy->xfrm_nr == 0) {
@@ -782,8 +782,8 @@ restart:
                 */
                dst = xfrm_find_bundle(fl, policy, family);
                if (IS_ERR(dst)) {
-                       xfrm_pol_put(policy);
-                       return PTR_ERR(dst);
+                       err = PTR_ERR(dst);
+                       goto error;
                }
 
                if (dst)
index 5aa5fe651a8aaac837e09335ecb1dfa31c073654..bfbec5876659caf00bd95c0e2d700402f3649730 100644 (file)
@@ -735,10 +735,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
                if (test_bit(i, &subs->active_mask)) {
                        if (! test_and_set_bit(i, &subs->unlink_mask)) {
                                struct urb *u = subs->dataurb[i].urb;
-                               if (async) {
-                                       u->transfer_flags |= URB_ASYNC_UNLINK;
+                               if (async)
                                        usb_unlink_urb(u);
-                               else
+                               else
                                        usb_kill_urb(u);
                        }
                }
@@ -748,10 +747,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
                        if (test_bit(i+16, &subs->active_mask)) {
                                if (! test_and_set_bit(i+16, &subs->unlink_mask)) {
                                        struct urb *u = subs->syncurb[i].urb;
-                                       if (async) {
-                                               u->transfer_flags |= URB_ASYNC_UNLINK;
+                                       if (async)
                                                usb_unlink_urb(u);
-                                       else
+                                       else
                                                usb_kill_urb(u);
                                }
                        }