]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Nov 2008 03:02:48 +0000 (19:02 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Nov 2008 03:02:48 +0000 (19:02 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: don't grab devices with no input
  HID: fix radio-mr800 hidquirks
  HID: fix kworld fm700 radio hidquirks
  HID: fix start/stop cycle in usbhid driver
  HID: use single threaded work queue for hid_compat
  HID: map macbook keys for "Expose" and "Dashboard"
  HID: support for new unibody macbooks
  HID: fix locking in hidraw_open()

147 files changed:
Documentation/00-INDEX
Documentation/PCI/00-INDEX
Documentation/PCI/MSI-HOWTO.txt [moved from Documentation/MSI-HOWTO.txt with 100% similarity]
Documentation/blockdev/00-INDEX [new file with mode: 0644]
Documentation/blockdev/README.DAC960 [moved from Documentation/README.DAC960 with 100% similarity]
Documentation/blockdev/cciss.txt [moved from Documentation/cciss.txt with 100% similarity]
Documentation/blockdev/cpqarray.txt [moved from Documentation/cpqarray.txt with 100% similarity]
Documentation/blockdev/floppy.txt [moved from Documentation/floppy.txt with 100% similarity]
Documentation/blockdev/nbd.txt [moved from Documentation/nbd.txt with 100% similarity]
Documentation/blockdev/paride.txt [moved from Documentation/paride.txt with 100% similarity]
Documentation/blockdev/ramdisk.txt [moved from Documentation/ramdisk.txt with 100% similarity]
Documentation/ioctl/00-INDEX [new file with mode: 0644]
Documentation/ioctl/ioctl-number.txt [moved from Documentation/ioctl-number.txt with 100% similarity]
Documentation/kernel-parameters.txt
Documentation/serial/00-INDEX [new file with mode: 0644]
Documentation/serial/README.cycladesZ [moved from Documentation/README.cycladesZ with 100% similarity]
Documentation/serial/computone.txt [moved from Documentation/computone.txt with 99% similarity]
Documentation/serial/digiepca.txt [moved from Documentation/digiepca.txt with 100% similarity]
Documentation/serial/hayes-esp.txt [moved from Documentation/hayes-esp.txt with 100% similarity]
Documentation/serial/moxa-smartio [moved from Documentation/moxa-smartio with 100% similarity]
Documentation/serial/riscom8.txt [moved from Documentation/riscom8.txt with 100% similarity]
Documentation/serial/rocket.txt [moved from Documentation/rocket.txt with 100% similarity]
Documentation/serial/specialix.txt [moved from Documentation/specialix.txt with 100% similarity]
Documentation/serial/stallion.txt [moved from Documentation/stallion.txt with 100% similarity]
Documentation/serial/sx.txt [moved from Documentation/sx.txt with 100% similarity]
Documentation/serial/tty.txt [moved from Documentation/tty.txt with 100% similarity]
Makefile
arch/arm/include/asm/dma-mapping.h
arch/arm/include/asm/mach/map.h
arch/arm/mach-clps711x/include/mach/hardware.h
arch/arm/mach-clps7500/core.c
arch/arm/mach-clps7500/include/mach/hardware.h
arch/arm/mach-h720x/include/mach/boards.h
arch/arm/mach-integrator/include/mach/platform.h
arch/arm/mach-realview/clock.c
arch/arm/mach-realview/include/mach/platform.h
arch/arm/mach-versatile/clock.c
arch/arm/mach-versatile/include/mach/platform.h
arch/arm/mm/cache-feroceon-l2.c
arch/arm/mm/mmu.c
arch/arm/plat-iop/setup.c
arch/m68k/kernel/ints.c
arch/parisc/include/asm/smp.h
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/process.c
arch/s390/kernel/setup.c
arch/s390/kernel/sys_s390.c
arch/s390/kernel/topology.c
arch/sh/include/asm/io.h
arch/sh/include/asm/pgtable.h
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/early_printk.c
arch/sh/kernel/timers/timer-tmu.c
arch/sh/lib/copy_page.S
arch/sh/mm/Makefile_32
arch/sh/mm/Makefile_64
arch/sh/mm/init.c
arch/sh/mm/mmap.c [new file with mode: 0644]
arch/sh/mm/pg-sh4.c
arch/x86/include/asm/iommu.h
arch/x86/kernel/early-quirks.c
drivers/ata/libata-sff.c
drivers/block/Kconfig
drivers/block/floppy.c
drivers/block/ub.c
drivers/char/Kconfig
drivers/char/specialix.c
drivers/hwmon/lis3lv02d.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/ide/ide-cs.c
drivers/md/dm-mpath.c
drivers/md/dm-raid1.c
drivers/md/dm-stripe.c
drivers/md/dm.c
drivers/media/video/tvaudio.c
drivers/misc/c2port/core.c
drivers/mtd/maps/cdb89712.c
drivers/mtd/maps/h720x-flash.c
drivers/net/usb/asix.c
drivers/pci/pci-acpi.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pcmcia/ds.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/s390/block/dasd.c
drivers/s390/char/sclp_cmd.c
drivers/s390/cio/device.c
drivers/s390/kvm/kvm_virtio.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_dbf.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/dpt_i2o.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/scsi_error.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
drivers/usb/class/cdc-acm.c
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/core/urb.c
drivers/usb/gadget/f_acm.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-ps3.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/vstusb.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_debug.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_host.h
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/option.c
drivers/usb/storage/Kconfig
drivers/usb/storage/unusual_devs.h
fs/dlm/lockspace.c
fs/inotify.c
include/linux/inotify.h
include/linux/kernel.h
include/linux/serial_core.h
include/linux/slab.h
include/linux/usb.h
init/Kconfig
kernel/audit_tree.c
kernel/auditfilter.c
kernel/exit.c
kernel/fork.c
mm/vmscan.c
net/9p/Kconfig

index 50f99eab0e1fae2b825c8a9339d055877c0c3f7b..2a39aeba1464b8f66ed9cfe1dc7f20d40bbeb15f 100644 (file)
@@ -42,14 +42,8 @@ IRQ.txt
        - description of what an IRQ is.
 ManagementStyle
        - how to (attempt to) manage kernel hackers.
-MSI-HOWTO.txt
-       - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ.
 RCU/
        - directory with info on RCU (read-copy update).
-README.DAC960
-       - info on Mylex DAC960/DAC1100 PCI RAID Controller Driver for Linux.
-README.cycladesZ
-       - info on Cyclades-Z firmware loading.
 SAK.txt
        - info on Secure Attention Keys.
 SM501.txt
@@ -86,20 +80,16 @@ blackfin/
        - directory with documentation for the Blackfin arch.
 block/
        - info on the Block I/O (BIO) layer.
+blockdev/
+       - info on block devices & drivers
 cachetlb.txt
        - describes the cache/TLB flushing interfaces Linux uses.
-cciss.txt
-       - info, major/minor #'s for Compaq's SMART Array Controllers.
 cdrom/
        - directory with information on the CD-ROM drivers that Linux has.
-computone.txt
-       - info on Computone Intelliport II/Plus Multiport Serial Driver.
 connector/
        - docs on the netlink based userspace<->kernel space communication mod.
 console/
        - documentation on Linux console drivers.
-cpqarray.txt
-       - info on using Compaq's SMART2 Intelligent Disk Array Controllers.
 cpu-freq/
        - info on CPU frequency and voltage scaling.
 cpu-hotplug.txt
@@ -126,8 +116,6 @@ device-mapper/
        - directory with info on Device Mapper.
 devices.txt
        - plain ASCII listing of all the nodes in /dev/ with major minor #'s.
-digiepca.txt
-       - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
 dontdiff
        - file containing a list of files that should never be diff'ed.
 driver-model/
@@ -152,14 +140,10 @@ filesystems/
        - info on the vfs and the various filesystems that Linux supports.
 firmware_class/
        - request_firmware() hotplug interface info.
-floppy.txt
-       - notes and driver options for the floppy disk driver.
 frv/
        - Fujitsu FR-V Linux documentation.
 gpio.txt
        - overview of GPIO (General Purpose Input/Output) access conventions.
-hayes-esp.txt
-       - info on using the Hayes ESP serial driver.
 highuid.txt
        - notes on the change from 16 bit to 32 bit user/group IDs.
 timers/
@@ -186,8 +170,6 @@ io_ordering.txt
        - info on ordering I/O writes to memory-mapped addresses.
 ioctl/
        - directory with documents describing various IOCTL calls.
-ioctl-number.txt
-       - how to implement and register device/driver ioctl calls.
 iostats.txt
        - info on I/O statistics Linux kernel provides.
 irqflags-tracing.txt
@@ -250,14 +232,10 @@ mips/
        - directory with info about Linux on MIPS architecture.
 mono.txt
        - how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
-moxa-smartio
-       - file with info on installing/using Moxa multiport serial driver.
 mutex-design.txt
        - info on the generic mutex subsystem.
 namespaces/
        - directory with various information about namespaces
-nbd.txt
-       - info on a TCP implementation of a network block device.
 netlabel/
        - directory with information on the NetLabel subsystem.
 networking/
@@ -270,8 +248,6 @@ numastat.txt
        - info on how to read Numa policy hit/miss statistics in sysfs.
 oops-tracing.txt
        - how to decode those nasty internal kernel error dump messages.
-paride.txt
-       - information about the parallel port IDE subsystem.
 parisc/
        - directory with info on using Linux on PA-RISC architecture.
 parport.txt
@@ -294,18 +270,12 @@ printk-formats.txt
        - how to get printk format specifiers right
 prio_tree.txt
        - info on radix-priority-search-tree use for indexing vmas.
-ramdisk.txt
-       - short guide on how to set up and use the RAM disk.
 rbtree.txt
        - info on what red-black trees are and what they are for.
-riscom8.txt
-       - notes on using the RISCom/8 multi-port serial driver.
 robust-futex-ABI.txt
        - documentation of the robust futex ABI.
 robust-futexes.txt
        - a description of what robust futexes are.
-rocket.txt
-       - info on the Comtrol RocketPort multiport serial driver.
 rt-mutex-design.txt
        - description of the RealTime mutex implementation design.
 rt-mutex.txt
@@ -334,8 +304,6 @@ sparc/
        - directory with info on using Linux on Sparc architecture.
 sparse.txt
        - info on how to obtain and use the sparse tool for typechecking.
-specialix.txt
-       - info on hardware/driver for specialix IO8+ multiport serial card.
 spi/
        - overview of Linux kernel Serial Peripheral Interface (SPI) support.
 spinlocks.txt
@@ -344,14 +312,10 @@ stable_api_nonsense.txt
        - info on why the kernel does not have a stable in-kernel api or abi.
 stable_kernel_rules.txt
        - rules and procedures for the -stable kernel releases.
-stallion.txt
-       - info on using the Stallion multiport serial driver.
 svga.txt
        - short guide on selecting video modes at boot via VGA BIOS.
 sysfs-rules.txt
        - How not to use sysfs.
-sx.txt
-       - info on the Specialix SX/SI multiport serial driver.
 sysctl/
        - directory with info on the /proc/sys/* files.
 sysrq.txt
@@ -360,8 +324,6 @@ telephony/
        - directory with info on telephony (e.g. voice over IP) support.
 time_interpolators.txt
        - info on time interpolators.
-tty.txt
-       - guide to the locking policies of the tty layer.
 uml/
        - directory with information about User Mode Linux.
 unicode.txt
index 49f43946c6b62b0ce8ca4e58c1a66281c324cf2c..812b17fe3ed0d55703d188e3a03b24937c1f1abc 100644 (file)
@@ -1,5 +1,7 @@
 00-INDEX
        - this file
+MSI-HOWTO.txt
+       - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ.
 PCI-DMA-mapping.txt
        - info for PCI drivers using DMA portably across all platforms
 PCIEBUS-HOWTO.txt
diff --git a/Documentation/blockdev/00-INDEX b/Documentation/blockdev/00-INDEX
new file mode 100644 (file)
index 0000000..86f054c
--- /dev/null
@@ -0,0 +1,16 @@
+00-INDEX
+       - this file
+README.DAC960
+       - info on Mylex DAC960/DAC1100 PCI RAID Controller Driver for Linux.
+cciss.txt
+       - info, major/minor #'s for Compaq's SMART Array Controllers.
+cpqarray.txt
+       - info on using Compaq's SMART2 Intelligent Disk Array Controllers.
+floppy.txt
+       - notes and driver options for the floppy disk driver.
+nbd.txt
+       - info on a TCP implementation of a network block device.
+paride.txt
+       - information about the parallel port IDE subsystem.
+ramdisk.txt
+       - short guide on how to set up and use the RAM disk.
diff --git a/Documentation/ioctl/00-INDEX b/Documentation/ioctl/00-INDEX
new file mode 100644 (file)
index 0000000..d2fe4d4
--- /dev/null
@@ -0,0 +1,10 @@
+00-INDEX
+       - this file
+cdrom.txt
+       - summary of CDROM ioctl calls
+hdio.txt
+       - summary of HDIO_ ioctl calls
+ioctl-decoding.txt
+       - how to decode the bits of an IOCTL code
+ioctl-number.txt
+       - how to implement and register device/driver ioctl calls
index c600c4ffc6573a1b8cbf7ae811c31a047dbb1cfc..9fa6508892c287ce68e5449c894ae2fab2c7bbf9 100644 (file)
@@ -629,7 +629,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        digiepca=       [HW,SERIAL]
                        See drivers/char/README.epca and
-                       Documentation/digiepca.txt.
+                       Documentation/serial/digiepca.txt.
 
        disable_mtrr_cleanup [X86]
        enable_mtrr_cleanup [X86]
@@ -740,7 +740,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        See header of drivers/scsi/fdomain.c.
 
        floppy=         [HW]
-                       See Documentation/floppy.txt.
+                       See Documentation/blockdev/floppy.txt.
 
        force_pal_cache_flush
                        [IA-64] Avoid check_sal_cache_flush which may hang on
@@ -1101,7 +1101,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        the same attribute, the last one is used.
 
        load_ramdisk=   [RAM] List of ramdisks to load from floppy
-                       See Documentation/ramdisk.txt.
+                       See Documentation/blockdev/ramdisk.txt.
 
        lockd.nlm_grace_period=P  [NFS] Assign grace period.
                        Format: <integer>
@@ -1596,7 +1596,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        pcd.            [PARIDE]
                        See header of drivers/block/paride/pcd.c.
-                       See also Documentation/paride.txt.
+                       See also Documentation/blockdev/paride.txt.
 
        pci=option[,option...]  [PCI] various PCI subsystem options:
                off             [X86] don't probe for the PCI bus
@@ -1697,7 +1697,7 @@ and is between 256 and 4096 characters. It is defined in the file
        pcmv=           [HW,PCMCIA] BadgePAD 4
 
        pd.             [PARIDE]
-                       See Documentation/paride.txt.
+                       See Documentation/blockdev/paride.txt.
 
        pdcchassis=     [PARISC,HW] Disable/Enable PDC Chassis Status codes at
                        boot time.
@@ -1705,10 +1705,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        See arch/parisc/kernel/pdc_chassis.c
 
        pf.             [PARIDE]
-                       See Documentation/paride.txt.
+                       See Documentation/blockdev/paride.txt.
 
        pg.             [PARIDE]
-                       See Documentation/paride.txt.
+                       See Documentation/blockdev/paride.txt.
 
        pirq=           [SMP,APIC] Manual mp-table setup
                        See Documentation/x86/i386/IO-APIC.txt.
@@ -1778,7 +1778,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk
                        before loading.
-                       See Documentation/ramdisk.txt.
+                       See Documentation/blockdev/ramdisk.txt.
 
        psmouse.proto=  [HW,MOUSE] Highest PS2 mouse protocol extension to
                        probe for; one of (bare|imps|exps|lifebook|any).
@@ -1798,7 +1798,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
 
        pt.             [PARIDE]
-                       See Documentation/paride.txt.
+                       See Documentation/blockdev/paride.txt.
 
        pty.legacy_count=
                        [KNL] Number of legacy pty's. Overwrites compiled-in
@@ -1812,10 +1812,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        See Documentation/md.txt.
 
        ramdisk_blocksize=      [RAM]
-                       See Documentation/ramdisk.txt.
+                       See Documentation/blockdev/ramdisk.txt.
 
        ramdisk_size=   [RAM] Sizes of RAM disks in kilobytes
-                       See Documentation/ramdisk.txt.
+                       See Documentation/blockdev/ramdisk.txt.
 
        rcupdate.blimit=        [KNL,BOOT]
                        Set maximum number of finished RCU callbacks to process
@@ -2147,7 +2147,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        See Documentation/sonypi.txt
 
        specialix=      [HW,SERIAL] Specialix multi-serial port adapter
-                       See Documentation/specialix.txt.
+                       See Documentation/serial/specialix.txt.
 
        spia_io_base=   [HW,MTD]
        spia_fio_base=
diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX
new file mode 100644 (file)
index 0000000..07dcdb0
--- /dev/null
@@ -0,0 +1,24 @@
+00-INDEX
+       - this file.
+README.cycladesZ
+       - info on Cyclades-Z firmware loading.
+computone.txt
+       - info on Computone Intelliport II/Plus Multiport Serial Driver.
+digiepca.txt
+       - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
+hayes-esp.txt
+       - info on using the Hayes ESP serial driver.
+moxa-smartio
+       - file with info on installing/using Moxa multiport serial driver.
+riscom8.txt
+       - notes on using the RISCom/8 multi-port serial driver.
+rocket.txt
+       - info on the Comtrol RocketPort multiport serial driver.
+specialix.txt
+       - info on hardware/driver for specialix IO8+ multiport serial card.
+stallion.txt
+       - info on using the Stallion multiport serial driver.
+sx.txt
+       - info on the Specialix SX/SI multiport serial driver.
+tty.txt
+       - guide to the locking policies of the tty layer.
similarity index 99%
rename from Documentation/computone.txt
rename to Documentation/serial/computone.txt
index 5e2a0c76bfa0b61a697772496a281ed42b6f13c4..c57ea4781e5d7426631eaf308b145fb05b921eef 100644 (file)
@@ -247,7 +247,7 @@ shar archive to make it easier to extract the script from the documentation.
 To create the ip2mkdev shell script change to a convenient directory (/tmp
 works just fine) and run the following command:
 
-       unshar Documentation/computone.txt
+       unshar Documentation/serial/computone.txt
                (This file)
 
 You should now have a file ip2mkdev in your current working directory with
index 7f9ff9bf1544049db441f9d0be0da6df628cd0d5..a9ae5dc0aa161e4f4c809fb6a1f9b8f6e8a0c9c7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 28
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Killer Bat of Doom
 
 # *DOCUMENTATION*
index 1cb8602dd9d5f5b0a29c56b3c8ac80c35f874e85..4ed149cbb32a401c26a6d91f062aa25151d994bf 100644 (file)
@@ -256,8 +256,17 @@ int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
 int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
                size_t, enum dma_data_direction);
 #else
-#define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)     (1)
-#define dmabounce_sync_for_device(dev,dma,off,sz,dir)  (1)
+static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr,
+       unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+       return 1;
+}
+
+static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
+       unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+       return 1;
+}
 
 
 /**
index cb1139ac19432f555b32ccc188b12f838f1ee9d4..39d949b63e80bc0cb23a59b086a2bb24711493ef 100644 (file)
@@ -19,12 +19,13 @@ struct map_desc {
 };
 
 /* types 0-3 are defined in asm/io.h */
-#define MT_CACHECLEAN          4
-#define MT_MINICLEAN           5
-#define MT_LOW_VECTORS         6
-#define MT_HIGH_VECTORS                7
-#define MT_MEMORY              8
-#define MT_ROM                 9
+#define MT_UNCACHED            4
+#define MT_CACHECLEAN          5
+#define MT_MINICLEAN           6
+#define MT_LOW_VECTORS         7
+#define MT_HIGH_VECTORS                8
+#define MT_MEMORY              9
+#define MT_ROM                 10
 
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
index 4c3e101b96c9582fcaf6473a5824fa9e10705f56..b3ebe9e4871fe938585e5cad55eb7390424d25b3 100644 (file)
 #include <asm/hardware/ep7212.h>
 #include <asm/hardware/cs89712.h>
 
-/* dynamic ioremap() areas */
-#define FLASH_START      0x00000000
-#define FLASH_SIZE       0x800000
-#define FLASH_WIDTH      4
-
-#define SRAM_START       0x60000000
-#define SRAM_SIZE        0xc000
-#define SRAM_WIDTH       4
-
-#define BOOTROM_START    0x70000000
-#define BOOTROM_SIZE     0x80
-#define BOOTROM_WIDTH    4
-
-
 /* static cdb89712_map_io() areas */
 #define REGISTER_START   0x80000000
 #define REGISTER_SIZE    0x4000
 #define CEIVA_FLASH_SIZE        0x100000
 #define CEIVA_FLASH_WIDTH       2
 
-#define SRAM_START       0x60000000
-#define SRAM_SIZE        0xc000
-#define SRAM_WIDTH       4
-
-#define BOOTROM_START    0x70000000
-#define BOOTROM_SIZE     0x80
-#define BOOTROM_WIDTH    4
-
 /*
  * SED1355 LCD controller
  */
index c3a33b8a5aacc8406d3bcb7279e824cc7500513f..7e247c04d41c471312ff10161654ecc35b441c46 100644 (file)
@@ -275,9 +275,9 @@ static struct map_desc cl7500_io_desc[] __initdata = {
                .length         = ISA_SIZE,
                .type           = MT_DEVICE
        }, {    /* Flash        */
-               .virtual        = FLASH_BASE,
-               .pfn            = __phys_to_pfn(FLASH_START),
-               .length         = FLASH_SIZE,
+               .virtual        = CLPS7500_FLASH_BASE,
+               .pfn            = __phys_to_pfn(CLPS7500_FLASH_START),
+               .length         = CLPS7500_FLASH_SIZE,
                .type           = MT_DEVICE
        }, {    /* LED          */
                .virtual        = LED_BASE,
index d66578a3371c9f0a972a8266497e37519446875e..a6ad1d44badfd44e1fe140297517259652e3c63a 100644 (file)
@@ -39,9 +39,9 @@
 #define ISA_SIZE               0x00010000
 #define ISA_BASE               0xe1000000
 
-#define FLASH_START            0x01000000      /* XXX */
-#define FLASH_SIZE             0x01000000
-#define FLASH_BASE             0xe2000000
+#define CLPS7500_FLASH_START   0x01000000      /* XXX */
+#define CLPS7500_FLASH_SIZE    0x01000000
+#define CLPS7500_FLASH_BASE    0xe2000000
 
 #define LED_START              0x0302B000
 #define LED_SIZE               0x00001000
index 079b279e1242f8f681c0a0d7995cbe3d4cd1602c..38b8e0d61fbfc93f5d3b6cc89b8211bca0dae5c4 100644 (file)
@@ -19,9 +19,9 @@
 #ifdef CONFIG_ARCH_H7202
 
 /* FLASH */
-#define FLASH_VIRT             0xd0000000
-#define FLASH_PHYS             0x00000000
-#define FLASH_SIZE             0x02000000
+#define H720X_FLASH_VIRT       0xd0000000
+#define H720X_FLASH_PHYS       0x00000000
+#define H720X_FLASH_SIZE       0x02000000
 
 /* onboard LAN controller */
 # define ETH0_PHYS             0x08000000
index 028b87839c0f64b3ef421ee488b9e4c149d75899..e00a2624f269922d579cee9d154acb2d4852bfa9 100644 (file)
  */
 #define uHAL_MEMORY_SIZE                INTEGRATOR_SSRAM_SIZE
 
-/*
- *  Application Flash
- *
- */
-#define FLASH_BASE                      INTEGRATOR_FLASH_BASE
-#define FLASH_SIZE                      INTEGRATOR_FLASH_SIZE
-#define FLASH_END                       (FLASH_BASE + FLASH_SIZE - 1)
-#define FLASH_BLOCK_SIZE                SZ_128K
-
-/*
- *  Boot Flash
- *
- */
-#define EPROM_BASE                      INTEGRATOR_BOOT_ROM_HI
-#define EPROM_SIZE                      INTEGRATOR_BOOT_ROM_SIZE
-#define EPROM_END                       (EPROM_BASE + EPROM_SIZE - 1)
-
 /*
  *  Clean base - dummy
  *
  */
-#define CLEAN_BASE                      EPROM_BASE
+#define CLEAN_BASE                      INTEGRATOR_BOOT_ROM_HI
 
 /*
  *  Timer definitions
index 3e706c57833aebc16a39e0f61a1fa1356e4ed730..3347c4236a60bd6cb2b34cbadc09d0d966614ebf 100644 (file)
@@ -104,7 +104,7 @@ static struct clk uart_clk = {
 
 static struct clk mmci_clk = {
        .name   = "MCLK",
-       .rate   = 33000000,
+       .rate   = 24000000,
 };
 
 int clk_register(struct clk *clk)
index 4034b54950c26d9d811856aceb9d77f5802c113e..793a3a3327121152072645828237c9d3f17c9e8d 100644 (file)
 #define REALVIEW_INTREG_OFFSET         0x8     /* Interrupt control */
 #define REALVIEW_DECODE_OFFSET         0xC     /* Fitted logic modules */
 
-/* 
- *  Application Flash
- * 
- */
-#define FLASH_BASE                      REALVIEW_FLASH_BASE
-#define FLASH_SIZE                      REALVIEW_FLASH_SIZE
-#define FLASH_END                       (FLASH_BASE + FLASH_SIZE - 1)
-#define FLASH_BLOCK_SIZE                SZ_128K
-
-/* 
- *  Boot Flash
- * 
- */
-#define EPROM_BASE                      REALVIEW_BOOT_ROM_HI
-#define EPROM_SIZE                      REALVIEW_BOOT_ROM_SIZE
-#define EPROM_END                       (EPROM_BASE + EPROM_SIZE - 1)
-
 /* 
  *  Clean base - dummy
  * 
  */
-#define CLEAN_BASE                      EPROM_BASE
+#define CLEAN_BASE                      REALVIEW_BOOT_ROM_HI
 
 /*
  * System controller bit assignment
index 9336508ec0b2b1311bbf6c0ceda0fdaa40d8910d..58937f1fb38ce7b4d805f86771d1ccdac9383457 100644 (file)
@@ -105,7 +105,7 @@ static struct clk uart_clk = {
 
 static struct clk mmci_clk = {
        .name   = "MCLK",
-       .rate   = 33000000,
+       .rate   = 24000000,
 };
 
 int clk_register(struct clk *clk)
index 27cbe6a3f2208f5abf4e4f33ce024b8c1498023e..f91ba930ca8a45221b8cb60074ec9bd186731eab 100644 (file)
 #define SIC_INTMASK_PCI1                (1 << SIC_INT_PCI1)
 #define SIC_INTMASK_PCI2                (1 << SIC_INT_PCI2)
 #define SIC_INTMASK_PCI3                (1 << SIC_INT_PCI3)
-/* 
- *  Application Flash
- * 
- */
-#define FLASH_BASE                      VERSATILE_FLASH_BASE
-#define FLASH_SIZE                      VERSATILE_FLASH_SIZE
-#define FLASH_END                       (FLASH_BASE + FLASH_SIZE - 1)
-#define FLASH_BLOCK_SIZE                SZ_128K
-
-/* 
- *  Boot Flash
- * 
- */
-#define EPROM_BASE                      VERSATILE_BOOT_ROM_HI
-#define EPROM_SIZE                      VERSATILE_BOOT_ROM_SIZE
-#define EPROM_END                       (EPROM_BASE + EPROM_SIZE - 1)
 
 /* 
  *  Clean base - dummy
  * 
  */
-#define CLEAN_BASE                      EPROM_BASE
+#define CLEAN_BASE                      VERSATILE_BOOT_ROM_HI
 
 /*
  * System controller bit assignment
index 13cdae8b0d44192107bdb0c626b9e6a3162d8b93..80cd207cbaea14c282e368fe08791d1ebcf09b2c 100644 (file)
@@ -150,7 +150,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
        /*
         * Clean and invalidate partial last cache line.
         */
-       if (end & (CACHE_LINE_SIZE - 1)) {
+       if (start < end && end & (CACHE_LINE_SIZE - 1)) {
                l2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
                end &= ~(CACHE_LINE_SIZE - 1);
        }
@@ -158,7 +158,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
        /*
         * Invalidate all full cache lines between 'start' and 'end'.
         */
-       while (start != end) {
+       while (start < end) {
                unsigned long range_end = calc_range_end(start, end);
                l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE);
                start = range_end;
index e63db11f16a808fc0de3b73ea841ad2797ca597b..7f36c825718d37e6f424c57d8e81e2547692a0e4 100644 (file)
@@ -208,6 +208,12 @@ static struct mem_type mem_types[] = {
                .prot_sect      = PROT_SECT_DEVICE,
                .domain         = DOMAIN_IO,
        },
+       [MT_UNCACHED] = {
+               .prot_pte       = PROT_PTE_DEVICE,
+               .prot_l1        = PMD_TYPE_TABLE,
+               .prot_sect      = PMD_TYPE_SECT | PMD_SECT_XN,
+               .domain         = DOMAIN_IO,
+       },
        [MT_CACHECLEAN] = {
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
                .domain    = DOMAIN_KERNEL,
index 4689db638e95216ebcf1008767e6f8acbcddb4e4..9e573e78176a65d4bfdb93ae19235f5e39d4ca2b 100644 (file)
 #include <asm/hardware/iop3xx.h>
 
 /*
- * Standard IO mapping for all IOP3xx based systems
+ * Standard IO mapping for all IOP3xx based systems.  Note that
+ * the IOP3xx OCCDR must be mapped uncached and unbuffered.
  */
 static struct map_desc iop3xx_std_desc[] __initdata = {
         {      /* mem mapped registers */
                .virtual        = IOP3XX_PERIPHERAL_VIRT_BASE,
                .pfn            = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
                .length         = IOP3XX_PERIPHERAL_SIZE,
-               .type           = MT_DEVICE,
+               .type           = MT_UNCACHED,
         }, {   /* PCI IO space */
                .virtual        = IOP3XX_PCI_LOWER_IO_VA,
                .pfn            = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA),
index 7e8a0d394e6184cbf63a5fb257befa4082ce0148..761ee0440c996a29d4fe784f56571e2cab3358ee 100644 (file)
@@ -133,7 +133,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
 {
        int i;
 
-       BUG_ON(IRQ_USER + cnt >= NR_IRQS);
+       BUG_ON(IRQ_USER + cnt > NR_IRQS);
        m68k_first_user_vec = vec;
        for (i = 0; i < cnt; i++)
                irq_controller[IRQ_USER + i] = &user_irq_controller;
index 398cdbaf4e540f6e6bccffdb84a7fbc8a88e5e98..409e698f436117bd2a18468f8a26ead3cf400d16 100644 (file)
@@ -44,8 +44,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask);
  
 #define PROC_CHANGE_PENALTY    15              /* Schedule penalty */
 
-extern unsigned long cpu_present_mask;
-
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
 #else /* CONFIG_SMP */
index ed500ef799b795a21f322ae0d8e818b8bd926a36..08844fc24a2e7b8f042364e7e0bf44a0ca4bbb3c 100644 (file)
@@ -61,22 +61,25 @@ STACK_SIZE  = 1 << STACK_SHIFT
 
 #ifdef CONFIG_TRACE_IRQFLAGS
        .macro  TRACE_IRQS_ON
-       l       %r1,BASED(.Ltrace_irq_on)
+       basr    %r2,%r0
+       l       %r1,BASED(.Ltrace_irq_on_caller)
        basr    %r14,%r1
        .endm
 
        .macro  TRACE_IRQS_OFF
-       l       %r1,BASED(.Ltrace_irq_off)
+       basr    %r2,%r0
+       l       %r1,BASED(.Ltrace_irq_off_caller)
        basr    %r14,%r1
        .endm
 
        .macro  TRACE_IRQS_CHECK
+       basr    %r2,%r0
        tm      SP_PSW(%r15),0x03       # irqs enabled?
        jz      0f
-       l       %r1,BASED(.Ltrace_irq_on)
+       l       %r1,BASED(.Ltrace_irq_on_caller)
        basr    %r14,%r1
        j       1f
-0:     l       %r1,BASED(.Ltrace_irq_off)
+0:     l       %r1,BASED(.Ltrace_irq_off_caller)
        basr    %r14,%r1
 1:
        .endm
@@ -1113,9 +1116,12 @@ cleanup_io_leave_insn:
 .Lschedtail:   .long   schedule_tail
 .Lsysc_table:  .long   sys_call_table
 #ifdef CONFIG_TRACE_IRQFLAGS
-.Ltrace_irq_on: .long  trace_hardirqs_on
-.Ltrace_irq_off:
-               .long   trace_hardirqs_off
+.Ltrace_irq_on_caller:
+               .long   trace_hardirqs_on_caller
+.Ltrace_irq_off_caller:
+               .long   trace_hardirqs_off_caller
+#endif
+#ifdef CONFIG_LOCKDEP
 .Llockdep_sys_exit:
                .long   lockdep_sys_exit
 #endif
index d7ce150453f2865bfa4c9e99f53c03cda198442d..41aca06682aa19e294ac54160500da46594cb97a 100644 (file)
@@ -61,19 +61,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
 
 #ifdef CONFIG_TRACE_IRQFLAGS
        .macro  TRACE_IRQS_ON
-        brasl  %r14,trace_hardirqs_on
+        basr   %r2,%r0
+        brasl  %r14,trace_hardirqs_on_caller
        .endm
 
        .macro  TRACE_IRQS_OFF
-        brasl  %r14,trace_hardirqs_off
+        basr   %r2,%r0
+        brasl  %r14,trace_hardirqs_off_caller
        .endm
 
        .macro TRACE_IRQS_CHECK
+       basr    %r2,%r0
        tm      SP_PSW(%r15),0x03       # irqs enabled?
        jz      0f
-       brasl   %r14,trace_hardirqs_on
+       brasl   %r14,trace_hardirqs_on_caller
        j       1f
-0:     brasl   %r14,trace_hardirqs_off
+0:     brasl   %r14,trace_hardirqs_off_caller
 1:
        .endm
 #else
index 3e2c05cb6a8733683c57d2935536ee936cc52059..04f8c67a610180413788684390d64bc613b8ca30 100644 (file)
@@ -136,9 +136,12 @@ static void default_idle(void)
                return;
        }
        trace_hardirqs_on();
+       /* Don't trace preempt off for idle. */
+       stop_critical_timings();
        /* Wait for external, I/O or machine check interrupt. */
        __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
                        PSW_MASK_IO | PSW_MASK_EXT);
+       start_critical_timings();
 }
 
 void cpu_idle(void)
index 62122bad1e3316f2112ae66c22e51859c7214b52..400b040df7fa05b1028bb9a9744e002957b29f5b 100644 (file)
@@ -604,13 +604,13 @@ setup_memory(void)
                if (memory_chunk[i].type != CHUNK_READ_WRITE)
                        continue;
                start_chunk = PFN_DOWN(memory_chunk[i].addr);
-               end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1;
+               end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size);
                end_chunk = min(end_chunk, end_pfn);
                if (start_chunk >= end_chunk)
                        continue;
                add_active_range(0, start_chunk, end_chunk);
                pfn = max(start_chunk, start_pfn);
-               for (; pfn <= end_chunk; pfn++)
+               for (; pfn < end_chunk; pfn++)
                        page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY);
        }
 
index 5fdb799062b7abfa1471488fd2582660cd56b08a..4fe952e557ac3bf683bb9535ff89b553035aad25 100644 (file)
@@ -198,7 +198,7 @@ asmlinkage long s390x_newuname(struct new_utsname __user *name)
 {
        int ret = sys_newuname(name);
 
-       if (current->personality == PER_LINUX32 && !ret) {
+       if (personality(current->personality) == PER_LINUX32 && !ret) {
                ret = copy_to_user(name->machine, "s390\0\0\0\0", 8);
                if (ret) ret = -EFAULT;
        }
index 632b13e100538704758cea2eebd75c6cfdc15bf7..a947899dcba1d55f56f8e00af05ab738293df6a3 100644 (file)
@@ -65,18 +65,21 @@ static int machine_has_topology_irq;
 static struct timer_list topology_timer;
 static void set_topology_timer(void);
 static DECLARE_WORK(topology_work, topology_work_fn);
+/* topology_lock protects the core linked list */
+static DEFINE_SPINLOCK(topology_lock);
 
 cpumask_t cpu_core_map[NR_CPUS];
 
 cpumask_t cpu_coregroup_map(unsigned int cpu)
 {
        struct core_info *core = &core_info;
+       unsigned long flags;
        cpumask_t mask;
 
        cpus_clear(mask);
        if (!machine_has_topology)
                return cpu_present_map;
-       mutex_lock(&smp_cpu_state_mutex);
+       spin_lock_irqsave(&topology_lock, flags);
        while (core) {
                if (cpu_isset(cpu, core->mask)) {
                        mask = core->mask;
@@ -84,7 +87,7 @@ cpumask_t cpu_coregroup_map(unsigned int cpu)
                }
                core = core->next;
        }
-       mutex_unlock(&smp_cpu_state_mutex);
+       spin_unlock_irqrestore(&topology_lock, flags);
        if (cpus_empty(mask))
                mask = cpumask_of_cpu(cpu);
        return mask;
@@ -133,7 +136,7 @@ static void tl_to_cores(struct tl_info *info)
        union tl_entry *tle, *end;
        struct core_info *core = &core_info;
 
-       mutex_lock(&smp_cpu_state_mutex);
+       spin_lock_irq(&topology_lock);
        clear_cores();
        tle = info->tle;
        end = (union tl_entry *)((unsigned long)info + info->length);
@@ -157,7 +160,7 @@ static void tl_to_cores(struct tl_info *info)
                }
                tle = next_tle(tle);
        }
-       mutex_unlock(&smp_cpu_state_mutex);
+       spin_unlock_irq(&topology_lock);
 }
 
 static void topology_update_polarization_simple(void)
index 436c28539577ebf75e9d0aefa0514faf2351ec83..65eaae34e753035209455a1916dc68cc4e7b22d6 100644 (file)
@@ -293,6 +293,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
  */
 #define xlate_dev_kmem_ptr(p)  p
 
+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
+int valid_phys_addr_range(unsigned long addr, size_t size);
+int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_IO_H */
index 52220d70a096a378f7dd9c4fbbda635177f4b808..b517ae08b9c0f1794a3c72b52aec0cfe181e4294 100644 (file)
@@ -148,6 +148,12 @@ extern void paging_init(void);
 extern void page_table_range_init(unsigned long start, unsigned long end,
                                  pgd_t *pgd);
 
+#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU)
+extern void kmap_coherent_init(void);
+#else
+#define kmap_coherent_init()   do { } while (0)
+#endif
+
 #include <asm-generic/pgtable.h>
 
 #endif /* __ASM_SH_PGTABLE_H */
index a7412cede534f6cd5e3ef16d060cf1324f8bcd4b..6d9e6972cfc9d8d1cecf57bffb3fe8ab9f72136e 100644 (file)
@@ -119,17 +119,17 @@ static struct plat_sci_port sci_platform_data[] = {
        },{
                .mapbase        = 0xa4e30000,
                .flags          = UPF_BOOT_AUTOCONF,
-               .type           = PORT_SCI,
+               .type           = PORT_SCIFA,
                .irqs           = { 56, 56, 56, 56 },
        },{
                .mapbase        = 0xa4e40000,
                .flags          = UPF_BOOT_AUTOCONF,
-               .type           = PORT_SCI,
+               .type           = PORT_SCIFA,
                .irqs           = { 88, 88, 88, 88 },
        },{
                .mapbase        = 0xa4e50000,
                .flags          = UPF_BOOT_AUTOCONF,
-               .type           = PORT_SCI,
+               .type           = PORT_SCIFA,
                .irqs           = { 109, 109, 109, 109 },
        }, {
                .flags = 0,
index 6b7d166694e28fecc3f949b66cb94ae8c2e53950..a952dcf9999d43bedbef8ff275aa3517fb13ab91 100644 (file)
@@ -75,6 +75,7 @@ static struct console bios_console = {
 #endif
 
 static struct uart_port scif_port = {
+       .type           = PORT_SCIF,
        .mapbase        = CONFIG_EARLY_SCIF_CONSOLE_PORT,
        .membase        = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
 };
@@ -84,9 +85,9 @@ static void scif_sercon_putc(int c)
        while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
                ;
 
-       sci_out(&scif_port, SCxTDR, c);
        sci_in(&scif_port, SCxSR);
        sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
+       sci_out(&scif_port, SCxTDR, c);
 
        while ((sci_in(&scif_port, SCxSR) & 0x40) == 0)
                ;
index aaaf90d06b85f89237e776125c27fd43e6eb8064..3c61ddd4d43e0459c3cd4355133a486f328bea50 100644 (file)
@@ -120,7 +120,7 @@ static void tmu_set_mode(enum clock_event_mode mode,
 {
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               ctrl_outl(ctrl_inl(TMU0_TCNT), TMU0_TCOR);
+               ctrl_outl(tmu_latest_interval[TMU0], TMU0_TCOR);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                ctrl_outl(0, TMU0_TCOR);
index 5d12e657be34e051b8ba2ab676cf472d58ffe77b..43de7e8e4e17df58849aef36e69dd28895e46bab 100644 (file)
@@ -80,6 +80,11 @@ ENTRY(copy_page)
        .section __ex_table, "a";       \
        .long 9999b, 6000f      ;       \
        .previous
+#define EX_NO_POP(...)                 \
+       9999: __VA_ARGS__ ;             \
+       .section __ex_table, "a";       \
+       .long 9999b, 6005f      ;       \
+       .previous
 ENTRY(__copy_user)
        ! Check if small number of bytes
        mov     #11,r0
@@ -139,9 +144,9 @@ EX( mov.b   r1,@r4          )
        bt      1f
 
 2:
-EX(    mov.b   @r5+,r0         )
+EX_NO_POP(     mov.b   @r5+,r0         )
        dt      r6
-EX(    mov.b   r0,@r4          )
+EX_NO_POP(     mov.b   r0,@r4          )
        bf/s    2b
         add    #1,r4
 
@@ -150,7 +155,7 @@ EX( mov.b   r0,@r4          )
 
 # Exception handler:
 .section .fixup, "ax"
-6000:
+6005:
        mov.l   8000f,r1
        mov     r3,r0
        jmp     @r1
index 70e0906023ccc80282d11f2264176c0fa34e907f..f066e76da2044fb9430c80ec2481546ad963c275 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the Linux SuperH-specific parts of the memory manager.
 #
 
-obj-y                  := init.o extable_32.o consistent.o
+obj-y                  := init.o extable_32.o consistent.o mmap.o
 
 ifndef CONFIG_CACHE_OFF
 cache-$(CONFIG_CPU_SH2)                := cache-sh2.o
index 0d92a8a3ac9a1e312870740b7d982e1eafebb021..9481d0f54efdd8a5fd6e76b86c72f12be906604f 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the Linux SuperH-specific parts of the memory manager.
 #
 
-obj-y                  := init.o consistent.o
+obj-y                  := init.o consistent.o mmap.o
 
 mmu-y                  := tlb-nommu.o pg-nommu.o extable_32.o
 mmu-$(CONFIG_MMU)      := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \
index 4abf00031daef8521e39d09a1d032f1d937b26af..6cbef8caeb560e69776579d5525bbad028e9aaec 100644 (file)
@@ -137,6 +137,7 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
 void __init paging_init(void)
 {
        unsigned long max_zone_pfns[MAX_NR_ZONES];
+       unsigned long vaddr;
        int nid;
 
        /* We don't need to map the kernel through the TLB, as
@@ -148,10 +149,15 @@ void __init paging_init(void)
         * check for a null value. */
        set_TTB(swapper_pg_dir);
 
-       /* Populate the relevant portions of swapper_pg_dir so that
+       /*
+        * Populate the relevant portions of swapper_pg_dir so that
         * we can use the fixmap entries without calling kmalloc.
-        * pte's will be filled in by __set_fixmap(). */
-       page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir);
+        * pte's will be filled in by __set_fixmap().
+        */
+       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+       page_table_range_init(vaddr, 0, swapper_pg_dir);
+
+       kmap_coherent_init();
 
        memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
 
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
new file mode 100644 (file)
index 0000000..8837d51
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * arch/sh/mm/mmap.c
+ *
+ * Copyright (C) 2008  Paul Mundt
+ *
+ * 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/io.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+
+/*
+ * You really shouldn't be using read() or write() on /dev/mem.  This
+ * might go away in the future.
+ */
+int valid_phys_addr_range(unsigned long addr, size_t count)
+{
+       if (addr < __MEMORY_START)
+               return 0;
+       if (addr + count > __pa(high_memory))
+               return 0;
+
+       return 1;
+}
+
+int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
+{
+       return 1;
+}
index 38870e0fc182af3347ed90986d9fb3b31578fadb..2fe14da1f83909826d352249ba849488103fb4c2 100644 (file)
@@ -7,6 +7,7 @@
  * Released under the terms of the GNU GPL v2.0.
  */
 #include <linux/mm.h>
+#include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/fs.h>
 #include <linux/highmem.h>
 
 #define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
 
+#define kmap_get_fixmap_pte(vaddr)                                     \
+       pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+
+static pte_t *kmap_coherent_pte;
+
+void __init kmap_coherent_init(void)
+{
+       unsigned long vaddr;
+
+       /* cache the first coherent kmap pte */
+       vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+       kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+
 static inline void *kmap_coherent(struct page *page, unsigned long addr)
 {
        enum fixed_addresses idx;
@@ -34,6 +49,8 @@ static inline void *kmap_coherent(struct page *page, unsigned long addr)
 
        update_mmu_cache(NULL, vaddr, pte);
 
+       set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
+
        return (void *)vaddr;
 }
 
index e4a552d44465b88b0f422a5cb51fcfba23598751..0b500c5b6446e6690846fe9d13a0a5483bef2f20 100644 (file)
@@ -6,7 +6,6 @@ extern void no_iommu_init(void);
 extern struct dma_mapping_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
-extern int dmar_disabled;
 
 extern unsigned long iommu_nr_pages(unsigned long addr, unsigned long len);
 
index 3ce029ffaa55b2085ef4de993b427f86a3cdfdb7..1b894b72c0f5df35a1d489def584086ebb2affe5 100644 (file)
@@ -188,20 +188,6 @@ static void __init ati_bugs_contd(int num, int slot, int func)
 }
 #endif
 
-#ifdef CONFIG_DMAR
-static void __init intel_g33_dmar(int num, int slot, int func)
-{
-       struct acpi_table_header *dmar_tbl;
-       acpi_status status;
-
-       status = acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_tbl);
-       if (ACPI_SUCCESS(status)) {
-               printk(KERN_INFO "BIOS BUG: DMAR advertised on Intel G31/G33 chipset -- ignoring\n");
-               dmar_disabled = 1;
-       }
-}
-#endif
-
 #define QFLAG_APPLY_ONCE       0x1
 #define QFLAG_APPLIED          0x2
 #define QFLAG_DONE             (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
@@ -225,10 +211,6 @@ static struct chipset early_qrk[] __initdata = {
          PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
          PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
-#ifdef CONFIG_DMAR
-       { PCI_VENDOR_ID_INTEL, 0x29c0,
-         PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, intel_g33_dmar },
-#endif
        {}
 };
 
index 4b47394863279606dc7427d79789bdc8c8485d99..9033d164c4ece13f876777fd7fbb549e4c27456b 100644 (file)
@@ -1227,10 +1227,19 @@ fsm_start:
                        /* ATA PIO protocol */
                        if (unlikely((status & ATA_DRQ) == 0)) {
                                /* handle BSY=0, DRQ=0 as error */
-                               if (likely(status & (ATA_ERR | ATA_DF)))
+                               if (likely(status & (ATA_ERR | ATA_DF))) {
                                        /* device stops HSM for abort/error */
                                        qc->err_mask |= AC_ERR_DEV;
-                               else {
+
+                                       /* If diagnostic failed and this is
+                                        * IDENTIFY, it's likely a phantom
+                                        * device.  Mark hint.
+                                        */
+                                       if (qc->dev->horkage &
+                                           ATA_HORKAGE_DIAGNOSTIC)
+                                               qc->err_mask |=
+                                                       AC_ERR_NODEV_HINT;
+                               } else {
                                        /* HSM violation. Let EH handle this.
                                         * Phantom devices also trigger this
                                         * condition.  Mark hint.
index 61ad8d639ba39830ee96687d2ef18d3fcba8cad4..0344a8a8321d130b3833681708426becdcfa45d1 100644 (file)
@@ -21,7 +21,8 @@ config BLK_DEV_FD
        ---help---
          If you want to use the floppy disk drive(s) of your PC under Linux,
          say Y. Information about this driver, especially important for IBM
-         Thinkpad users, is contained in <file:Documentation/floppy.txt>.
+         Thinkpad users, is contained in
+         <file:Documentation/blockdev/floppy.txt>.
          That file also contains the location of the Floppy driver FAQ as
          well as location of the fdutils package used to configure additional
          parameters of the driver at run time.
@@ -76,7 +77,7 @@ config PARIDE
          your computer's parallel port. Most of them are actually IDE devices
          using a parallel port IDE adapter. This option enables the PARIDE
          subsystem which contains drivers for many of these external drives.
-         Read <file:Documentation/paride.txt> for more information.
+         Read <file:Documentation/blockdev/paride.txt> for more information.
 
          If you have said Y to the "Parallel-port support" configuration
          option, you may share a single port between your printer and other
@@ -114,9 +115,9 @@ config BLK_CPQ_DA
        help
          This is the driver for Compaq Smart Array controllers.  Everyone
          using these boards should say Y here.  See the file
-         <file:Documentation/cpqarray.txt> for the current list of boards
-         supported by this driver, and for further information on the use of
-         this driver.
+         <file:Documentation/blockdev/cpqarray.txt> for the current list of
+         boards supported by this driver, and for further information on the
+         use of this driver.
 
 config BLK_CPQ_CISS_DA
        tristate "Compaq Smart Array 5xxx support"
@@ -124,7 +125,7 @@ config BLK_CPQ_CISS_DA
        help
          This is the driver for Compaq Smart Array 5xxx controllers.
          Everyone using these boards should say Y here.
-         See <file:Documentation/cciss.txt> for the current list of
+         See <file:Documentation/blockdev/cciss.txt> for the current list of
          boards supported by this driver, and for further information
          on the use of this driver.
 
@@ -135,7 +136,7 @@ config CISS_SCSI_TAPE
        help
          When enabled (Y), this option allows SCSI tape drives and SCSI medium
          changers (tape robots) to be accessed via a Compaq 5xxx array 
-         controller.  (See <file:Documentation/cciss.txt> for more details.)
+         controller.  (See <file:Documentation/blockdev/cciss.txt> for more details.)
 
          "SCSI support" and "SCSI tape support" must also be enabled for this 
          option to work.
@@ -149,8 +150,8 @@ config BLK_DEV_DAC960
        help
          This driver adds support for the Mylex DAC960, AcceleRAID, and
          eXtremeRAID PCI RAID controllers.  See the file
-         <file:Documentation/README.DAC960> for further information about
-         this driver.
+         <file:Documentation/blockdev/README.DAC960> for further information
+         about this driver.
 
          To compile this driver as a module, choose M here: the
          module will be called DAC960.
@@ -278,9 +279,9 @@ config BLK_DEV_NBD
          userland (making server and client physically the same computer,
          communicating using the loopback network device).
 
-         Read <file:Documentation/nbd.txt> for more information, especially
-         about where to find the server code, which runs in user space and
-         does not need special kernel support.
+         Read <file:Documentation/blockdev/nbd.txt> for more information,
+         especially about where to find the server code, which runs in user
+         space and does not need special kernel support.
 
          Note that this has nothing to do with the network file systems NFS
          or Coda; you can say N here even if you intend to use NFS or Coda.
@@ -321,8 +322,8 @@ config BLK_DEV_RAM
          store a copy of a minimal root file system off of a floppy into RAM
          during the initial install of Linux.
 
-         Note that the kernel command line option "ramdisk=XX" is now
-         obsolete. For details, read <file:Documentation/ramdisk.txt>.
+         Note that the kernel command line option "ramdisk=XX" is now obsolete.
+         For details, read <file:Documentation/blockdev/ramdisk.txt>.
 
          To compile this driver as a module, choose M here: the
          module will be called rd.
index 14db747a636e93a33766e4faf23dbd5b48e5e8bd..cf29cc4e6ab73d2d95e6d4778f576aae9c98b327 100644 (file)
@@ -4124,7 +4124,7 @@ static int __init floppy_setup(char *str)
                printk("\n");
        } else
                DPRINT("botched floppy option\n");
-       DPRINT("Read Documentation/floppy.txt\n");
+       DPRINT("Read Documentation/blockdev/floppy.txt\n");
        return 0;
 }
 
index fccac18d311121d01f28ca4ce819886f79cf300f..048d71d244d7335d3e719e916632ef1a71079465 100644 (file)
@@ -1546,8 +1546,6 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
 
 /*
  * Reset management
- * XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing.
- * XXX Make usb_sync_reset asynchronous.
  */
 
 static void ub_reset_enter(struct ub_dev *sc, int try)
@@ -1632,6 +1630,22 @@ static void ub_reset_task(struct work_struct *work)
        spin_unlock_irqrestore(sc->lock, flags);
 }
 
+/*
+ * XXX Reset brackets are too much hassle to implement, so just stub them
+ * in order to prevent forced unbinding (which deadlocks solid when our
+ * ->disconnect method waits for the reset to complete and this kills keventd).
+ *
+ * XXX Tell Alan to move usb_unlock_device inside of usb_reset_device,
+ * or else the post_reset is invoked, and restats I/O on a locked device.
+ */
+static int ub_pre_reset(struct usb_interface *iface) {
+       return 0;
+}
+
+static int ub_post_reset(struct usb_interface *iface) {
+       return 0;
+}
+
 /*
  * This is called from a process context.
  */
@@ -2446,6 +2460,8 @@ static struct usb_driver ub_driver = {
        .probe =        ub_probe,
        .disconnect =   ub_disconnect,
        .id_table =     ub_usb_ids,
+       .pre_reset =    ub_pre_reset,
+       .post_reset =   ub_post_reset,
 };
 
 static int __init ub_init(void)
index 43b35d0369d6c9486b3f5d677313ece83218130c..43d6ba83a1912ccbc5f668876e8e6cf7a82a3066 100644 (file)
@@ -124,7 +124,7 @@ config COMPUTONE
          which give you many serial ports. You would need something like this
          to connect more than two modems to your Linux box, for instance in
          order to become a dial-in server. If you have a card like that, say
-         Y here and read <file:Documentation/computone.txt>.
+         Y here and read <file:Documentation/serial/computone.txt>.
 
          To compile this driver as module, choose M here: the
          module will be called ip2.
@@ -136,7 +136,7 @@ config ROCKETPORT
          This driver supports Comtrol RocketPort and RocketModem PCI boards.   
           These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
           modems.  For information about the RocketPort/RocketModem  boards
-          and this driver read <file:Documentation/rocket.txt>.
+          and this driver read <file:Documentation/serial/rocket.txt>.
 
          To compile this driver as a module, choose M here: the
          module will be called rocket.
@@ -154,7 +154,7 @@ config CYCLADES
          your Linux box, for instance in order to become a dial-in server.
 
          For information about the Cyclades-Z card, read
-         <file:Documentation/README.cycladesZ>.
+         <file:Documentation/serial/README.cycladesZ>.
 
          To compile this driver as a module, choose M here: the
          module will be called cyclades.
@@ -183,7 +183,7 @@ config DIGIEPCA
          box, for instance in order to become a dial-in server. This driver
          supports the original PC (ISA) boards as well as PCI, and EISA. If
          you have a card like this, say Y here and read the file
-         <file:Documentation/digiepca.txt>.
+         <file:Documentation/serial/digiepca.txt>.
 
          To compile this driver as a module, choose M here: the
          module will be called epca.
@@ -289,7 +289,7 @@ config RISCOM8
          which gives you many serial ports. You would need something like
          this to connect more than two modems to your Linux box, for instance
          in order to become a dial-in server. If you have a card like that,
-         say Y here and read the file <file:Documentation/riscom8.txt>.
+         say Y here and read the file <file:Documentation/serial/riscom8.txt>.
 
          Also it's possible to say M here and compile this driver as kernel
          loadable module; the module will be called riscom8.
@@ -304,8 +304,8 @@ config SPECIALIX
          your Linux box, for instance in order to become a dial-in server.
 
          If you have a card like that, say Y here and read the file
-         <file:Documentation/specialix.txt>. Also it's possible to say M here
-         and compile this driver as kernel loadable module which will be
+         <file:Documentation/serial/specialix.txt>. Also it's possible to say
+         M here and compile this driver as kernel loadable module which will be
          called specialix.
 
 config SX
@@ -313,7 +313,7 @@ config SX
        depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
        help
          This is a driver for the SX and SI multiport serial cards.
-         Please read the file <file:Documentation/sx.txt> for details.
+         Please read the file <file:Documentation/serial/sx.txt> for details.
 
          This driver can only be built as a module ( = code which can be
          inserted in and removed from the running kernel whenever you want).
@@ -344,8 +344,8 @@ config STALDRV
          like this to connect more than two modems to your Linux box, for
          instance in order to become a dial-in server.  If you say Y here,
          you will be asked for your specific card model in the next
-         questions.  Make sure to read <file:Documentation/stallion.txt> in
-         this case.  If you have never heard about all this, it's safe to
+         questions.  Make sure to read <file:Documentation/serial/stallion.txt>
+         in this case.  If you have never heard about all this, it's safe to
          say N.
 
 config STALLION
@@ -354,7 +354,7 @@ config STALLION
        help
          If you have an EasyIO or EasyConnection 8/32 multiport Stallion
          card, then this is for you; say Y.  Make sure to read
-         <file:Documentation/stallion.txt>.
+         <file:Documentation/serial/stallion.txt>.
 
          To compile this driver as a module, choose M here: the
          module will be called stallion.
@@ -365,7 +365,7 @@ config ISTALLION
        help
          If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
          serial multiport card, say Y here. Make sure to read
-         <file:Documentation/stallion.txt>.
+         <file:Documentation/serial/stallion.txt>.
 
          To compile this driver as a module, choose M here: the
          module will be called istallion.
index 242fd46fda22fef8747909efb71f29b8ded4c157..a16b94f12eb23e1fea8b99bfd6621a0b1bc8b7cd 100644 (file)
@@ -72,7 +72,7 @@
 /*
  * There is a bunch of documentation about the card, jumpers, config
  * settings, restrictions, cables, device names and numbers in
- * Documentation/specialix.txt
+ * Documentation/serial/specialix.txt
  */
 
 #include <linux/module.h>
index 752b5c44df9c3ebb10cfc73e6df00b7d1641fb45..c002144c76bc8762636f4fdb7649772d0b3a04cc 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/wait.h>
 #include <linux/poll.h>
 #include <linux/freezer.h>
-#include <linux/version.h>
 #include <linux/uaccess.h>
 #include <acpi/acpi_drivers.h>
 #include <asm/atomic.h>
index 640cbb237328196b1b3b22a91fea4b9ee42bf3b1..3384a717fec0d1d864eff63d8d0c798d7edd47cc 100644 (file)
@@ -318,7 +318,8 @@ static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
                } else
                        data = i2c_op(pd, OP_RX, 0);
 
-               pd->msg->buf[real_pos] = data;
+               if (real_pos >= 0)
+                       pd->msg->buf[real_pos] = data;
        } while (0);
 
        pd->pos++;
index cb199c815b534234bbd115c0ea19df7fea3a48e9..f50210fe558f1cd7ffff023385508be18029d4a1 100644 (file)
@@ -444,6 +444,7 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
        PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
        PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
+       PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506),
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
index 4840733cd9032c48a1253a8fae8ebdea2d4c09cd..3d7f4923cd133a2216115bb18d6fb177eb93ffd1 100644 (file)
@@ -441,13 +441,13 @@ static void process_queued_ios(struct work_struct *work)
                __choose_pgpath(m);
 
        pgpath = m->current_pgpath;
-       m->pgpath_to_activate = m->current_pgpath;
 
        if ((pgpath && !m->queue_io) ||
            (!pgpath && !m->queue_if_no_path))
                must_queue = 0;
 
-       if (m->pg_init_required && !m->pg_init_in_progress) {
+       if (m->pg_init_required && !m->pg_init_in_progress && pgpath) {
+               m->pgpath_to_activate = pgpath;
                m->pg_init_count++;
                m->pg_init_required = 0;
                m->pg_init_in_progress = 1;
@@ -708,6 +708,10 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m)
                m->hw_handler_name = NULL;
                return -EINVAL;
        }
+
+       if (hw_argc > 1)
+               DMWARN("Ignoring user-specified arguments for "
+                      "hardware handler \"%s\"", m->hw_handler_name);
        consume(as, hw_argc - 1);
 
        return 0;
index 9d7b53ed75b228e05bc865571afdd424da92f483..ec43f9fa4b2acaffed0bf45f79edc5a115f36804 100644 (file)
@@ -1032,6 +1032,7 @@ static void mirror_dtr(struct dm_target *ti)
 
        del_timer_sync(&ms->timer);
        flush_workqueue(ms->kmirrord_wq);
+       flush_scheduled_work();
        dm_kcopyd_client_destroy(ms->kcopyd_client);
        destroy_workqueue(ms->kmirrord_wq);
        free_context(ms, ti, ms->nr_mirrors);
index a2d068dbe9e2669dc25290a09e8918b4b5c2f28f..9e4ef88d421e499dfb05e1697593bcbf82fefe38 100644 (file)
@@ -320,8 +320,10 @@ int __init dm_stripe_init(void)
        int r;
 
        r = dm_register_target(&stripe_target);
-       if (r < 0)
+       if (r < 0) {
                DMWARN("target registration failed");
+               return r;
+       }
 
        kstriped = create_singlethread_workqueue("kstriped");
        if (!kstriped) {
index 6963ad1484082bf5d0f8009c60aa1db18eb980c1..c99e4728ff4162ed16c4a7ec99fdc0c27c8cb35f 100644 (file)
@@ -375,7 +375,7 @@ static void start_io_acct(struct dm_io *io)
        dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
 }
 
-static int end_io_acct(struct dm_io *io)
+static void end_io_acct(struct dm_io *io)
 {
        struct mapped_device *md = io->md;
        struct bio *bio = io->bio;
@@ -391,7 +391,9 @@ static int end_io_acct(struct dm_io *io)
        dm_disk(md)->part0.in_flight = pending =
                atomic_dec_return(&md->pending);
 
-       return !pending;
+       /* nudge anyone waiting on suspend queue */
+       if (!pending)
+               wake_up(&md->wait);
 }
 
 /*
@@ -499,9 +501,7 @@ static void dec_pending(struct dm_io *io, int error)
                        spin_unlock_irqrestore(&io->md->pushback_lock, flags);
                }
 
-               if (end_io_acct(io))
-                       /* nudge anyone waiting on suspend queue */
-                       wake_up(&io->md->wait);
+               end_io_acct(io);
 
                if (io->error != DM_ENDIO_REQUEUE) {
                        blk_add_trace_bio(io->md->queue, io->bio,
@@ -937,16 +937,24 @@ static void dm_unplug_all(struct request_queue *q)
 
 static int dm_any_congested(void *congested_data, int bdi_bits)
 {
-       int r;
-       struct mapped_device *md = (struct mapped_device *) congested_data;
-       struct dm_table *map = dm_get_table(md);
+       int r = bdi_bits;
+       struct mapped_device *md = congested_data;
+       struct dm_table *map;
 
-       if (!map || test_bit(DMF_BLOCK_IO, &md->flags))
-               r = bdi_bits;
-       else
-               r = dm_table_any_congested(map, bdi_bits);
+       atomic_inc(&md->pending);
+
+       if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
+               map = dm_get_table(md);
+               if (map) {
+                       r = dm_table_any_congested(map, bdi_bits);
+                       dm_table_put(map);
+               }
+       }
+
+       if (!atomic_dec_return(&md->pending))
+               /* nudge anyone waiting on suspend queue */
+               wake_up(&md->wait);
 
-       dm_table_put(map);
        return r;
 }
 
index b59e47272abfc292493e65bf66a0d2fbdda56f62..3720f0e03a16906efd339b0eefb89b5454499abf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * experimental driver for simple i2c audio chips.
+ * Driver for simple i2c audio chips.
  *
  * Copyright (c) 2000 Gerd Knorr
  * based on code by:
@@ -7,6 +7,10 @@
  *   Steve VanDeBogart (vandebo@uclink.berkeley.edu)
  *   Greg Alexander (galexand@acm.org)
  *
+ * Copyright(c) 2005-2008 Mauro Carvalho Chehab
+ *     - Some cleanups, code fixes, etc
+ *     - Convert it to V4L2 API
+ *
  * This code is placed under the terms of the GNU General Public License
  *
  * OPTIONS:
@@ -30,6 +34,7 @@
 
 #include <media/tvaudio.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv-legacy.h>
 
@@ -58,7 +63,6 @@ typedef int  (*checkit)(struct CHIPSTATE*);
 typedef int  (*initialize)(struct CHIPSTATE*);
 typedef int  (*getmode)(struct CHIPSTATE*);
 typedef void (*setmode)(struct CHIPSTATE*, int mode);
-typedef void (*checkmode)(struct CHIPSTATE*);
 
 /* i2c command */
 typedef struct AUDIOCMD {
@@ -79,6 +83,7 @@ struct CHIPDESC {
 #define CHIP_HAS_VOLUME      1
 #define CHIP_HAS_BASSTREBLE  2
 #define CHIP_HAS_INPUTSEL    4
+#define CHIP_NEED_CHECKMODE  8
 
        /* various i2c command sequences */
        audiocmd   init;
@@ -96,23 +101,20 @@ struct CHIPDESC {
        getmode  getmode;
        setmode  setmode;
 
-       /* check / autoswitch audio after channel switches */
-       checkmode  checkmode;
-
        /* input switch register + values for v4l inputs */
        int  inputreg;
        int  inputmap[4];
        int  inputmute;
        int  inputmask;
 };
-static struct CHIPDESC chiplist[];
 
 /* current state of the chip */
 struct CHIPSTATE {
        struct i2c_client *c;
 
-       /* index into CHIPDESC array */
-       int type;
+       /* chip-specific description - should point to
+          an entry at CHIPDESC table */
+       struct CHIPDESC *desc;
 
        /* shadow register set */
        audiocmd   shadow;
@@ -152,7 +154,7 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
 {
        unsigned char buffer[2];
 
-       if (-1 == subaddr) {
+       if (subaddr < 0) {
                v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n",
                        chip->c->name, val);
                chip->shadow.bytes[1] = val;
@@ -163,6 +165,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
                        return -1;
                }
        } else {
+               if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
+                       v4l_info(chip->c,
+                               "Tried to access a non-existent register: %d\n",
+                               subaddr);
+                       return -EINVAL;
+               }
+
                v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n",
                        chip->c->name, subaddr, val);
                chip->shadow.bytes[subaddr+1] = val;
@@ -177,12 +186,20 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
        return 0;
 }
 
-static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask)
+static int chip_write_masked(struct CHIPSTATE *chip,
+                            int subaddr, int val, int mask)
 {
        if (mask != 0) {
-               if (-1 == subaddr) {
+               if (subaddr < 0) {
                        val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
                } else {
+                       if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
+                               v4l_info(chip->c,
+                                       "Tried to access a non-existent register: %d\n",
+                                       subaddr);
+                               return -EINVAL;
+                       }
+
                        val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
                }
        }
@@ -228,6 +245,15 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
        if (0 == cmd->count)
                return 0;
 
+       if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
+               v4l_info(chip->c,
+                        "Tried to access a non-existent register range: %d to %d\n",
+                        cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1);
+               return -EINVAL;
+       }
+
+       /* FIXME: it seems that the shadow bytes are wrong bellow !*/
+
        /* update our shadow register set; print bytes if (debug > 0) */
        v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:",
                chip->c->name, name,cmd->bytes[0]);
@@ -263,7 +289,8 @@ static void chip_thread_wake(unsigned long data)
 static int chip_thread(void *data)
 {
        struct CHIPSTATE *chip = data;
-       struct CHIPDESC  *desc = chiplist + chip->type;
+       struct CHIPDESC  *desc = chip->desc;
+       int mode;
 
        v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name);
        set_freezable();
@@ -282,7 +309,26 @@ static int chip_thread(void *data)
                        continue;
 
                /* have a look what's going on */
-               desc->checkmode(chip);
+               mode = desc->getmode(chip);
+               if (mode == chip->prevmode)
+                       continue;
+
+               /* chip detected a new audio mode - set it */
+               v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n",
+                       chip->c->name);
+
+               chip->prevmode = mode;
+
+               if (mode & V4L2_TUNER_MODE_STEREO)
+                       desc->setmode(chip, V4L2_TUNER_MODE_STEREO);
+               if (mode & V4L2_TUNER_MODE_LANG1_LANG2)
+                       desc->setmode(chip, V4L2_TUNER_MODE_STEREO);
+               else if (mode & V4L2_TUNER_MODE_LANG1)
+                       desc->setmode(chip, V4L2_TUNER_MODE_LANG1);
+               else if (mode & V4L2_TUNER_MODE_LANG2)
+                       desc->setmode(chip, V4L2_TUNER_MODE_LANG2);
+               else
+                       desc->setmode(chip, V4L2_TUNER_MODE_MONO);
 
                /* schedule next check */
                mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
@@ -292,29 +338,6 @@ static int chip_thread(void *data)
        return 0;
 }
 
-static void generic_checkmode(struct CHIPSTATE *chip)
-{
-       struct CHIPDESC  *desc = chiplist + chip->type;
-       int mode = desc->getmode(chip);
-
-       if (mode == chip->prevmode)
-       return;
-
-       v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", chip->c->name);
-       chip->prevmode = mode;
-
-       if (mode & V4L2_TUNER_MODE_STEREO)
-               desc->setmode(chip,V4L2_TUNER_MODE_STEREO);
-       if (mode & V4L2_TUNER_MODE_LANG1_LANG2)
-               desc->setmode(chip,V4L2_TUNER_MODE_STEREO);
-       else if (mode & V4L2_TUNER_MODE_LANG1)
-               desc->setmode(chip,V4L2_TUNER_MODE_LANG1);
-       else if (mode & V4L2_TUNER_MODE_LANG2)
-               desc->setmode(chip,V4L2_TUNER_MODE_LANG2);
-       else
-               desc->setmode(chip,V4L2_TUNER_MODE_MONO);
-}
-
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tda9840                */
 
@@ -777,7 +800,7 @@ static struct tda9874a_MODES {
        char *name;
        audiocmd cmd;
 } tda9874a_modelist[9] = {
-  {    "A2, B/G",
+  {    "A2, B/G", /* default */
        { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} },
   {    "A2, M (Korea)",
        { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} },
@@ -791,7 +814,7 @@ static struct tda9874a_MODES {
        { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} },
   {    "NICAM, B/G",
        { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} },
-  {    "NICAM, D/K", /* default */
+  {    "NICAM, D/K",
        { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} },
   {    "NICAM, L",
        { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} }
@@ -981,7 +1004,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
 {
        if (tda9874a_SIF > 2)
                tda9874a_SIF = 1;
-       if (tda9874a_STD > 8)
+       if (tda9874a_STD >= ARRAY_SIZE(tda9874a_modelist))
                tda9874a_STD = 0;
        if(tda9874a_AMSEL > 1)
                tda9874a_AMSEL = 0;
@@ -1089,7 +1112,7 @@ static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }
 
 static int tda8425_initialize(struct CHIPSTATE *chip)
 {
-       struct CHIPDESC *desc = chiplist + chip->type;
+       struct CHIPDESC *desc = chip->desc;
        int inputmap[4] = { /* tuner    */ TDA8425_S1_CH2, /* radio  */ TDA8425_S1_CH1,
                            /* extern   */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF};
 
@@ -1259,27 +1282,28 @@ static struct CHIPDESC chiplist[] = {
                .addr_lo    = I2C_ADDR_TDA9840 >> 1,
                .addr_hi    = I2C_ADDR_TDA9840 >> 1,
                .registers  = 5,
+               .flags      = CHIP_NEED_CHECKMODE,
 
+               /* callbacks */
                .checkit    = tda9840_checkit,
                .getmode    = tda9840_getmode,
                .setmode    = tda9840_setmode,
-               .checkmode  = generic_checkmode,
 
                .init       = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
                                /* ,TDA9840_SW, TDA9840_MONO */} }
        },
        {
                .name       = "tda9873h",
-               .checkit    = tda9873_checkit,
                .insmodopt  = &tda9873,
                .addr_lo    = I2C_ADDR_TDA985x_L >> 1,
                .addr_hi    = I2C_ADDR_TDA985x_H >> 1,
                .registers  = 3,
-               .flags      = CHIP_HAS_INPUTSEL,
+               .flags      = CHIP_HAS_INPUTSEL | CHIP_NEED_CHECKMODE,
 
+               /* callbacks */
+               .checkit    = tda9873_checkit,
                .getmode    = tda9873_getmode,
                .setmode    = tda9873_setmode,
-               .checkmode  = generic_checkmode,
 
                .init       = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
                .inputreg   = TDA9873_SW,
@@ -1290,15 +1314,16 @@ static struct CHIPDESC chiplist[] = {
        },
        {
                .name       = "tda9874h/a",
-               .checkit    = tda9874a_checkit,
-               .initialize = tda9874a_initialize,
                .insmodopt  = &tda9874a,
                .addr_lo    = I2C_ADDR_TDA9874 >> 1,
                .addr_hi    = I2C_ADDR_TDA9874 >> 1,
+               .flags      = CHIP_NEED_CHECKMODE,
 
+               /* callbacks */
+               .initialize = tda9874a_initialize,
+               .checkit    = tda9874a_checkit,
                .getmode    = tda9874a_getmode,
                .setmode    = tda9874a_setmode,
-               .checkmode  = generic_checkmode,
        },
        {
                .name       = "tda9850",
@@ -1324,10 +1349,11 @@ static struct CHIPDESC chiplist[] = {
                .rightreg   = TDA9855_VR,
                .bassreg    = TDA9855_BA,
                .treblereg  = TDA9855_TR,
+
+               /* callbacks */
                .volfunc    = tda9855_volume,
                .bassfunc   = tda9855_bass,
                .treblefunc = tda9855_treble,
-
                .getmode    = tda985x_getmode,
                .setmode    = tda985x_setmode,
 
@@ -1348,6 +1374,8 @@ static struct CHIPDESC chiplist[] = {
                .rightreg   = TEA6300_VL,
                .bassreg    = TEA6300_BA,
                .treblereg  = TEA6300_TR,
+
+               /* callbacks */
                .volfunc    = tea6300_shift10,
                .bassfunc   = tea6300_shift12,
                .treblefunc = tea6300_shift12,
@@ -1358,7 +1386,6 @@ static struct CHIPDESC chiplist[] = {
        },
        {
                .name       = "tea6320",
-               .initialize = tea6320_initialize,
                .insmodopt  = &tea6320,
                .addr_lo    = I2C_ADDR_TEA6300 >> 1,
                .addr_hi    = I2C_ADDR_TEA6300 >> 1,
@@ -1369,6 +1396,9 @@ static struct CHIPDESC chiplist[] = {
                .rightreg   = TEA6320_V,
                .bassreg    = TEA6320_BA,
                .treblereg  = TEA6320_TR,
+
+               /* callbacks */
+               .initialize = tea6320_initialize,
                .volfunc    = tea6320_volume,
                .bassfunc   = tea6320_shift11,
                .treblefunc = tea6320_shift11,
@@ -1401,16 +1431,18 @@ static struct CHIPDESC chiplist[] = {
                .rightreg   = TDA8425_VR,
                .bassreg    = TDA8425_BA,
                .treblereg  = TDA8425_TR,
+
+               /* callbacks */
+               .initialize = tda8425_initialize,
                .volfunc    = tda8425_shift10,
                .bassfunc   = tda8425_shift12,
                .treblefunc = tda8425_shift12,
+               .setmode    = tda8425_setmode,
 
                .inputreg   = TDA8425_S1,
                .inputmap   = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 },
                .inputmute  = TDA8425_S1_OFF,
 
-               .setmode    = tda8425_setmode,
-               .initialize = tda8425_initialize,
        },
        {
                .name       = "pic16c54 (PV951)",
@@ -1434,10 +1466,11 @@ static struct CHIPDESC chiplist[] = {
                .addr_lo    = I2C_ADDR_TDA9840 >> 1,
                .addr_hi    = I2C_ADDR_TDA9840 >> 1,
                .registers  = 2,
+               .flags      = CHIP_NEED_CHECKMODE,
 
+               /* callbacks */
                .getmode    = ta8874z_getmode,
                .setmode    = ta8874z_setmode,
-               .checkmode  = generic_checkmode,
 
                .init       = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
        },
@@ -1481,6 +1514,7 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
        }
        if (desc->name == NULL) {
                v4l_dbg(1, debug, client, "no matching chip description found\n");
+               kfree(chip);
                return -EIO;
        }
        v4l_info(client, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
@@ -1494,7 +1528,7 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
        /* fill required data structures */
        if (!id)
                strlcpy(client->name, desc->name, I2C_NAME_SIZE);
-       chip->type = desc-chiplist;
+       chip->desc = desc;
        chip->shadow.count = desc->registers+1;
        chip->prevmode = -1;
        chip->audmode = V4L2_TUNER_MODE_LANG1;
@@ -1506,20 +1540,49 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
                chip_cmd(chip,"init",&desc->init);
 
        if (desc->flags & CHIP_HAS_VOLUME) {
-               chip->left   = desc->leftinit   ? desc->leftinit   : 65535;
-               chip->right  = desc->rightinit  ? desc->rightinit  : 65535;
-               chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
-               chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
+               if (!desc->volfunc) {
+                       /* This shouldn't be happen. Warn user, but keep working
+                          without volume controls
+                        */
+                       v4l_info(chip->c, "volume callback undefined!\n");
+                       desc->flags &= ~CHIP_HAS_VOLUME;
+               } else {
+                       chip->left  = desc->leftinit  ? desc->leftinit  : 65535;
+                       chip->right = desc->rightinit ? desc->rightinit : 65535;
+                       chip_write(chip, desc->leftreg,
+                                  desc->volfunc(chip->left));
+                       chip_write(chip, desc->rightreg,
+                                  desc->volfunc(chip->right));
+               }
        }
        if (desc->flags & CHIP_HAS_BASSTREBLE) {
-               chip->treble = desc->trebleinit ? desc->trebleinit : 32768;
-               chip->bass   = desc->bassinit   ? desc->bassinit   : 32768;
-               chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
-               chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
+               if (!desc->bassfunc || !desc->treblefunc) {
+                       /* This shouldn't be happen. Warn user, but keep working
+                          without bass/treble controls
+                        */
+                       v4l_info(chip->c, "bass/treble callbacks undefined!\n");
+                       desc->flags &= ~CHIP_HAS_BASSTREBLE;
+               } else {
+                       chip->treble = desc->trebleinit ?
+                                               desc->trebleinit : 32768;
+                       chip->bass   = desc->bassinit   ?
+                                               desc->bassinit   : 32768;
+                       chip_write(chip, desc->bassreg,
+                                  desc->bassfunc(chip->bass));
+                       chip_write(chip, desc->treblereg,
+                                  desc->treblefunc(chip->treble));
+               }
        }
 
        chip->thread = NULL;
-       if (desc->checkmode) {
+       if (desc->flags & CHIP_NEED_CHECKMODE) {
+               if (!desc->getmode || !desc->setmode) {
+                       /* This shouldn't be happen. Warn user, but keep working
+                          without kthread
+                        */
+                       v4l_info(chip->c, "set/get mode callbacks undefined!\n");
+                       return 0;
+               }
                /* start async thread */
                init_timer(&chip->wt);
                chip->wt.function = chip_thread_wake;
@@ -1552,7 +1615,7 @@ static int chip_remove(struct i2c_client *client)
 static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
                            struct v4l2_control *ctrl)
 {
-       struct CHIPDESC *desc = chiplist + chip->type;
+       struct CHIPDESC *desc = chip->desc;
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
@@ -1576,13 +1639,13 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
                return 0;
        }
        case V4L2_CID_AUDIO_BASS:
-               if (desc->flags & CHIP_HAS_BASSTREBLE)
+               if (!(desc->flags & CHIP_HAS_BASSTREBLE))
                        break;
                ctrl->value = chip->bass;
                return 0;
        case V4L2_CID_AUDIO_TREBLE:
-               if (desc->flags & CHIP_HAS_BASSTREBLE)
-                       return -EINVAL;
+               if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+                       break;
                ctrl->value = chip->treble;
                return 0;
        }
@@ -1592,7 +1655,7 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
 static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
                            struct v4l2_control *ctrl)
 {
-       struct CHIPDESC *desc = chiplist + chip->type;
+       struct CHIPDESC *desc = chip->desc;
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
@@ -1642,16 +1705,15 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
                return 0;
        }
        case V4L2_CID_AUDIO_BASS:
-               if (desc->flags & CHIP_HAS_BASSTREBLE)
+               if (!(desc->flags & CHIP_HAS_BASSTREBLE))
                        break;
                chip->bass = ctrl->value;
                chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
 
                return 0;
        case V4L2_CID_AUDIO_TREBLE:
-               if (desc->flags & CHIP_HAS_BASSTREBLE)
-                       return -EINVAL;
-
+               if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+                       break;
                chip->treble = ctrl->value;
                chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
 
@@ -1668,9 +1730,12 @@ static int chip_command(struct i2c_client *client,
                        unsigned int cmd, void *arg)
 {
        struct CHIPSTATE *chip = i2c_get_clientdata(client);
-       struct CHIPDESC  *desc = chiplist + chip->type;
+       struct CHIPDESC  *desc = chip->desc;
 
-       v4l_dbg(1, debug, chip->c, "%s: chip_command 0x%x\n", chip->c->name, cmd);
+       if (debug > 0) {
+               v4l_i2c_print_ioctl(chip->c, cmd);
+               printk("\n");
+       }
 
        switch (cmd) {
        case AUDC_SET_RADIO:
@@ -1695,7 +1760,7 @@ static int chip_command(struct i2c_client *client,
                                break;
                        case V4L2_CID_AUDIO_BASS:
                        case V4L2_CID_AUDIO_TREBLE:
-                               if (desc->flags & CHIP_HAS_BASSTREBLE)
+                               if (!(desc->flags & CHIP_HAS_BASSTREBLE))
                                        return -EINVAL;
                                break;
                        default:
@@ -1792,12 +1857,20 @@ static int chip_command(struct i2c_client *client,
                break;
        case VIDIOC_S_FREQUENCY:
                chip->mode = 0; /* automatic */
-               if (desc->checkmode && desc->setmode) {
+
+               /* For chips that provide getmode and setmode, and doesn't
+                  automatically follows the stereo carrier, a kthread is
+                  created to set the audio standard. In this case, when then
+                  the video channel is changed, tvaudio starts on MONO mode.
+                  After waiting for 2 seconds, the kernel thread is called,
+                  to follow whatever audio standard is pointed by the
+                  audio carrier.
+                */
+               if (chip->thread) {
                        desc->setmode(chip,V4L2_TUNER_MODE_MONO);
                        if (chip->prevmode != V4L2_TUNER_MODE_MONO)
                                chip->prevmode = -1; /* reset previous mode */
                        mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
-                       /* the thread will call checkmode() later */
                }
                break;
 
@@ -1836,9 +1909,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
        .legacy_probe = chip_legacy_probe,
        .id_table = chip_id,
 };
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
index 976b35d1d035350beaf8b8d5a36aa30e6a3882e1..0207dd59090d195b4d0d21027e511cf484e14121 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/idr.h>
+#include <linux/sched.h>
 
 #include <linux/c2port.h>
 
index e5059aa3c724b189613db3ab6a61255a91d2f3be..8d92d8db9a98c0a3c5625ce74fd27a4268070ba4 100644 (file)
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 
-
+/* dynamic ioremap() areas */
+#define FLASH_START      0x00000000
+#define FLASH_SIZE       0x800000
+#define FLASH_WIDTH      4
+
+#define SRAM_START       0x60000000
+#define SRAM_SIZE        0xc000
+#define SRAM_WIDTH       4
+
+#define BOOTROM_START    0x70000000
+#define BOOTROM_SIZE     0x80
+#define BOOTROM_WIDTH    4
 
 
 static struct mtd_info *flash_mtd;
index 35fef655ccc4c8e5cbfe55eae84f6aead0456b32..3b959fad1c4ec082bfd7310f789e673de214ac47 100644 (file)
@@ -24,8 +24,8 @@ static struct mtd_info *mymtd;
 static struct map_info h720x_map = {
        .name =         "H720X",
        .bankwidth =    4,
-       .size =         FLASH_SIZE,
-       .phys =         FLASH_PHYS,
+       .size =         H720X_FLASH_SIZE,
+       .phys =         H720X_FLASH_PHYS,
 };
 
 static struct mtd_partition h720x_partitions[] = {
@@ -70,7 +70,7 @@ int __init h720x_mtd_init(void)
 
        char    *part_type = NULL;
 
-       h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE);
+       h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size);
 
        if (!h720x_map.virt) {
                printk(KERN_ERR "H720x-MTD: ioremap failed\n");
index 37ecf845edfe9b91c5a6aee4ef514ad713e541ea..e12cdb4543b406f543e6e363dd43dcef20918db7 100644 (file)
@@ -1444,6 +1444,10 @@ static const struct usb_device_id        products [] = {
        // Apple USB Ethernet Adapter
        USB_DEVICE(0x05ac, 0x1402),
        .driver_info = (unsigned long) &ax88772_info,
+}, {
+       // Cables-to-Go USB Ethernet Adapter
+       USB_DEVICE(0x0b95, 0x772a),
+       .driver_info = (unsigned long) &ax88772_info,
 },
        { },            // END
 };
index b3a63edb69012bd443f4caebffdaddf12103b86a..ae5ec76dca77a636bf5b1f1a6cf4c52b03b8d9c8 100644 (file)
@@ -63,7 +63,7 @@ static acpi_status acpi_run_osc(acpi_handle handle,
        union acpi_object in_params[4];
        struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
        union acpi_object *out_obj;
-       u32 osc_dw0, flags = osc_args->capbuf[OSC_QUERY_TYPE];
+       u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE];
 
        /* Setting up input parameters */
        input.count = 4;
@@ -92,15 +92,16 @@ static acpi_status acpi_run_osc(acpi_handle handle,
                status = AE_TYPE;
                goto out_kfree;
        }
-       osc_dw0 = *((u32 *)out_obj->buffer.pointer);
-       if (osc_dw0) {
-               if (osc_dw0 & OSC_REQUEST_ERROR)
+       /* Need to ignore the bit0 in result code */
+       errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+       if (errors) {
+               if (errors & OSC_REQUEST_ERROR)
                        printk(KERN_DEBUG "_OSC request fails\n"); 
-               if (osc_dw0 & OSC_INVALID_UUID_ERROR)
+               if (errors & OSC_INVALID_UUID_ERROR)
                        printk(KERN_DEBUG "_OSC invalid UUID\n"); 
-               if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
+               if (errors & OSC_INVALID_REVISION_ERROR)
                        printk(KERN_DEBUG "_OSC invalid revision\n"); 
-               if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
+               if (errors & OSC_CAPABILITIES_MASK_ERROR) {
                        if (flags & OSC_QUERY_ENABLE)
                                goto out_success;
                        printk(KERN_DEBUG "_OSC FW not grant req. control\n");
index dcce9f5d84654a0612f99ed9bbe85813d53966f5..4a110b7b2673911885741209b3891c5eab891fab 100644 (file)
@@ -351,10 +351,11 @@ int verify_cis_cache(struct pcmcia_socket *s)
        char *buf;
 
        buf = kmalloc(256, GFP_KERNEL);
-       if (buf == NULL)
+       if (buf == NULL) {
                dev_printk(KERN_WARNING, &s->dev,
                           "no memory for verifying CIS\n");
                return -ENOMEM;
+       }
        list_for_each_entry(cis, &s->cis_cache, node) {
                int len = cis->len;
 
index c68c5d3382859eb4af84f8d9e0278ee3ce00b8ea..0660ad18258953af06dfa7cc72afda3b9259f716 100644 (file)
@@ -186,12 +186,6 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
 
        spin_lock_init(&socket->lock);
 
-       if (socket->resource_ops->init) {
-               ret = socket->resource_ops->init(socket);
-               if (ret)
-                       return (ret);
-       }
-
        /* try to obtain a socket number [yes, it gets ugly if we
         * register more than 2^sizeof(unsigned int) pcmcia
         * sockets... but the socket number is deprecated
@@ -226,7 +220,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
        /* set proper values in socket->dev */
        dev_set_drvdata(&socket->dev, socket);
        socket->dev.class = &pcmcia_socket_class;
-       snprintf(socket->dev.bus_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
+       dev_set_name(&socket->dev, "pcmcia_socket%u", socket->sock);
 
        /* base address = 0, map = 0 */
        socket->cis_mem.flags = 0;
@@ -239,6 +233,12 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
        mutex_init(&socket->skt_mutex);
        spin_lock_init(&socket->thread_lock);
 
+       if (socket->resource_ops->init) {
+               ret = socket->resource_ops->init(socket);
+               if (ret)
+                       goto err;
+       }
+
        tsk = kthread_run(pccardd, socket, "pccardd");
        if (IS_ERR(tsk)) {
                ret = PTR_ERR(tsk);
index 7956602554901297f86055cea142707f7eead769..47cab31ff6e49c0780692ead159cf81fb4113c58 100644 (file)
@@ -622,7 +622,6 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
 {
        struct pcmcia_device *p_dev, *tmp_dev;
        unsigned long flags;
-       int bus_id_len;
 
        s = pcmcia_get_socket(s);
        if (!s)
@@ -650,12 +649,12 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
        /* by default don't allow DMA */
        p_dev->dma_mask = DMA_MASK_NONE;
        p_dev->dev.dma_mask = &p_dev->dma_mask;
-       bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
-
-       p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL);
+       dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no);
+       if (!dev_name(&p_dev->dev))
+               goto err_free;
+       p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
        if (!p_dev->devname)
                goto err_free;
-       sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
        ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
 
        spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -668,6 +667,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
         list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
                 if (p_dev->func == tmp_dev->func) {
                        p_dev->function_config = tmp_dev->function_config;
+                       p_dev->io = tmp_dev->io;
+                       p_dev->irq = tmp_dev->irq;
                        kref_get(&p_dev->function_config->ref);
                }
 
index 76d4a98f09559b9a78d3f4335a1961b9de11eb6e..f5d0ba8e22d5473fb46e00bfbe5e3bfe2e7719a9 100644 (file)
@@ -302,9 +302,10 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
        /* We only allow changing Vpp1 and Vpp2 to the same value */
        if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
            (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
-               if (mod->Vpp1 != mod->Vpp2)
+               if (mod->Vpp1 != mod->Vpp2) {
                        ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
                        return -EINVAL;
+               }
                s->socket.Vpp = mod->Vpp1;
                if (s->ops->set_socket(s, &s->socket)) {
                        dev_printk(KERN_WARNING, &s->dev,
index 17f4ecf1c0c5b214af03b7188ecedca3e516d8b5..9ca22c7aafb29f5959bbcb3ddb2ed0296408b6c4 100644 (file)
@@ -71,7 +71,7 @@ static DEFINE_MUTEX(rsrc_mutex);
 ======================================================================*/
 
 static struct resource *
-make_resource(resource_size_t b, resource_size_t n, int flags, char *name)
+make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
 {
        struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
@@ -624,7 +624,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
                   unsigned long align, struct pcmcia_socket *s)
 {
-       struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.bus_id);
+       struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev));
        struct socket_data *s_data = s->resource_data;
        struct pcmcia_align_data data;
        unsigned long min = base;
@@ -658,7 +658,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
 static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
                u_long align, int low, struct pcmcia_socket *s)
 {
-       struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.bus_id);
+       struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
        struct socket_data *s_data = s->resource_data;
        struct pcmcia_align_data data;
        unsigned long min, max;
index 4b76fca64a6f1bf5538c8babc8595b15a234aa8e..363bd1303d217aa4904ea088549e8f0bb9f23618 100644 (file)
@@ -1746,6 +1746,11 @@ restart:
                        goto restart;
                }
 
+               /* log sense for fatal error */
+               if (cqr->status == DASD_CQR_FAILED) {
+                       dasd_log_sense(cqr, &cqr->irb);
+               }
+
                /* First of all call extended error reporting. */
                if (dasd_eer_enabled(base) &&
                    cqr->status == DASD_CQR_FAILED) {
index eb5f1b8bc57fd0546c94067a5b57364f3db1addf..ec9c0bcf66eeefd8ee9029675cc193d0af328b0f 100644 (file)
@@ -324,6 +324,9 @@ static int do_assign_storage(sclp_cmdw_t cmd, u16 rn)
        case 0x0120:
                break;
        default:
+               pr_warning("assign storage failed (cmd=0x%08x, "
+                          "response=0x%04x, rn=0x%04x)\n", cmd,
+                          sccb->header.response_code, rn);
                rc = -EIO;
                break;
        }
index 4e78c82194b47520c271be8617ac5202644d395c..4e4008325e281edc58f11b3a211506b3f8bac35a 100644 (file)
@@ -874,11 +874,15 @@ void ccw_device_move_to_orphanage(struct work_struct *work)
        replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev);
        if (replacing_cdev) {
                sch_attach_disconnected_device(sch, replacing_cdev);
+               /* Release reference from get_disc_ccwdev_by_dev_id() */
+               put_device(&cdev->dev);
                return;
        }
        replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id);
        if (replacing_cdev) {
                sch_attach_orphaned_device(sch, replacing_cdev);
+               /* Release reference from get_orphaned_ccwdev_by_dev_id() */
+               put_device(&cdev->dev);
                return;
        }
        sch_create_and_recog_new_device(sch);
index ff4a6931bb8e680b4f429577fc81e481df4cd786..3d442444c618ccb431d7e4d6b6e1b5bc4f16924b 100644 (file)
@@ -322,13 +322,13 @@ static int __init kvm_devices_init(void)
                return rc;
        }
 
-       rc = vmem_add_mapping(PFN_PHYS(max_pfn), PAGE_SIZE);
+       rc = vmem_add_mapping(real_memory_size, PAGE_SIZE);
        if (rc) {
                s390_root_dev_unregister(kvm_root);
                return rc;
        }
 
-       kvm_devices = (void *) PFN_PHYS(max_pfn);
+       kvm_devices = (void *) real_memory_size;
 
        ctl_set_bit(0, 9);
        register_external_interrupt(0x2603, kvm_extint_handler);
index 3b56220fb900291df60b56284191b6e66119a02d..3d4e3e3f3fc07c873846d75b56d6e338c54475ce 100644 (file)
@@ -610,7 +610,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
        atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
        atomic_set(&port->refcount, 0);
 
-       dev_set_name(&port->sysfs_device, "0x%016llx", wwpn);
+       dev_set_name(&port->sysfs_device, "0x%016llx",
+                    (unsigned long long)wwpn);
        port->sysfs_device.parent = &adapter->ccw_device->dev;
 
        port->sysfs_device.release = zfcp_sysfs_port_release;
index b04038c74786b32456ded58505b96efd7f4c1756..951a8d409d1d5faa787a058d3f3542f13c9852c6 100644 (file)
@@ -116,7 +116,9 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
        zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85,
                                NULL);
        zfcp_erp_wait(adapter);
-       goto out;
+       up(&zfcp_data.config_sema);
+       flush_work(&adapter->scan_work);
+       return 0;
 
  out_scsi_register:
        zfcp_erp_thread_kill(adapter);
index 060f5f2352ecb590b74e8667bb703fb1c0e62bc1..31012d58cfb760fb457862bfd596da12f8532310 100644 (file)
@@ -30,7 +30,7 @@ static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
                dump->offset = offset;
                dump->size = min(from_len - offset, room);
                memcpy(dump->data, from + offset, dump->size);
-               debug_event(dbf, level, dump, dump->size);
+               debug_event(dbf, level, dump, dump->size + sizeof(*dump));
        }
 }
 
@@ -108,7 +108,7 @@ static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
                             t.tv_sec, t.tv_nsec);
                zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
        } else  {
-               zfcp_dbf_outd(&p, NULL, dump->data, dump->size, dump->offset,
+               zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset,
                              dump->total_size);
                if ((dump->offset + dump->size) == dump->total_size)
                        p += sprintf(p, "\n");
@@ -366,6 +366,7 @@ static void zfcp_hba_dbf_view_response(char **p,
                        break;
                zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
                zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
+               p += sprintf(*p, "\n");
                break;
 
        case FSF_QTCB_OPEN_PORT_WITH_DID:
@@ -465,7 +466,8 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
        else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
                zfcp_hba_dbf_view_berr(&p, &r->u.berr);
 
-       p += sprintf(p, "\n");
+       if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0)
+               p += sprintf(p, "\n");
        return p - out_buf;
 }
 
@@ -880,6 +882,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
        struct ct_hdr *hdr = sg_virt(ct->req);
        struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
        struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
+       int level = 3;
        unsigned long flags;
 
        spin_lock_irqsave(&adapter->san_dbf_lock, flags);
@@ -896,9 +899,10 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
        oct->options = hdr->options;
        oct->max_res_size = hdr->max_res_size;
        oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
-                      ZFCP_DBF_CT_PAYLOAD);
-       memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len);
-       debug_event(adapter->san_dbf, 3, r, sizeof(*r));
+                      ZFCP_DBF_SAN_MAX_PAYLOAD);
+       debug_event(adapter->san_dbf, level, r, sizeof(*r));
+       zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
+                        (void *)hdr + sizeof(struct ct_hdr), oct->len);
        spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 }
 
@@ -914,6 +918,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
        struct ct_hdr *hdr = sg_virt(ct->resp);
        struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
        struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
+       int level = 3;
        unsigned long flags;
 
        spin_lock_irqsave(&adapter->san_dbf_lock, flags);
@@ -929,9 +934,10 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
        rct->expl = hdr->reason_code_expl;
        rct->vendor_unique = hdr->vendor_unique;
        rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
-                      ZFCP_DBF_CT_PAYLOAD);
-       memcpy(rct->payload, (void *)hdr + sizeof(struct ct_hdr), rct->len);
-       debug_event(adapter->san_dbf, 3, r, sizeof(*r));
+                      ZFCP_DBF_SAN_MAX_PAYLOAD);
+       debug_event(adapter->san_dbf, level, r, sizeof(*r));
+       zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
+                        (void *)hdr + sizeof(struct ct_hdr), rct->len);
        spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 }
 
@@ -954,7 +960,7 @@ static void zfcp_san_dbf_event_els(const char *tag, int level,
        rec->u.els.ls_code = ls_code;
        debug_event(adapter->san_dbf, level, rec, sizeof(*rec));
        zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level,
-                        buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD));
+                        buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
        spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 }
 
@@ -1008,8 +1014,6 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
                                    char *out_buf, const char *in_buf)
 {
        struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf;
-       char *buffer = NULL;
-       int buflen = 0, total = 0;
        char *p = out_buf;
 
        if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
@@ -1029,9 +1033,6 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
                zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype);
                zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
                zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
-               total = ct->len;
-               buffer = ct->payload;
-               buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
        } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
                struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp;
                zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
@@ -1039,23 +1040,12 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
                zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
                zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
                zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
-               total = ct->len;
-               buffer = ct->payload;
-               buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
        } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
                   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
                   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
                struct zfcp_san_dbf_record_els *els = &r->u.els;
                zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
-               total = els->len;
-               buffer = els->payload;
-               buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
        }
-
-       zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total);
-       if (buflen == total)
-               p += sprintf(p, "\n");
-
        return p - out_buf;
 }
 
index e8f450801fea7f1cd351b7dad1049d02f82ab238..5d6b2dff855bb44e46d7fa6c65f93791b0bf1dfa 100644 (file)
@@ -163,8 +163,6 @@ struct zfcp_san_dbf_record_ct_request {
        u8 options;
        u16 max_res_size;
        u32 len;
-#define ZFCP_DBF_CT_PAYLOAD    24
-       u8 payload[ZFCP_DBF_CT_PAYLOAD];
 } __attribute__ ((packed));
 
 struct zfcp_san_dbf_record_ct_response {
@@ -174,15 +172,11 @@ struct zfcp_san_dbf_record_ct_response {
        u8 expl;
        u8 vendor_unique;
        u32 len;
-       u8 payload[ZFCP_DBF_CT_PAYLOAD];
 } __attribute__ ((packed));
 
 struct zfcp_san_dbf_record_els {
        u8 ls_code;
        u32 len;
-#define ZFCP_DBF_ELS_PAYLOAD   32
-#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
-       u8 payload[ZFCP_DBF_ELS_PAYLOAD];
 } __attribute__ ((packed));
 
 struct zfcp_san_dbf_record {
@@ -196,6 +190,8 @@ struct zfcp_san_dbf_record {
                struct zfcp_san_dbf_record_ct_response ct_resp;
                struct zfcp_san_dbf_record_els els;
        } u;
+#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
+       u8 payload[32];
 } __attribute__ ((packed));
 
 struct zfcp_scsi_dbf_record {
index 9040f738ff333f47fd243486c311380f0ea00ebe..35364f64da7ff27ce7c740f3bde2a121df3d8556 100644 (file)
@@ -472,6 +472,7 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
                                   ZFCP_STATUS_ERP_TIMEDOUT)) {
                        act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
                        zfcp_rec_dbf_event_action(142, act);
+                       act->fsf_req->erp_action = NULL;
                }
                if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
                        zfcp_rec_dbf_event_action(143, act);
index 5ae1d497e5ed21f9061d36331a5a75ee63934b76..d024442ee128d9ee04ec44c5fe6b43e9ec099959 100644 (file)
@@ -683,6 +683,7 @@ static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool)
        if (!req)
                return NULL;
        memset(req, 0, sizeof(*req));
+       req->pool = pool;
        return req;
 }
 
@@ -769,28 +770,24 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
 static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
 {
        struct zfcp_adapter *adapter = req->adapter;
-       struct zfcp_qdio_queue *req_q = &adapter->req_q;
+       unsigned long flags;
        int idx;
 
        /* put allocated FSF request into hash table */
-       spin_lock(&adapter->req_list_lock);
+       spin_lock_irqsave(&adapter->req_list_lock, flags);
        idx = zfcp_reqlist_hash(req->req_id);
        list_add_tail(&req->list, &adapter->req_list[idx]);
-       spin_unlock(&adapter->req_list_lock);
+       spin_unlock_irqrestore(&adapter->req_list_lock, flags);
 
-       req->qdio_outb_usage = atomic_read(&req_q->count);
+       req->qdio_outb_usage = atomic_read(&adapter->req_q.count);
        req->issued = get_clock();
        if (zfcp_qdio_send(req)) {
-               /* Queues are down..... */
                del_timer(&req->timer);
-               spin_lock(&adapter->req_list_lock);
-               zfcp_reqlist_remove(adapter, req);
-               spin_unlock(&adapter->req_list_lock);
-               /* undo changes in request queue made for this request */
-               atomic_add(req->sbal_number, &req_q->count);
-               req_q->first -= req->sbal_number;
-               req_q->first += QDIO_MAX_BUFFERS_PER_Q;
-               req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
+               spin_lock_irqsave(&adapter->req_list_lock, flags);
+               /* lookup request again, list might have changed */
+               if (zfcp_reqlist_find_safe(adapter, req))
+                       zfcp_reqlist_remove(adapter, req);
+               spin_unlock_irqrestore(&adapter->req_list_lock, flags);
                zfcp_erp_adapter_reopen(adapter, 0, 116, req);
                return -EIO;
        }
index ca8f85f3dad439f515e25b8e5b049a0edd3701ee..e46fd3e9f68fb85ff3dc9899e454772b5bb33a39 100644 (file)
@@ -24,14 +24,10 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
 static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
 {
        struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
-       WARN_ON(!unit);
-       if (unit) {
-               atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
-               sdpnt->hostdata = NULL;
-               unit->device = NULL;
-               zfcp_erp_unit_failed(unit, 12, NULL);
-               zfcp_unit_put(unit);
-       }
+       atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
+       unit->device = NULL;
+       zfcp_erp_unit_failed(unit, 12, NULL);
+       zfcp_unit_put(unit);
 }
 
 static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
index 8aba4fdfb5222b40d93a8e231fd1b69858ddecdc..6194ed5d02c4e694bc2bfbe3faf9a56860a2ade5 100644 (file)
@@ -2445,7 +2445,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
        hba_status = detailed_status >> 8;
 
        // calculate resid for sg 
-       scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
+       scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+20));
 
        pHba = (adpt_hba*) cmd->device->host->hostdata[0];
 
@@ -2456,7 +2456,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
                case I2O_SCSI_DSC_SUCCESS:
                        cmd->result = (DID_OK << 16);
                        // handle underflow
-                       if(readl(reply+5) < cmd->underflow ) {
+                       if (readl(reply+20) < cmd->underflow) {
                                cmd->result = (DID_ERROR <<16);
                                printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
                        }
index 28c9da7d4a5c5f0aad97c0a41f964c8994c4d228..7dc62deb4087cead7dfeed562cc3e9bc4a5c9011 100644 (file)
@@ -4402,6 +4402,10 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
        scb_t   *scb;
        int     rval;
 
+       scmd = scsi_allocate_command(GFP_KERNEL);
+       if (!scmd)
+               return -ENOMEM;
+
        /*
         * The internal commands share one command id and hence are
         * serialized. This is so because we want to reserve maximum number of
@@ -4412,12 +4416,11 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
        scb = &adapter->int_scb;
        memset(scb, 0, sizeof(scb_t));
 
-       scmd = &adapter->int_scmd;
-       memset(scmd, 0, sizeof(Scsi_Cmnd));
-
        sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
        scmd->device = sdev;
 
+       memset(adapter->int_cdb, 0, sizeof(adapter->int_cdb));
+       scmd->cmnd = adapter->int_cdb;
        scmd->device->host = adapter->host;
        scmd->host_scribble = (void *)scb;
        scmd->cmnd[0] = MEGA_INTERNAL_CMD;
@@ -4456,6 +4459,8 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
 
        mutex_unlock(&adapter->int_mtx);
 
+       scsi_free_command(GFP_KERNEL, scmd);
+
        return rval;
 }
 
index ee70bd4ae4badc0f2f7a82eb0a523d5702c796f4..795201fa0b487d1a23113f38534666d90d23ec49 100644 (file)
@@ -888,8 +888,8 @@ typedef struct {
 
        u8      sglen;  /* f/w supported scatter-gather list length */
 
+       unsigned char int_cdb[MAX_COMMAND_SIZE];
        scb_t                   int_scb;
-       Scsi_Cmnd               int_scmd;
        struct mutex            int_mtx;        /* To synchronize the internal
                                                commands */
        struct completion       int_waitq;      /* wait queue for internal
index f25f41a499e5ed7be7ebd3dc109d4d4b14c9494a..b97194096d8e6a285f55389360bf92691c6cf471 100644 (file)
@@ -2547,7 +2547,6 @@ typedef struct scsi_qla_host {
        uint8_t         fcode_revision[16];
        uint32_t        fw_revision[4];
 
-       uint16_t        fdt_odd_index;
        uint32_t        fdt_wrt_disable;
        uint32_t        fdt_erase_cmd;
        uint32_t        fdt_block_size;
index a470f2d3270d205ad35ee26519a25e9d37f90252..4218f20f5ed5256b35a61862a73424e7c581d712 100644 (file)
@@ -140,7 +140,6 @@ int
 qla2100_pci_config(scsi_qla_host_t *ha)
 {
        uint16_t w;
-       uint32_t d;
        unsigned long flags;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
@@ -151,10 +150,7 @@ qla2100_pci_config(scsi_qla_host_t *ha)
        w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
        pci_write_config_word(ha->pdev, PCI_COMMAND, w);
 
-       /* Reset expansion ROM address decode enable */
-       pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
-       d &= ~PCI_ROM_ADDRESS_ENABLE;
-       pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
+       pci_disable_rom(ha->pdev);
 
        /* Get PCI bus information. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -174,7 +170,6 @@ int
 qla2300_pci_config(scsi_qla_host_t *ha)
 {
        uint16_t        w;
-       uint32_t        d;
        unsigned long   flags = 0;
        uint32_t        cnt;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
@@ -236,10 +231,7 @@ qla2300_pci_config(scsi_qla_host_t *ha)
 
        pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
 
-       /* Reset expansion ROM address decode enable */
-       pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
-       d &= ~PCI_ROM_ADDRESS_ENABLE;
-       pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
+       pci_disable_rom(ha->pdev);
 
        /* Get PCI bus information. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -259,7 +251,6 @@ int
 qla24xx_pci_config(scsi_qla_host_t *ha)
 {
        uint16_t w;
-       uint32_t d;
        unsigned long flags = 0;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
@@ -281,10 +272,7 @@ qla24xx_pci_config(scsi_qla_host_t *ha)
        if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP))
                pcie_set_readrq(ha->pdev, 2048);
 
-       /* Reset expansion ROM address decode enable */
-       pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
-       d &= ~PCI_ROM_ADDRESS_ENABLE;
-       pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
+       pci_disable_rom(ha->pdev);
 
        ha->chip_revision = ha->pdev->revision;
 
@@ -306,7 +294,6 @@ int
 qla25xx_pci_config(scsi_qla_host_t *ha)
 {
        uint16_t w;
-       uint32_t d;
 
        pci_set_master(ha->pdev);
        pci_try_set_mwi(ha->pdev);
@@ -320,10 +307,7 @@ qla25xx_pci_config(scsi_qla_host_t *ha)
        if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP))
                pcie_set_readrq(ha->pdev, 2048);
 
-       /* Reset expansion ROM address decode enable */
-       pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
-       d &= ~PCI_ROM_ADDRESS_ENABLE;
-       pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
+       pci_disable_rom(ha->pdev);
 
        ha->chip_revision = ha->pdev->revision;
 
@@ -980,7 +964,6 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
                                    &ha->fw_minor_version,
                                    &ha->fw_subminor_version,
                                    &ha->fw_attributes, &ha->fw_memory_size);
-                               qla2x00_resize_request_q(ha);
                                ha->flags.npiv_supported = 0;
                                if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) ||
                                     IS_QLA84XX(ha)) &&
@@ -992,6 +975,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
                                                ha->max_npiv_vports =
                                                    MIN_MULTI_ID_FABRIC - 1;
                                }
+                               qla2x00_resize_request_q(ha);
 
                                if (ql2xallocfwdump)
                                        qla2x00_alloc_fw_dump(ha);
index 36bc6851e23dd2b13cfbbe98a6a14eac5faf0c07..3402746ec128a54115ac1880acbba27b7da6541f 100644 (file)
@@ -1964,7 +1964,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
                        *cur_iocb_cnt = mcp->mb[7];
                if (orig_iocb_cnt)
                        *orig_iocb_cnt = mcp->mb[10];
-               if (max_npiv_vports)
+               if (ha->flags.npiv_supported && max_npiv_vports)
                        *max_npiv_vports = mcp->mb[11];
        }
 
index 21dd182ad512214c7646299a1af4ad4f2e9d9e88..35567203ef611bc730df2fde134c036b6e124107 100644 (file)
@@ -728,6 +728,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
                if (ha->isp_ops->abort_command(ha, sp)) {
                        DEBUG2(printk("%s(%ld): abort_command "
                            "mbx failed.\n", __func__, ha->host_no));
+                       ret = FAILED;
                } else {
                        DEBUG3(printk("%s(%ld): abort_command "
                            "mbx success.\n", __func__, ha->host_no));
index 90a13211717f7d367a89c3b7f0b74fc5dd0f113c..e4af678eb2d62ca071f6d04a2461074d611d089a 100644 (file)
@@ -722,6 +722,7 @@ done:
 static void
 qla2xxx_get_fdt_info(scsi_qla_host_t *ha)
 {
+#define FLASH_BLK_SIZE_4K      0x1000
 #define FLASH_BLK_SIZE_32K     0x8000
 #define FLASH_BLK_SIZE_64K     0x10000
        const char *loc, *locations[] = { "MID", "FDT" };
@@ -755,7 +756,6 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *ha)
        loc = locations[1];
        mid = le16_to_cpu(fdt->man_id);
        fid = le16_to_cpu(fdt->id);
-       ha->fdt_odd_index = mid == 0x1f;
        ha->fdt_wrt_disable = fdt->wrt_disable_bits;
        ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
        ha->fdt_block_size = le32_to_cpu(fdt->block_size);
@@ -788,8 +788,7 @@ no_flash_data:
                ha->fdt_block_size = FLASH_BLK_SIZE_64K;
                break;
        case 0x1f: /* Atmel 26DF081A. */
-               ha->fdt_odd_index = 1;
-               ha->fdt_block_size = FLASH_BLK_SIZE_64K;
+               ha->fdt_block_size = FLASH_BLK_SIZE_4K;
                ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320);
                ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339);
                ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336);
@@ -801,9 +800,9 @@ no_flash_data:
        }
 done:
        DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x "
-           "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
+           "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
            ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
-           ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
+           ha->fdt_unprotect_sec_cmd, ha->fdt_wrt_disable,
            ha->fdt_block_size));
 }
 
@@ -987,13 +986,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
        qla24xx_unprotect_flash(ha);
 
        for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
-               if (ha->fdt_odd_index) {
-                       findex = faddr << 2;
-                       fdata = findex & sec_mask;
-               } else {
-                       findex = faddr;
-                       fdata = (findex & sec_mask) << 2;
-               }
+
+               findex = faddr;
+               fdata = (findex & sec_mask) << 2;
 
                /* Are we at the beginning of a sector? */
                if ((findex & rest_addr) == 0) {
index be5e299df528e22eed62f8ac25d03c01a11630d7..eea6720adf1693c8521851f57e8b15bb1b87880b 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.02.01-k8"
+#define QLA2XXX_VERSION      "8.02.01-k9"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   2
index 94ed262bdf0c7731040c0112d955ded856fe96e4..386361778ebb32d859c6770971329f46d55ae23e 100644 (file)
@@ -1340,9 +1340,10 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
                 * LLD/transport was disrupted during processing of the IO.
                 * The transport class is now blocked/blocking,
                 * and the transport will decide what to do with the IO
-                * based on its timers and recovery capablilities.
+                * based on its timers and recovery capablilities if
+                * there are enough retries.
                 */
-               return ADD_TO_MLQUEUE;
+               goto maybe_retry;
        case DID_TRANSPORT_FAILFAST:
                /*
                 * The transport decided to failfast the IO (most likely
index 5c0f32c7fbf6b20c8e20fba1ec32f7e08af29909..165fc010978c2624a7a45730f403b505ed48e726 100644 (file)
@@ -144,9 +144,9 @@ static void put_char(struct uart_port *port, char c)
                status = sci_in(port, SCxSR);
        } while (!(status & SCxSR_TDxE(port)));
 
-       sci_out(port, SCxTDR, c);
        sci_in(port, SCxSR);            /* Dummy read */
        sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+       sci_out(port, SCxTDR, c);
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
@@ -478,10 +478,10 @@ static void sci_transmit_chars(struct uart_port *port)
                return;
        }
 
-       if (port->type == PORT_SCIF)
-               count = scif_txroom(port);
-       else
+       if (port->type == PORT_SCI)
                count = sci_txroom(port);
+       else
+               count = scif_txroom(port);
 
        do {
                unsigned char c;
@@ -510,7 +510,7 @@ static void sci_transmit_chars(struct uart_port *port)
        } else {
                ctrl = sci_in(port, SCSCR);
 
-               if (port->type == PORT_SCIF) {
+               if (port->type != PORT_SCI) {
                        sci_in(port, SCxSR); /* Dummy read */
                        sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
                }
@@ -536,10 +536,10 @@ static inline void sci_receive_chars(struct uart_port *port)
                return;
 
        while (1) {
-               if (port->type == PORT_SCIF)
-                       count = scif_rxroom(port);
-               else
+               if (port->type == PORT_SCI)
                        count = sci_rxroom(port);
+               else
+                       count = scif_rxroom(port);
 
                /* Don't copy more bytes than there is room for in the buffer */
                count = tty_buffer_request_room(tty, count);
@@ -714,7 +714,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
 
 #if defined(SCIF_ORER)
        /* XXX: Handle SCIF overrun error */
-       if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
+       if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
                sci_out(port, SCLSR, 0);
                if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) {
                        copied++;
@@ -1042,7 +1042,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
        sci_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
 
-       if (port->type == PORT_SCIF)
+       if (port->type != PORT_SCI)
                sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
 
        smr_val = sci_in(port, SCSMR) & 3;
@@ -1085,6 +1085,7 @@ static const char *sci_type(struct uart_port *port)
                case PORT_SCI:  return "sci";
                case PORT_SCIF: return "scif";
                case PORT_IRDA: return "irda";
+               case PORT_SCIFA:        return "scifa";
        }
 
        return NULL;
@@ -1112,6 +1113,7 @@ static void sci_config_port(struct uart_port *port, int flags)
                s->init_pins = sci_init_pins_sci;
                break;
        case PORT_SCIF:
+       case PORT_SCIFA:
                s->init_pins = sci_init_pins_scif;
                break;
        case PORT_IRDA:
index 6163a45f968f4b9aef1b79056f02e2329232e231..9f33b064172e86607e607ae69afbfaf595c21da9 100644 (file)
 #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
   static inline unsigned int sci_##name##_in(struct uart_port *port)   \
   {                                                                    \
-    if (port->type == PORT_SCI) {                                      \
-      SCI_IN(sci_size, sci_offset)                                     \
-    } else {                                                           \
-      SCI_IN(scif_size, scif_offset);                                  \
+    if (port->type == PORT_SCIF) {                                     \
+      SCI_IN(scif_size, scif_offset)                                   \
+    } else {   /* PORT_SCI or PORT_SCIFA */                            \
+      SCI_IN(sci_size, sci_offset);                                    \
     }                                                                  \
   }                                                                    \
   static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
   {                                                                    \
-    if (port->type == PORT_SCI) {                                      \
-      SCI_OUT(sci_size, sci_offset, value)                             \
-    } else {                                                           \
-      SCI_OUT(scif_size, scif_offset, value);                          \
+    if (port->type == PORT_SCIF) {                                     \
+      SCI_OUT(scif_size, scif_offset, value)                           \
+    } else {   /* PORT_SCI or PORT_SCIFA */                            \
+      SCI_OUT(sci_size, sci_offset, value);                            \
     }                                                                  \
   }
 
index 20104443081ad1fc260d4ba74f17a0c9828eca69..d50a99f70aee8d33941e5445f62bef41778093d3 100644 (file)
@@ -158,16 +158,12 @@ static int acm_wb_is_avail(struct acm *acm)
 }
 
 /*
- * Finish write.
+ * Finish write. Caller must hold acm->write_lock
  */
 static void acm_write_done(struct acm *acm, struct acm_wb *wb)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&acm->write_lock, flags);
        wb->use = 0;
        acm->transmitting--;
-       spin_unlock_irqrestore(&acm->write_lock, flags);
 }
 
 /*
@@ -482,6 +478,7 @@ static void acm_write_bulk(struct urb *urb)
 {
        struct acm_wb *wb = urb->context;
        struct acm *acm = wb->instance;
+       unsigned long flags;
 
        if (verbose || urb->status
                        || (urb->actual_length != urb->transfer_buffer_length))
@@ -490,7 +487,9 @@ static void acm_write_bulk(struct urb *urb)
                        urb->transfer_buffer_length,
                        urb->status);
 
+       spin_lock_irqsave(&acm->write_lock, flags);
        acm_write_done(acm, wb);
+       spin_unlock_irqrestore(&acm->write_lock, flags);
        if (ACM_READY(acm))
                schedule_work(&acm->work);
        else
index 887738577b2838df3e02f93c05a9fe32a48b0606..6d1048faf08e1679597af0fadd6a5849d3afd299 100644 (file)
@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                                continue;
                        dev_dbg(&dev->dev, "unregistering interface %s\n",
                                dev_name(&interface->dev));
+                       interface->unregistering = 1;
                        usb_remove_sysfs_intf_files(interface);
                        device_del(&interface->dev);
                }
index f66fba11fbd53f2eeaf5a5ebc17a9d8251c526db..4fb65fdc9dc36bb51eb25059789886fbd1dfe857 100644 (file)
@@ -840,7 +840,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
        struct usb_host_interface *alt = intf->cur_altsetting;
        int retval;
 
-       if (intf->sysfs_files_created)
+       if (intf->sysfs_files_created || intf->unregistering)
                return 0;
 
        /* The interface string may be present in some altsettings
index 4342bd9c3bb610d9582217aae0bc524378a28a7f..1f68af9db3f7d6bed13bcab914eb238b638b5bee 100644 (file)
@@ -85,8 +85,8 @@ EXPORT_SYMBOL_GPL(usb_alloc_urb);
  * Must be called when a user of a urb is finished with it.  When the last user
  * of the urb calls this function, the memory of the urb is freed.
  *
- * Note: The transfer buffer associated with the urb is not freed, that must be
- * done elsewhere.
+ * Note: The transfer buffer associated with the urb is not freed unless the
+ * URB_FREE_BUFFER transfer flag is set.
  */
 void usb_free_urb(struct urb *urb)
 {
index 5ee1590b8e9cf2739e629804193aa8fa053954cf..c1d34df0b157c45f533b03b794bd14a929055f70 100644 (file)
@@ -463,7 +463,11 @@ static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
        notify->wLength = cpu_to_le16(length);
        memcpy(buf, data, length);
 
+       /* ep_queue() can complete immediately if it fills the fifo... */
+       spin_unlock(&acm->lock);
        status = usb_ep_queue(ep, req, GFP_ATOMIC);
+       spin_lock(&acm->lock);
+
        if (status < 0) {
                ERROR(acm->port.func.config->cdev,
                                "acm ttyGS%d can't notify serial state, %d\n",
index 56f592dc0b3626139f4e9b34dd191af967f30bf0..f3a75a929e0aa26dcdbaee0c75c0cfa10403f8bf 100644 (file)
@@ -110,29 +110,18 @@ config USB_ISP116X_HCD
 
 config USB_ISP1760_HCD
        tristate "ISP 1760 HCD support"
-       depends on USB && EXPERIMENTAL
+       depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
        ---help---
          The ISP1760 chip is a USB 2.0 host controller.
 
          This driver does not support isochronous transfers or OTG.
+         This USB controller is usually attached to a non-DMA-Master
+         capable bus. NXP's eval kit brings this chip on PCI card
+         where the chip itself is behind a PLB to simulate such
+         a bus.
 
          To compile this driver as a module, choose M here: the
-         module will be called isp1760-hcd.
-
-config USB_ISP1760_PCI
-       bool "Support for the PCI bus"
-       depends on USB_ISP1760_HCD && PCI
-       ---help---
-         Enables support for the device present on the PCI bus.
-         This should only be required if you happen to have the eval kit from
-         NXP and you are going to test it.
-
-config USB_ISP1760_OF
-       bool "Support for the OF platform bus"
-       depends on USB_ISP1760_HCD && PPC_OF
-       ---help---
-         Enables support for the device present on the PowerPC
-         OpenFirmware platform bus.
+         module will be called isp1760.
 
 config USB_OHCI_HCD
        tristate "OHCI HCD support"
index 15a803b206b8ea72c4774ba6edb504a0fd5e964c..4725d15d096f559fc833d0e0f6323bcff4aa7631 100644 (file)
@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd)
 static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
-       u32                     status, pcd_status = 0, cmd;
+       u32                     status, masked_status, pcd_status = 0, cmd;
        int                     bh;
 
        spin_lock (&ehci->lock);
@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                goto dead;
        }
 
-       status &= INTR_MASK;
-       if (!status) {                  /* irq sharing? */
+       masked_status = status & INTR_MASK;
+       if (!masked_status) {           /* irq sharing? */
                spin_unlock(&ehci->lock);
                return IRQ_NONE;
        }
 
        /* clear (just) interrupts */
-       ehci_writel(ehci, status, &ehci->regs->status);
+       ehci_writel(ehci, masked_status, &ehci->regs->status);
        cmd = ehci_readl(ehci, &ehci->regs->command);
        bh = 0;
 
@@ -734,18 +734,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
        /* PCI errors [4.15.2.4] */
        if (unlikely ((status & STS_FATAL) != 0)) {
+               ehci_err(ehci, "fatal error\n");
                dbg_cmd(ehci, "fatal", cmd);
                dbg_status(ehci, "fatal", status);
-               if (status & STS_HALT) {
-                       ehci_err (ehci, "fatal error\n");
+               ehci_halt(ehci);
 dead:
-                       ehci_reset (ehci);
-                       ehci_writel(ehci, 0, &ehci->regs->configured_flag);
-                       /* generic layer kills/unlinks all urbs, then
-                        * uses ehci_stop to clean up the rest
-                        */
-                       bh = 1;
-               }
+               ehci_reset(ehci);
+               ehci_writel(ehci, 0, &ehci->regs->configured_flag);
+               /* generic layer kills/unlinks all urbs, then
+                * uses ehci_stop to clean up the rest
+                */
+               bh = 1;
        }
 
        if (bh)
index 0eba894bcb017aa0706f5e60224149e76338d99a..9c9da35abc6c010c6929a1e515fc4179ef898111 100644 (file)
@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
 
        tmp = hcd->irq;
 
+       ehci_shutdown(hcd);
        usb_remove_hcd(hcd);
 
        ps3_system_bus_set_driver_data(dev, NULL);
index 4a0c5a78b2ed74358055e800d5181b1a1e2cb1c7..a081ee65bde6d933f3f2000c67028d461ece27c7 100644 (file)
@@ -918,7 +918,7 @@ iso_stream_init (
                 */
                stream->usecs = HS_USECS_ISO (maxp);
                bandwidth = stream->usecs * 8;
-               bandwidth /= 1 << (interval - 1);
+               bandwidth /= interval;
 
        } else {
                u32             addr;
@@ -951,7 +951,7 @@ iso_stream_init (
                } else
                        stream->raw_mask = smask_out [hs_transfers - 1];
                bandwidth = stream->usecs + stream->c_usecs;
-               bandwidth /= 1 << (interval + 2);
+               bandwidth /= interval << 3;
 
                /* stream->splits gets created from raw_mask later */
                stream->address = cpu_to_hc32(ehci, addr);
index af849f596135324bf727ac667f7f2d4cbc7d9920..b87ca7cf4b378f4ee0c6ee7ed403e629d79a38ea 100644 (file)
 #include "../core/hcd.h"
 #include "isp1760-hcd.h"
 
-#ifdef CONFIG_USB_ISP1760_OF
+#ifdef CONFIG_PPC_OF
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #endif
 
-#ifdef CONFIG_USB_ISP1760_PCI
+#ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif
 
-#ifdef CONFIG_USB_ISP1760_OF
+#ifdef CONFIG_PPC_OF
 static int of_isp1760_probe(struct of_device *dev,
                const struct of_device_id *match)
 {
@@ -128,7 +128,7 @@ static struct of_platform_driver isp1760_of_driver = {
 };
 #endif
 
-#ifdef CONFIG_USB_ISP1760_PCI
+#ifdef CONFIG_PCI
 static u32 nxp_pci_io_base;
 static u32 iolength;
 static u32 pci_mem_phy0;
@@ -288,28 +288,28 @@ static struct pci_driver isp1761_pci_driver = {
 
 static int __init isp1760_init(void)
 {
-       int ret = -ENODEV;
+       int ret;
 
        init_kmem_once();
 
-#ifdef CONFIG_USB_ISP1760_OF
+#ifdef CONFIG_PPC_OF
        ret = of_register_platform_driver(&isp1760_of_driver);
        if (ret) {
                deinit_kmem_cache();
                return ret;
        }
 #endif
-#ifdef CONFIG_USB_ISP1760_PCI
+#ifdef CONFIG_PCI
        ret = pci_register_driver(&isp1761_pci_driver);
        if (ret)
                goto unreg_of;
 #endif
        return ret;
 
-#ifdef CONFIG_USB_ISP1760_PCI
+#ifdef CONFIG_PCI
 unreg_of:
 #endif
-#ifdef CONFIG_USB_ISP1760_OF
+#ifdef CONFIG_PPC_OF
        of_unregister_platform_driver(&isp1760_of_driver);
 #endif
        deinit_kmem_cache();
@@ -319,10 +319,10 @@ module_init(isp1760_init);
 
 static void __exit isp1760_exit(void)
 {
-#ifdef CONFIG_USB_ISP1760_OF
+#ifdef CONFIG_PPC_OF
        of_unregister_platform_driver(&isp1760_of_driver);
 #endif
-#ifdef CONFIG_USB_ISP1760_PCI
+#ifdef CONFIG_PCI
        pci_unregister_driver(&isp1761_pci_driver);
 #endif
        deinit_kmem_cache();
index 2089d8a46c4bbedb0cd140dc5db4d0cee4cab908..3c1a3b5f89f19fb19dde0962b8b4e6a2e704b9e4 100644 (file)
@@ -192,7 +192,7 @@ fail_start:
        return result;
 }
 
-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
+static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
 {
        unsigned int tmp;
        struct usb_hcd *hcd =
@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
 
        tmp = hcd->irq;
 
+       ohci_shutdown(hcd);
        usb_remove_hcd(hcd);
 
        ps3_system_bus_set_driver_data(dev, NULL);
index c18d8790c4107c032eb0e34b94be345683828d8d..2376f24f3c83dc964f03286a66a88ab195434179 100644 (file)
@@ -1763,11 +1763,12 @@ static void r8a66597_timer(unsigned long _r8a66597)
 {
        struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
        unsigned long flags;
+       int port;
 
        spin_lock_irqsave(&r8a66597->lock, flags);
 
-       r8a66597_root_hub_control(r8a66597, 0);
-       r8a66597_root_hub_control(r8a66597, 1);
+       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+               r8a66597_root_hub_control(r8a66597, port);
 
        spin_unlock_irqrestore(&r8a66597->lock, flags);
 }
index 69c34a58e2054a7c49d225164a3f1a7ead20cf5a..b4ec716de7dadc12b766e445822edbc4f35f537a 100644 (file)
@@ -3270,6 +3270,7 @@ static struct usb_device_id sisusb_table [] = {
        { USB_DEVICE(0x0711, 0x0900) },
        { USB_DEVICE(0x0711, 0x0901) },
        { USB_DEVICE(0x0711, 0x0902) },
+       { USB_DEVICE(0x0711, 0x0903) },
        { USB_DEVICE(0x0711, 0x0918) },
        { USB_DEVICE(0x182d, 0x021c) },
        { USB_DEVICE(0x182d, 0x0269) },
index 8648470c81caa3a4e516445255a00b9101373c25..63dff9ba73c5d074bcd87ba13fcd4188dce81960 100644 (file)
@@ -620,7 +620,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                __func__);
                        retval = -EFAULT;
                } else {
-                       dev_dbg(&dev->dev, "%s: recv %d bytes from pipe %d\n",
+                       dev_dbg(&dev->dev, "%s: recv %zd bytes from pipe %d\n",
                                __func__, usb_data.count, usb_data.pipe);
                }
 
index 4a35745b30be6992ff775cfd118c02750a2eef52..5280dba9b1fb7e0a94f6dc1b379b28fc5c7d831b 100644 (file)
 
 
 
-unsigned debug;
-module_param(debug, uint, S_IRUGO | S_IWUSR);
+unsigned musb_debug;
+module_param(musb_debug, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
 
 #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
@@ -2248,7 +2248,7 @@ static int __init musb_init(void)
                "host"
 #endif
                ", debug=%d\n",
-               musb_driver_name, debug);
+               musb_driver_name, musb_debug);
        return platform_driver_probe(&musb_driver, musb_probe);
 }
 
index 4d2794441b153ac6c2f745b99f06c245cb56bbe5..9fc1db44c72c13844e73148112bbe8055c65ef3f 100644 (file)
                                __func__, __LINE__ , ## args); \
        } } while (0)
 
-extern unsigned debug;
+extern unsigned musb_debug;
 
 static inline int _dbg_level(unsigned l)
 {
-       return debug >= l;
+       return musb_debug >= l;
 }
 
 #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)
index 3133990f04ec868fcb0809cd233535f3fc562ff2..e45e70bcc5e2ea1c79610ad7f754a8029e922ccd 100644 (file)
@@ -378,6 +378,19 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
 
                switch (qh->type) {
 
+               case USB_ENDPOINT_XFER_CONTROL:
+               case USB_ENDPOINT_XFER_BULK:
+                       /* fifo policy for these lists, except that NAKing
+                        * should rotate a qh to the end (for fairness).
+                        */
+                       if (qh->mux == 1) {
+                               head = qh->ring.prev;
+                               list_del(&qh->ring);
+                               kfree(qh);
+                               qh = first_qh(head);
+                               break;
+                       }
+
                case USB_ENDPOINT_XFER_ISOC:
                case USB_ENDPOINT_XFER_INT:
                        /* this is where periodic bandwidth should be
@@ -388,17 +401,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
                        kfree(qh);
                        qh = NULL;
                        break;
-
-               case USB_ENDPOINT_XFER_CONTROL:
-               case USB_ENDPOINT_XFER_BULK:
-                       /* fifo policy for these lists, except that NAKing
-                        * should rotate a qh to the end (for fairness).
-                        */
-                       head = qh->ring.prev;
-                       list_del(&qh->ring);
-                       kfree(qh);
-                       qh = first_qh(head);
-                       break;
                }
        }
        return qh;
@@ -1507,10 +1509,29 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                musb_writew(hw_ep->regs, MUSB_RXCSR, val);
 
 #ifdef CONFIG_USB_INVENTRA_DMA
+               if (usb_pipeisoc(pipe)) {
+                       struct usb_iso_packet_descriptor *d;
+
+                       d = urb->iso_frame_desc + qh->iso_idx;
+                       d->actual_length = xfer_len;
+
+                       /* even if there was an error, we did the dma
+                        * for iso_frame_desc->length
+                        */
+                       if (d->status != EILSEQ && d->status != -EOVERFLOW)
+                               d->status = 0;
+
+                       if (++qh->iso_idx >= urb->number_of_packets)
+                               done = true;
+                       else
+                               done = false;
+
+               } else  {
                /* done if urb buffer is full or short packet is recd */
                done = (urb->actual_length + xfer_len >=
                                urb->transfer_buffer_length
                        || dma->actual_len < qh->maxpacket);
+               }
 
                /* send IN token for next packet, without AUTOREQ */
                if (!done) {
@@ -1547,7 +1568,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                if (dma) {
                        struct dma_controller   *c;
                        u16                     rx_count;
-                       int                     ret;
+                       int                     ret, length;
+                       dma_addr_t              buf;
 
                        rx_count = musb_readw(epio, MUSB_RXCOUNT);
 
@@ -1560,6 +1582,35 @@ void musb_host_rx(struct musb *musb, u8 epnum)
 
                        c = musb->dma_controller;
 
+                       if (usb_pipeisoc(pipe)) {
+                               int status = 0;
+                               struct usb_iso_packet_descriptor *d;
+
+                               d = urb->iso_frame_desc + qh->iso_idx;
+
+                               if (iso_err) {
+                                       status = -EILSEQ;
+                                       urb->error_count++;
+                               }
+                               if (rx_count > d->length) {
+                                       if (status == 0) {
+                                               status = -EOVERFLOW;
+                                               urb->error_count++;
+                                       }
+                                       DBG(2, "** OVERFLOW %d into %d\n",\
+                                           rx_count, d->length);
+
+                                       length = d->length;
+                               } else
+                                       length = rx_count;
+                               d->status = status;
+                               buf = urb->transfer_dma + d->offset;
+                       } else {
+                               length = rx_count;
+                               buf = urb->transfer_dma +
+                                               urb->actual_length;
+                       }
+
                        dma->desired_mode = 0;
 #ifdef USE_MODE1
                        /* because of the issue below, mode 1 will
@@ -1571,6 +1622,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                                                urb->actual_length)
                                        > qh->maxpacket)
                                dma->desired_mode = 1;
+                       if (rx_count < hw_ep->max_packet_sz_rx) {
+                               length = rx_count;
+                               dma->bDesiredMode = 0;
+                       } else {
+                               length = urb->transfer_buffer_length;
+                       }
 #endif
 
 /* Disadvantage of using mode 1:
@@ -1608,12 +1665,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                         */
                        ret = c->channel_program(
                                dma, qh->maxpacket,
-                               dma->desired_mode,
-                               urb->transfer_dma
-                                       + urb->actual_length,
-                               (dma->desired_mode == 0)
-                                       ? rx_count
-                                       : urb->transfer_buffer_length);
+                               dma->desired_mode, buf, length);
 
                        if (!ret) {
                                c->channel_release(dma);
@@ -1631,19 +1683,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                }
        }
 
-       if (dma && usb_pipeisoc(pipe)) {
-               struct usb_iso_packet_descriptor        *d;
-               int                                     iso_stat = status;
-
-               d = urb->iso_frame_desc + qh->iso_idx;
-               d->actual_length += xfer_len;
-               if (iso_err) {
-                       iso_stat = -EILSEQ;
-                       urb->error_count++;
-               }
-               d->status = iso_stat;
-       }
-
 finish:
        urb->actual_length += xfer_len;
        qh->offset += xfer_len;
@@ -1671,22 +1710,9 @@ static int musb_schedule(
        struct list_head        *head = NULL;
 
        /* use fixed hardware for control and bulk */
-       switch (qh->type) {
-       case USB_ENDPOINT_XFER_CONTROL:
+       if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
                head = &musb->control;
                hw_ep = musb->control_ep;
-               break;
-       case USB_ENDPOINT_XFER_BULK:
-               hw_ep = musb->bulk_ep;
-               if (is_in)
-                       head = &musb->in_bulk;
-               else
-                       head = &musb->out_bulk;
-               break;
-       }
-       if (head) {
-               idle = list_empty(head);
-               list_add_tail(&qh->ring, head);
                goto success;
        }
 
@@ -1725,19 +1751,34 @@ static int musb_schedule(
                else
                        diff = hw_ep->max_packet_sz_tx - qh->maxpacket;
 
-               if (diff > 0 && best_diff > diff) {
+               if (diff >= 0 && best_diff > diff) {
                        best_diff = diff;
                        best_end = epnum;
                }
        }
-       if (best_end < 0)
+       /* use bulk reserved ep1 if no other ep is free */
+       if (best_end > 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
+               hw_ep = musb->bulk_ep;
+               if (is_in)
+                       head = &musb->in_bulk;
+               else
+                       head = &musb->out_bulk;
+               goto success;
+       } else if (best_end < 0) {
                return -ENOSPC;
+       }
 
        idle = 1;
+       qh->mux = 0;
        hw_ep = musb->endpoints + best_end;
        musb->periodic[best_end] = qh;
        DBG(4, "qh %p periodic slot %d\n", qh, best_end);
 success:
+       if (head) {
+               idle = list_empty(head);
+               list_add_tail(&qh->ring, head);
+               qh->mux = 1;
+       }
        qh->hw_ep = hw_ep;
        qh->hep->hcpriv = qh;
        if (idle)
@@ -2015,11 +2056,13 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                        sched = &musb->control;
                        break;
                case USB_ENDPOINT_XFER_BULK:
-                       if (usb_pipein(urb->pipe))
-                               sched = &musb->in_bulk;
-                       else
-                               sched = &musb->out_bulk;
-                       break;
+                       if (qh->mux == 1) {
+                               if (usb_pipein(urb->pipe))
+                                       sched = &musb->in_bulk;
+                               else
+                                       sched = &musb->out_bulk;
+                               break;
+                       }
                default:
                        /* REVISIT when we get a schedule tree, periodic
                         * transfers won't always be at the head of a
@@ -2067,11 +2110,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
                sched = &musb->control;
                break;
        case USB_ENDPOINT_XFER_BULK:
-               if (is_in)
-                       sched = &musb->in_bulk;
-               else
-                       sched = &musb->out_bulk;
-               break;
+               if (qh->mux == 1) {
+                       if (is_in)
+                               sched = &musb->in_bulk;
+                       else
+                               sched = &musb->out_bulk;
+                       break;
+               }
        default:
                /* REVISIT when we get a schedule tree, periodic transfers
                 * won't always be at the head of a singleton queue...
index 77bcdb9d5b32d93c1fd77433bce4821d9ab9c4bd..0b7fbcd21963ebcc23435d168a061bed741ff612 100644 (file)
@@ -53,6 +53,7 @@ struct musb_qh {
 
        struct list_head        ring;           /* of musb_qh */
        /* struct musb_qh               *next; */       /* for periodic tree */
+       u8                      mux;            /* qh multiplexed to hw_ep */
 
        unsigned                offset;         /* in urb->transfer_buffer */
        unsigned                segsize;        /* current xfer fragment */
index 9d2dcb121c5e95cc7e6ba81a5cdfa59ae07637ae..ce6c162920f7bfcb5bef980b2438aeba4661d12b 100644 (file)
@@ -53,7 +53,9 @@ static void musb_do_idle(unsigned long _musb)
 {
        struct musb     *musb = (void *)_musb;
        unsigned long   flags;
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
        u8      power;
+#endif
        u8      devctl;
 
        devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
index b73b036f3d7770c01822e0885635a5fa3879aeae..ee8fca92a4ac4cd0ec58b157941bf8017ecff331 100644 (file)
@@ -605,7 +605,7 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 
        if (musb->board_mode != MUSB_OTG) {
                ERR("Changing mode currently only supported in OTG mode\n");
-               return;
+               return -EINVAL;
        }
 
        otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
index 8008d0bc80ad3732a05b4fa82b04b06f3fb334fc..9035d7256b03570a63203994d0fc031ea59e0a22 100644 (file)
@@ -67,6 +67,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
        { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
        { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
+       { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
        { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
        { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
        { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
@@ -85,6 +86,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
        { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
        { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
+       { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
index bd07eaa300b967f792ffd2923af3385b8784cf3b..6fa1ec441b618d12575adf9bec5ee67a327fde6f 100644 (file)
@@ -160,6 +160,11 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 
 #define NOVATELWIRELESS_VENDOR_ID              0x1410
 
+/* YISO PRODUCTS */
+
+#define YISO_VENDOR_ID                         0x0EAB
+#define YISO_PRODUCT_U893                      0xC893
+
 /* MERLIN EVDO PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_V640           0x1100
 #define NOVATELWIRELESS_PRODUCT_V620           0x1110
@@ -408,6 +413,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) },
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
+       { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) },
index 3d9249632ae12e7051174817241ef37ea6f2cd4c..c68b738900bdbb9b6c8f6c95d536a69d7cada937 100644 (file)
@@ -2,8 +2,8 @@
 # USB Storage driver configuration
 #
 
-comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'"
-comment "may also be needed; see USB_STORAGE Help for more information"
+comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;"
+comment "see USB_STORAGE Help for more information"
        depends on USB
 
 config USB_STORAGE
index fb9e20e624c1477f909c6ec4825dc7e6d22ebe50..d4e5fc86e43c679eee20ee64e5334cfd2eceda66 100644 (file)
@@ -253,6 +253,14 @@ UNUSUAL_DEV(  0x0421, 0x006a, 0x0000, 0x0591,
        US_SC_DEVICE, US_PR_DEVICE, NULL,
        US_FL_FIX_CAPACITY ),
 
+/* Submitted by Ricky Wong Yung Fei <evilbladewarrior@gmail.com> */
+/* Nokia 7610 Supernova - Too many sectors reported in usb storage mode */
+UNUSUAL_DEV(  0x0421, 0x00f5, 0x0000, 0x0470,
+       "Nokia",
+       "7610 Supernova",
+       US_SC_DEVICE, US_PR_DEVICE, NULL,
+       US_FL_FIX_CAPACITY ),
+
 /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
@@ -418,6 +426,13 @@ UNUSUAL_DEV(  0x04b0, 0x0417, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY),
 
+/* Reported by paul ready <lxtwin@homecall.co.uk> */
+UNUSUAL_DEV(  0x04b0, 0x0419, 0x0100, 0x0200,
+               "NIKON",
+               "NIKON DSC D300",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY),
+
 /* Reported by Doug Maxey (dwm@austin.ibm.com) */
 UNUSUAL_DEV(  0x04b3, 0x4001, 0x0110, 0x0110,
                "IBM",
@@ -1258,6 +1273,13 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY),
 
+/* Reported by Luciano Rocha <luciano@eurotux.com> */
+UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001,
+               "Argosy",
+               "Storage",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY),
+
 /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
  * Flag will support Bulk devices which use a standards-violating 32-byte
  * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
index d910501de6d2ca9d4fc8ed1a1cda8d9a1aca1519..8d86b7960f0df7527fed5494230676b137b4f63b 100644 (file)
@@ -812,7 +812,7 @@ int dlm_release_lockspace(void *lockspace, int force)
        error = release_lockspace(ls, force);
        if (!error)
                ls_count--;
-       else if (!ls_count)
+       if (!ls_count)
                threads_stop();
        mutex_unlock(&ls_lock);
 
index 690e72595e6e6048addba645cf179cb418208f50..7bbed1b89825f8b37f4fa753201290d0002bf618 100644 (file)
@@ -106,6 +106,20 @@ void get_inotify_watch(struct inotify_watch *watch)
 }
 EXPORT_SYMBOL_GPL(get_inotify_watch);
 
+int pin_inotify_watch(struct inotify_watch *watch)
+{
+       struct super_block *sb = watch->inode->i_sb;
+       spin_lock(&sb_lock);
+       if (sb->s_count >= S_BIAS) {
+               atomic_inc(&sb->s_active);
+               spin_unlock(&sb_lock);
+               atomic_inc(&watch->count);
+               return 1;
+       }
+       spin_unlock(&sb_lock);
+       return 0;
+}
+
 /**
  * put_inotify_watch - decrements the ref count on a given watch.  cleans up
  * watch references if the count reaches zero.  inotify_watch is freed by
@@ -124,6 +138,13 @@ void put_inotify_watch(struct inotify_watch *watch)
 }
 EXPORT_SYMBOL_GPL(put_inotify_watch);
 
+void unpin_inotify_watch(struct inotify_watch *watch)
+{
+       struct super_block *sb = watch->inode->i_sb;
+       put_inotify_watch(watch);
+       deactivate_super(sb);
+}
+
 /*
  * inotify_handle_get_wd - returns the next WD for use by the given handle
  *
@@ -479,6 +500,112 @@ void inotify_init_watch(struct inotify_watch *watch)
 }
 EXPORT_SYMBOL_GPL(inotify_init_watch);
 
+/*
+ * Watch removals suck violently.  To kick the watch out we need (in this
+ * order) inode->inotify_mutex and ih->mutex.  That's fine if we have
+ * a hold on inode; however, for all other cases we need to make damn sure
+ * we don't race with umount.  We can *NOT* just grab a reference to a
+ * watch - inotify_unmount_inodes() will happily sail past it and we'll end
+ * with reference to inode potentially outliving its superblock.  Ideally
+ * we just want to grab an active reference to superblock if we can; that
+ * will make sure we won't go into inotify_umount_inodes() until we are
+ * done.  Cleanup is just deactivate_super().  However, that leaves a messy
+ * case - what if we *are* racing with umount() and active references to
+ * superblock can't be acquired anymore?  We can bump ->s_count, grab
+ * ->s_umount, which will almost certainly wait until the superblock is shut
+ * down and the watch in question is pining for fjords.  That's fine, but
+ * there is a problem - we might have hit the window between ->s_active
+ * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock
+ * is past the point of no return and is heading for shutdown) and the
+ * moment when deactivate_super() acquires ->s_umount.  We could just do
+ * drop_super() yield() and retry, but that's rather antisocial and this
+ * stuff is luser-triggerable.  OTOH, having grabbed ->s_umount and having
+ * found that we'd got there first (i.e. that ->s_root is non-NULL) we know
+ * that we won't race with inotify_umount_inodes().  So we could grab a
+ * reference to watch and do the rest as above, just with drop_super() instead
+ * of deactivate_super(), right?  Wrong.  We had to drop ih->mutex before we
+ * could grab ->s_umount.  So the watch could've been gone already.
+ *
+ * That still can be dealt with - we need to save watch->wd, do idr_find()
+ * and compare its result with our pointer.  If they match, we either have
+ * the damn thing still alive or we'd lost not one but two races at once,
+ * the watch had been killed and a new one got created with the same ->wd
+ * at the same address.  That couldn't have happened in inotify_destroy(),
+ * but inotify_rm_wd() could run into that.  Still, "new one got created"
+ * is not a problem - we have every right to kill it or leave it alone,
+ * whatever's more convenient.
+ *
+ * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as
+ * "grab it and kill it" check.  If it's been our original watch, we are
+ * fine, if it's a newcomer - nevermind, just pretend that we'd won the
+ * race and kill the fscker anyway; we are safe since we know that its
+ * superblock won't be going away.
+ *
+ * And yes, this is far beyond mere "not very pretty"; so's the entire
+ * concept of inotify to start with.
+ */
+
+/**
+ * pin_to_kill - pin the watch down for removal
+ * @ih: inotify handle
+ * @watch: watch to kill
+ *
+ * Called with ih->mutex held, drops it.  Possible return values:
+ * 0 - nothing to do, it has died
+ * 1 - remove it, drop the reference and deactivate_super()
+ * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid
+ * that variant, since it involved a lot of PITA, but that's the best that
+ * could've been done.
+ */
+static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch)
+{
+       struct super_block *sb = watch->inode->i_sb;
+       s32 wd = watch->wd;
+
+       spin_lock(&sb_lock);
+       if (sb->s_count >= S_BIAS) {
+               atomic_inc(&sb->s_active);
+               spin_unlock(&sb_lock);
+               get_inotify_watch(watch);
+               mutex_unlock(&ih->mutex);
+               return 1;       /* the best outcome */
+       }
+       sb->s_count++;
+       spin_unlock(&sb_lock);
+       mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */
+       down_read(&sb->s_umount);
+       if (likely(!sb->s_root)) {
+               /* fs is already shut down; the watch is dead */
+               drop_super(sb);
+               return 0;
+       }
+       /* raced with the final deactivate_super() */
+       mutex_lock(&ih->mutex);
+       if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) {
+               /* the watch is dead */
+               mutex_unlock(&ih->mutex);
+               drop_super(sb);
+               return 0;
+       }
+       /* still alive or freed and reused with the same sb and wd; kill */
+       get_inotify_watch(watch);
+       mutex_unlock(&ih->mutex);
+       return 2;
+}
+
+static void unpin_and_kill(struct inotify_watch *watch, int how)
+{
+       struct super_block *sb = watch->inode->i_sb;
+       put_inotify_watch(watch);
+       switch (how) {
+       case 1:
+               deactivate_super(sb);
+               break;
+       case 2:
+               drop_super(sb);
+       }
+}
+
 /**
  * inotify_destroy - clean up and destroy an inotify instance
  * @ih: inotify handle
@@ -490,11 +617,15 @@ void inotify_destroy(struct inotify_handle *ih)
         * pretty.  We cannot do a simple iteration over the list, because we
         * do not know the inode until we iterate to the watch.  But we need to
         * hold inode->inotify_mutex before ih->mutex.  The following works.
+        *
+        * AV: it had to become even uglier to start working ;-/
         */
        while (1) {
                struct inotify_watch *watch;
                struct list_head *watches;
+               struct super_block *sb;
                struct inode *inode;
+               int how;
 
                mutex_lock(&ih->mutex);
                watches = &ih->watches;
@@ -503,8 +634,10 @@ void inotify_destroy(struct inotify_handle *ih)
                        break;
                }
                watch = list_first_entry(watches, struct inotify_watch, h_list);
-               get_inotify_watch(watch);
-               mutex_unlock(&ih->mutex);
+               sb = watch->inode->i_sb;
+               how = pin_to_kill(ih, watch);
+               if (!how)
+                       continue;
 
                inode = watch->inode;
                mutex_lock(&inode->inotify_mutex);
@@ -518,7 +651,7 @@ void inotify_destroy(struct inotify_handle *ih)
 
                mutex_unlock(&ih->mutex);
                mutex_unlock(&inode->inotify_mutex);
-               put_inotify_watch(watch);
+               unpin_and_kill(watch, how);
        }
 
        /* free this handle: the put matching the get in inotify_init() */
@@ -719,7 +852,9 @@ void inotify_evict_watch(struct inotify_watch *watch)
 int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
 {
        struct inotify_watch *watch;
+       struct super_block *sb;
        struct inode *inode;
+       int how;
 
        mutex_lock(&ih->mutex);
        watch = idr_find(&ih->idr, wd);
@@ -727,9 +862,12 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
                mutex_unlock(&ih->mutex);
                return -EINVAL;
        }
-       get_inotify_watch(watch);
+       sb = watch->inode->i_sb;
+       how = pin_to_kill(ih, watch);
+       if (!how)
+               return 0;
+
        inode = watch->inode;
-       mutex_unlock(&ih->mutex);
 
        mutex_lock(&inode->inotify_mutex);
        mutex_lock(&ih->mutex);
@@ -740,7 +878,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
 
        mutex_unlock(&ih->mutex);
        mutex_unlock(&inode->inotify_mutex);
-       put_inotify_watch(watch);
+       unpin_and_kill(watch, how);
 
        return 0;
 }
index bd578578a8b98408844e272fc65dc9f694692d0f..37ea2894b3c0ff870a79f014fb370894b3709e44 100644 (file)
@@ -134,6 +134,8 @@ extern void inotify_remove_watch_locked(struct inotify_handle *,
                                        struct inotify_watch *);
 extern void get_inotify_watch(struct inotify_watch *);
 extern void put_inotify_watch(struct inotify_watch *);
+extern int pin_inotify_watch(struct inotify_watch *);
+extern void unpin_inotify_watch(struct inotify_watch *);
 
 #else
 
@@ -228,6 +230,15 @@ static inline void put_inotify_watch(struct inotify_watch *watch)
 {
 }
 
+extern inline int pin_inotify_watch(struct inotify_watch *watch)
+{
+       return 0;
+}
+
+extern inline void unpin_inotify_watch(struct inotify_watch *watch)
+{
+}
+
 #endif /* CONFIG_INOTIFY */
 
 #endif /* __KERNEL __ */
index fba141d3ca0783303c661f39fb2c503ba418dc56..dc7e0d0a6474448aba71b4c32d2045afc44e240e 100644 (file)
@@ -318,32 +318,36 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
        return buf;
 }
 
-#define pr_emerg(fmt, arg...) \
-       printk(KERN_EMERG fmt, ##arg)
-#define pr_alert(fmt, arg...) \
-       printk(KERN_ALERT fmt, ##arg)
-#define pr_crit(fmt, arg...) \
-       printk(KERN_CRIT fmt, ##arg)
-#define pr_err(fmt, arg...) \
-       printk(KERN_ERR fmt, ##arg)
-#define pr_warning(fmt, arg...) \
-       printk(KERN_WARNING fmt, ##arg)
-#define pr_notice(fmt, arg...) \
-       printk(KERN_NOTICE fmt, ##arg)
-#define pr_info(fmt, arg...) \
-       printk(KERN_INFO fmt, ##arg)
+#ifndef pr_fmt
+#define pr_fmt(fmt) fmt
+#endif
+
+#define pr_emerg(fmt, ...) \
+        printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_alert(fmt, ...) \
+        printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_crit(fmt, ...) \
+        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_err(fmt, ...) \
+        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warning(fmt, ...) \
+        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_notice(fmt, ...) \
+        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_info(fmt, ...) \
+        printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
 
 /* If you are writing a driver, please use dev_dbg instead */
 #if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
 #define pr_debug(fmt, ...) do { \
-       dynamic_pr_debug(fmt, ##__VA_ARGS__); \
+       dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
        } while (0)
 #elif defined(DEBUG)
-#define pr_debug(fmt, arg...) \
-       printk(KERN_DEBUG fmt, ##arg)
+#define pr_debug(fmt, ...) \
+       printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #else
-#define pr_debug(fmt, arg...) \
-       ({ if (0) printk(KERN_DEBUG fmt, ##arg); 0; })
+#define pr_debug(fmt, ...) \
+       ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
 #endif
 
 /*
index e27f216361fc1511f6fc6b52d7570536af95a9e6..4e4f1277f3bf487517faf1d2dd4f275a6ddbad7f 100644 (file)
 
 #define PORT_SC26XX    82
 
+/* SH-SCI */
+#define PORT_SCIFA     83
+
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
index ba965c84ae0695b175da712a0951b6c3e0530b5c..000da12b5cf03650ad90db9be142d803930fb62e 100644 (file)
 #define SLAB_CACHE_DMA         0x00004000UL    /* Use GFP_DMA memory */
 #define SLAB_STORE_USER                0x00010000UL    /* DEBUG: Store the last owner for bug hunting */
 #define SLAB_PANIC             0x00040000UL    /* Panic if kmem_cache_create() fails */
+/*
+ * SLAB_DESTROY_BY_RCU - **WARNING** READ THIS!
+ *
+ * This delays freeing the SLAB page by a grace period, it does _NOT_
+ * delay object freeing. This means that if you do kmem_cache_free()
+ * that memory location is free to be reused at any time. Thus it may
+ * be possible to see another object there in the same RCU grace period.
+ *
+ * This feature only ensures the memory location backing the object
+ * stays valid, the trick to using this is relying on an independent
+ * object validation pass. Something like:
+ *
+ *  rcu_read_lock()
+ * again:
+ *  obj = lockless_lookup(key);
+ *  if (obj) {
+ *    if (!try_get_ref(obj)) // might fail for free objects
+ *      goto again;
+ *
+ *    if (obj->key != key) { // not the object we expected
+ *      put_ref(obj);
+ *      goto again;
+ *    }
+ *  }
+ *  rcu_read_unlock();
+ *
+ * See also the comment on struct slab_rcu in mm/slab.c.
+ */
 #define SLAB_DESTROY_BY_RCU    0x00080000UL    /* Defer freeing slabs to RCU */
 #define SLAB_MEM_SPREAD                0x00100000UL    /* Spread some memory over cpuset */
 #define SLAB_TRACE             0x00200000UL    /* Trace allocations and frees */
index 8fa973bede5e1930d8b96317b9fbc99305a4d66b..f72aa51f7bcdc3fdb3d728c452cdd12f2d3d9baf 100644 (file)
@@ -108,6 +108,7 @@ enum usb_interface_condition {
  *     (in probe()), bound to a driver, or unbinding (in disconnect())
  * @is_active: flag set when the interface is bound and not suspended.
  * @sysfs_files_created: sysfs attributes exist
+ * @unregistering: flag set when the interface is being unregistered
  * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
  *     capability during autosuspend.
  * @needs_altsetting0: flag set when a set-interface request for altsetting 0
@@ -163,6 +164,7 @@ struct usb_interface {
        enum usb_interface_condition condition;         /* state of binding */
        unsigned is_active:1;           /* the interface is not suspended */
        unsigned sysfs_files_created:1; /* the sysfs attributes exist */
+       unsigned unregistering:1;       /* unregistration is in progress */
        unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
        unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */
        unsigned needs_binding:1;       /* needs delayed unbind/rebind */
index 86b00c53fadeb833d054fab64d13fb9a0e8d6fde..226da2733c1e7f8a885d8db735f11605136fa103 100644 (file)
@@ -771,8 +771,7 @@ config SLAB
        help
          The regular slab allocator that is established and known to work
          well in all environments. It organizes cache hot objects in
-         per cpu and per node queues. SLAB is the default choice for
-         a slab allocator.
+         per cpu and per node queues.
 
 config SLUB
        bool "SLUB (Unqueued Allocator)"
@@ -781,7 +780,8 @@ config SLUB
           instead of managing queues of cached objects (SLAB approach).
           Per cpu caching is realized using slabs of objects instead
           of queues of objects. SLUB can use memory efficiently
-          and has enhanced diagnostics.
+          and has enhanced diagnostics. SLUB is the default choice for
+          a slab allocator.
 
 config SLOB
        depends on EMBEDDED
index 8ba0e0d934f23137762f74525f6757e27a129056..8b509441f49a2f740a2d709c66cecc73d9896f1c 100644 (file)
@@ -24,6 +24,7 @@ struct audit_chunk {
        struct list_head trees;         /* with root here */
        int dead;
        int count;
+       atomic_long_t refs;
        struct rcu_head head;
        struct node {
                struct list_head list;
@@ -56,7 +57,8 @@ static LIST_HEAD(prune_list);
  * tree is refcounted; one reference for "some rules on rules_list refer to
  * it", one for each chunk with pointer to it.
  *
- * chunk is refcounted by embedded inotify_watch.
+ * chunk is refcounted by embedded inotify_watch + .refs (non-zero refcount
+ * of watch contributes 1 to .refs).
  *
  * node.index allows to get from node.list to containing chunk.
  * MSB of that sucker is stolen to mark taggings that we might have to
@@ -121,6 +123,7 @@ static struct audit_chunk *alloc_chunk(int count)
        INIT_LIST_HEAD(&chunk->hash);
        INIT_LIST_HEAD(&chunk->trees);
        chunk->count = count;
+       atomic_long_set(&chunk->refs, 1);
        for (i = 0; i < count; i++) {
                INIT_LIST_HEAD(&chunk->owners[i].list);
                chunk->owners[i].index = i;
@@ -129,9 +132,8 @@ static struct audit_chunk *alloc_chunk(int count)
        return chunk;
 }
 
-static void __free_chunk(struct rcu_head *rcu)
+static void free_chunk(struct audit_chunk *chunk)
 {
-       struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
        int i;
 
        for (i = 0; i < chunk->count; i++) {
@@ -141,14 +143,16 @@ static void __free_chunk(struct rcu_head *rcu)
        kfree(chunk);
 }
 
-static inline void free_chunk(struct audit_chunk *chunk)
+void audit_put_chunk(struct audit_chunk *chunk)
 {
-       call_rcu(&chunk->head, __free_chunk);
+       if (atomic_long_dec_and_test(&chunk->refs))
+               free_chunk(chunk);
 }
 
-void audit_put_chunk(struct audit_chunk *chunk)
+static void __put_chunk(struct rcu_head *rcu)
 {
-       put_inotify_watch(&chunk->watch);
+       struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
+       audit_put_chunk(chunk);
 }
 
 enum {HASH_SIZE = 128};
@@ -176,7 +180,7 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode)
 
        list_for_each_entry_rcu(p, list, hash) {
                if (p->watch.inode == inode) {
-                       get_inotify_watch(&p->watch);
+                       atomic_long_inc(&p->refs);
                        return p;
                }
        }
@@ -194,17 +198,49 @@ int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
 
 /* tagging and untagging inodes with trees */
 
-static void untag_chunk(struct audit_chunk *chunk, struct node *p)
+static struct audit_chunk *find_chunk(struct node *p)
+{
+       int index = p->index & ~(1U<<31);
+       p -= index;
+       return container_of(p, struct audit_chunk, owners[0]);
+}
+
+static void untag_chunk(struct node *p)
 {
+       struct audit_chunk *chunk = find_chunk(p);
        struct audit_chunk *new;
        struct audit_tree *owner;
        int size = chunk->count - 1;
        int i, j;
 
+       if (!pin_inotify_watch(&chunk->watch)) {
+               /*
+                * Filesystem is shutting down; all watches are getting
+                * evicted, just take it off the node list for this
+                * tree and let the eviction logics take care of the
+                * rest.
+                */
+               owner = p->owner;
+               if (owner->root == chunk) {
+                       list_del_init(&owner->same_root);
+                       owner->root = NULL;
+               }
+               list_del_init(&p->list);
+               p->owner = NULL;
+               put_tree(owner);
+               return;
+       }
+
+       spin_unlock(&hash_lock);
+
+       /*
+        * pin_inotify_watch() succeeded, so the watch won't go away
+        * from under us.
+        */
        mutex_lock(&chunk->watch.inode->inotify_mutex);
        if (chunk->dead) {
                mutex_unlock(&chunk->watch.inode->inotify_mutex);
-               return;
+               goto out;
        }
 
        owner = p->owner;
@@ -221,7 +257,7 @@ static void untag_chunk(struct audit_chunk *chunk, struct node *p)
                inotify_evict_watch(&chunk->watch);
                mutex_unlock(&chunk->watch.inode->inotify_mutex);
                put_inotify_watch(&chunk->watch);
-               return;
+               goto out;
        }
 
        new = alloc_chunk(size);
@@ -263,7 +299,7 @@ static void untag_chunk(struct audit_chunk *chunk, struct node *p)
        inotify_evict_watch(&chunk->watch);
        mutex_unlock(&chunk->watch.inode->inotify_mutex);
        put_inotify_watch(&chunk->watch);
-       return;
+       goto out;
 
 Fallback:
        // do the best we can
@@ -277,6 +313,9 @@ Fallback:
        put_tree(owner);
        spin_unlock(&hash_lock);
        mutex_unlock(&chunk->watch.inode->inotify_mutex);
+out:
+       unpin_inotify_watch(&chunk->watch);
+       spin_lock(&hash_lock);
 }
 
 static int create_chunk(struct inode *inode, struct audit_tree *tree)
@@ -387,13 +426,6 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
        return 0;
 }
 
-static struct audit_chunk *find_chunk(struct node *p)
-{
-       int index = p->index & ~(1U<<31);
-       p -= index;
-       return container_of(p, struct audit_chunk, owners[0]);
-}
-
 static void kill_rules(struct audit_tree *tree)
 {
        struct audit_krule *rule, *next;
@@ -431,17 +463,10 @@ static void prune_one(struct audit_tree *victim)
        spin_lock(&hash_lock);
        while (!list_empty(&victim->chunks)) {
                struct node *p;
-               struct audit_chunk *chunk;
 
                p = list_entry(victim->chunks.next, struct node, list);
-               chunk = find_chunk(p);
-               get_inotify_watch(&chunk->watch);
-               spin_unlock(&hash_lock);
-
-               untag_chunk(chunk, p);
 
-               put_inotify_watch(&chunk->watch);
-               spin_lock(&hash_lock);
+               untag_chunk(p);
        }
        spin_unlock(&hash_lock);
        put_tree(victim);
@@ -469,7 +494,6 @@ static void trim_marked(struct audit_tree *tree)
 
        while (!list_empty(&tree->chunks)) {
                struct node *node;
-               struct audit_chunk *chunk;
 
                node = list_entry(tree->chunks.next, struct node, list);
 
@@ -477,14 +501,7 @@ static void trim_marked(struct audit_tree *tree)
                if (!(node->index & (1U<<31)))
                        break;
 
-               chunk = find_chunk(node);
-               get_inotify_watch(&chunk->watch);
-               spin_unlock(&hash_lock);
-
-               untag_chunk(chunk, node);
-
-               put_inotify_watch(&chunk->watch);
-               spin_lock(&hash_lock);
+               untag_chunk(node);
        }
        if (!tree->root && !tree->goner) {
                tree->goner = 1;
@@ -878,7 +895,7 @@ static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
 static void destroy_watch(struct inotify_watch *watch)
 {
        struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
-       free_chunk(chunk);
+       call_rcu(&chunk->head, __put_chunk);
 }
 
 static const struct inotify_operations rtree_inotify_ops = {
index b7d354e2b0ef35d618f7a69fee70d301078faa02..9fd85a4640a096eab72312d33a090e417e013548 100644 (file)
@@ -1094,8 +1094,8 @@ static void audit_inotify_unregister(struct list_head *in_list)
        list_for_each_entry_safe(p, n, in_list, ilist) {
                list_del(&p->ilist);
                inotify_rm_watch(audit_ih, &p->wdata);
-               /* the put matching the get in audit_do_del_rule() */
-               put_inotify_watch(&p->wdata);
+               /* the unpin matching the pin in audit_do_del_rule() */
+               unpin_inotify_watch(&p->wdata);
        }
 }
 
@@ -1389,9 +1389,13 @@ static inline int audit_del_rule(struct audit_entry *entry,
                                /* Put parent on the inotify un-registration
                                 * list.  Grab a reference before releasing
                                 * audit_filter_mutex, to be released in
-                                * audit_inotify_unregister(). */
-                               list_add(&parent->ilist, &inotify_list);
-                               get_inotify_watch(&parent->wdata);
+                                * audit_inotify_unregister().
+                                * If filesystem is going away, just leave
+                                * the sucker alone, eviction will take
+                                * care of it.
+                                */
+                               if (pin_inotify_watch(&parent->wdata))
+                                       list_add(&parent->ilist, &inotify_list);
                        }
                }
        }
index ae2b92be5faec1efa73beefb63304a22d030fc16..2d8be7ebb0f73499f894a1828fd827f0217290f1 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/cn_proc.h>
 #include <linux/mutex.h>
 #include <linux/futex.h>
-#include <linux/compat.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/audit.h> /* for audit_free() */
 #include <linux/resource.h>
@@ -1059,14 +1058,6 @@ NORET_TYPE void do_exit(long code)
                exit_itimers(tsk->signal);
        }
        acct_collect(code, group_dead);
-#ifdef CONFIG_FUTEX
-       if (unlikely(tsk->robust_list))
-               exit_robust_list(tsk);
-#ifdef CONFIG_COMPAT
-       if (unlikely(tsk->compat_robust_list))
-               compat_exit_robust_list(tsk);
-#endif
-#endif
        if (group_dead)
                tty_audit_exit();
        if (unlikely(tsk->audit_context))
index f6083561dfe0a9f8d2a13138f7332bc358a51653..2a372a0e206fa2de99dbfdd594f86f6eb927bf40 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/jiffies.h>
 #include <linux/tracehook.h>
 #include <linux/futex.h>
+#include <linux/compat.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/rcupdate.h>
 #include <linux/ptrace.h>
@@ -519,6 +520,16 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
 {
        struct completion *vfork_done = tsk->vfork_done;
 
+       /* Get rid of any futexes when releasing the mm */
+#ifdef CONFIG_FUTEX
+       if (unlikely(tsk->robust_list))
+               exit_robust_list(tsk);
+#ifdef CONFIG_COMPAT
+       if (unlikely(tsk->compat_robust_list))
+               compat_exit_robust_list(tsk);
+#endif
+#endif
+
        /* Get rid of any cached register state */
        deactivate_mm(tsk, mm);
 
index 3b5860294bb6654a7b6765a327cef83a9952a29d..c141b3e780719d314a5010f702190d8a9c56c23b 100644 (file)
@@ -2368,39 +2368,6 @@ int page_evictable(struct page *page, struct vm_area_struct *vma)
        return 1;
 }
 
-static void show_page_path(struct page *page)
-{
-       char buf[256];
-       if (page_is_file_cache(page)) {
-               struct address_space *mapping = page->mapping;
-               struct dentry *dentry;
-               pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
-
-               spin_lock(&mapping->i_mmap_lock);
-               dentry = d_find_alias(mapping->host);
-               printk(KERN_INFO "rescued: %s %lu\n",
-                      dentry_path(dentry, buf, 256), pgoff);
-               spin_unlock(&mapping->i_mmap_lock);
-       } else {
-#if defined(CONFIG_MM_OWNER) && defined(CONFIG_MMU)
-               struct anon_vma *anon_vma;
-               struct vm_area_struct *vma;
-
-               anon_vma = page_lock_anon_vma(page);
-               if (!anon_vma)
-                       return;
-
-               list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
-                       printk(KERN_INFO "rescued: anon %s\n",
-                              vma->vm_mm->owner->comm);
-                       break;
-               }
-               page_unlock_anon_vma(anon_vma);
-#endif
-       }
-}
-
-
 /**
  * check_move_unevictable_page - check page for evictability and move to appropriate zone lru list
  * @page: page to check evictability and move to appropriate lru list
@@ -2421,8 +2388,6 @@ retry:
        if (page_evictable(page, NULL)) {
                enum lru_list l = LRU_INACTIVE_ANON + page_is_file_cache(page);
 
-               show_page_path(page);
-
                __dec_zone_state(zone, NR_UNEVICTABLE);
                list_move(&page->lru, &zone->lru[l].list);
                __inc_zone_state(zone, NR_INACTIVE_ANON + l);
index c42c0c400bf9a36176ceedcac6a94083016e5b8d..0663f99e977a8af81e1c149d3b193b6b94acb520 100644 (file)
@@ -13,22 +13,24 @@ menuconfig NET_9P
 
          If unsure, say N.
 
+if NET_9P
+
 config NET_9P_VIRTIO
-       depends on NET_9P && EXPERIMENTAL && VIRTIO
+       depends on EXPERIMENTAL && VIRTIO
        tristate "9P Virtio Transport (Experimental)"
        help
          This builds support for a transports between
          guest partitions and a host partition.
 
 config NET_9P_RDMA
-       depends on NET_9P && INFINIBAND && EXPERIMENTAL
+       depends on INET && INFINIBAND && EXPERIMENTAL
        tristate "9P RDMA Transport (Experimental)"
        help
-         This builds support for a RDMA transport.
+         This builds support for an RDMA transport.
 
 config NET_9P_DEBUG
        bool "Debug information"
-       depends on NET_9P
        help
          Say Y if you want the 9P subsystem to log debug information.
 
+endif