]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 5 Oct 2009 19:02:18 +0000 (12:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 5 Oct 2009 19:02:18 +0000 (12:02 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Don't leak 64-bit kernel register values to 32-bit processes
  x86, SLUB: Remove unused CONFIG FAST_CMPXCHG_LOCAL
  x86: earlyprintk: Fix regression to handle serial,ttySn as 1 arg
  x86: Don't generate cmpxchg8b_emu if CONFIG_X86_CMPXCHG64=y
  x86: Fix csum_ipv6_magic asm memory clobber
  x86: Optimize cmpxchg64() at build-time some more

408 files changed:
Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
Documentation/SubmittingPatches
Documentation/arm/tcm.txt
Documentation/connector/cn_test.c
Documentation/connector/connector.txt
Documentation/hwmon/ltc4215
Documentation/hwmon/ltc4245
Documentation/i2c/instantiating-devices
Documentation/misc-devices/eeprom [moved from Documentation/i2c/chips/eeprom with 100% similarity]
Documentation/misc-devices/max6875 [moved from Documentation/i2c/chips/max6875 with 94% similarity]
Documentation/networking/timestamping/timestamping.c
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/w1/masters/ds2482
MAINTAINERS
Makefile
arch/arm/common/sa1111.c
arch/arm/configs/h3600_defconfig
arch/arm/configs/iop33x_defconfig
arch/arm/include/asm/glue.h
arch/arm/include/asm/hardware/iop3xx.h
arch/arm/include/asm/smp_plat.h [new file with mode: 0644]
arch/arm/include/asm/unistd.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/head-common.S
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/traps.c
arch/arm/mach-bcmring/core.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-iop32x/include/mach/iop32x.h
arch/arm/mach-iop33x/include/mach/iop33x.h
arch/arm/mach-ns9xxx/clock.c
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/time.c
arch/arm/mach-u300/gpio.c
arch/arm/mach-u300/include/mach/gpio.h
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/fault.c
arch/arm/mm/mmap.c
arch/arm/mm/mmu.c
arch/arm/mm/pabort-legacy.S [new file with mode: 0644]
arch/arm/mm/pabort-v6.S [new file with mode: 0644]
arch/arm/mm/pabort-v7.S [new file with mode: 0644]
arch/arm/mm/proc-arm1020.S
arch/arm/mm/proc-arm1020e.S
arch/arm/mm/proc-arm1022.S
arch/arm/mm/proc-arm1026.S
arch/arm/mm/proc-arm6_7.S
arch/arm/mm/proc-arm720.S
arch/arm/mm/proc-arm740.S
arch/arm/mm/proc-arm7tdmi.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm922.S
arch/arm/mm/proc-arm925.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-arm940.S
arch/arm/mm/proc-arm946.S
arch/arm/mm/proc-arm9tdmi.S
arch/arm/mm/proc-fa526.S
arch/arm/mm/proc-feroceon.S
arch/arm/mm/proc-mohawk.S
arch/arm/mm/proc-sa110.S
arch/arm/mm/proc-sa1100.S
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
arch/arm/plat-iop/pci.c
arch/arm/plat-iop/time.c
arch/arm/plat-s3c24xx/include/plat/mci.h
arch/blackfin/mach-bf561/coreb.c
arch/cris/arch-v10/drivers/sync_serial.c
arch/cris/arch-v32/drivers/mach-fs/gpio.c
arch/m32r/include/asm/io.h
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/time.c
arch/m32r/kernel/traps.c
arch/m32r/lib/delay.c
arch/m32r/mm/discontig.c
arch/m32r/mm/mmu.S
arch/m68k/include/asm/hardirq_mm.h
arch/m68knommu/kernel/asm-offsets.c
arch/m68knommu/kernel/entry.S
arch/m68knommu/mm/init.c
arch/m68knommu/platform/5206e/config.c
arch/m68knommu/platform/68328/entry.S
arch/m68knommu/platform/68360/entry.S
arch/m68knommu/platform/coldfire/entry.S
arch/mn10300/include/asm/uaccess.h
arch/mn10300/unit-asb2303/include/unit/clock.h
arch/mn10300/unit-asb2305/include/unit/clock.h
arch/powerpc/kvm/timing.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/pseries/dtl.c
arch/x86/xen/debugfs.c
block/blk-barrier.c
block/blk-core.c
block/blk-merge.c
block/blk-settings.c
block/blk-sysfs.c
block/cfq-iosched.c
block/compat_ioctl.c
block/genhd.c
block/ioctl.c
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/acpi_pad.c [new file with mode: 0644]
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/proc.c
drivers/acpi/processor_core.c
drivers/acpi/scan.c
drivers/acpi/video.c
drivers/atm/ambassador.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/horizon.c
drivers/atm/iphase.c
drivers/atm/zatm.c
drivers/block/DAC960.c
drivers/block/cciss.c
drivers/block/cciss.h
drivers/block/cpqarray.c
drivers/char/apm-emulation.c
drivers/char/bfin-otp.c
drivers/char/cyclades.c
drivers/char/dtlk.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/serial167.c
drivers/char/tty_ldisc.c
drivers/char/vt_ioctl.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/connector/cn_queue.c
drivers/connector/connector.c
drivers/firewire/core-cdev.c
drivers/gpio/gpiolib.c
drivers/hid/hidraw.c
drivers/hwmon/fschmd.c
drivers/hwmon/ltc4215.c
drivers/hwmon/ltc4245.c
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-isch.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-viapro.c
drivers/infiniband/core/ucm.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_main.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/misc/uinput.c
drivers/input/mousedev.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/mISDN/socket.c
drivers/leds/leds-pca9532.c
drivers/lguest/lguest_user.c
drivers/macintosh/therm_adt746x.c
drivers/macintosh/therm_pm72.c
drivers/macintosh/windfarm_lm75_sensor.c
drivers/macintosh/windfarm_max6690_sensor.c
drivers/macintosh/windfarm_smu_sat.c
drivers/md/dm-log-userspace-transfer.c
drivers/md/dm.c
drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dvb_demux.c
drivers/media/dvb/firewire/firedtv-ci.c
drivers/media/radio/radio-cadet.c
drivers/media/video/cpia.c
drivers/mfd/ab3100-core.c
drivers/mfd/ucb1400_core.c
drivers/misc/eeprom/max6875.c
drivers/misc/phantom.c
drivers/misc/sgi-gru/grufile.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/sdio_cis.c
drivers/mmc/host/Kconfig
drivers/mmc/host/mmci.c
drivers/mmc/host/s3cmci.c
drivers/mmc/host/s3cmci.h
drivers/mtd/mtd_blkdevs.c
drivers/net/3c59x.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/bcm63xx_enet.c
drivers/net/benet/be.h
drivers/net/benet/be_cmds.c
drivers/net/benet/be_cmds.h
drivers/net/benet/be_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/cnic.c
drivers/net/cnic_if.h
drivers/net/e1000e/netdev.c
drivers/net/hamradio/mkiss.c
drivers/net/igb/igb_main.c
drivers/net/iseries_veth.c
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/ks8851_mll.c [new file with mode: 0644]
drivers/net/meth.c
drivers/net/pppol2tp.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_main.c
drivers/net/sgiseeq.c
drivers/net/skge.c
drivers/net/skge.h
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/tg3.h
drivers/net/virtio_net.c
drivers/net/wireless/Kconfig
drivers/net/wireless/ath/ar9170/phy.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/pcmcia/sa1100_assabet.c
drivers/pcmcia/sa1100_neponset.c
drivers/platform/x86/sony-laptop.c
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_perf.c
drivers/scsi/sg.c
drivers/serial/8250.c
drivers/serial/Kconfig
drivers/serial/icom.c
drivers/serial/sa1100.c
drivers/serial/serial_txx9.c
drivers/sfi/sfi_core.c
drivers/spi/Makefile
drivers/spi/spi_imx.c [moved from drivers/spi/mxc_spi.c with 55% similarity]
drivers/spi/spidev.c
drivers/staging/dst/dcore.c
drivers/staging/iio/light/tsl2561.c
drivers/staging/pohmelfs/config.c
drivers/usb/class/usbtmc.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/printer.c
drivers/usb/host/whci/debug.c
drivers/usb/misc/rio500.c
drivers/uwb/uwb-debug.c
drivers/video/uvesafb.c
drivers/w1/masters/ds2482.c
drivers/w1/w1_netlink.c
drivers/xen/xenfs/xenbus.c
fs/afs/cache.h [deleted file]
fs/afs/internal.h
fs/anon_inodes.c
fs/bio.c
fs/btrfs/acl.c
fs/btrfs/btrfs_inode.h
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/btrfs/xattr.c
fs/coda/psdev.c
fs/ext4/Kconfig
fs/ext4/inode.c
fs/ext4/super.c
fs/jbd2/journal.c
fs/nfsd/nfsctl.c
fs/nilfs2/dir.c
fs/nilfs2/file.c
fs/nilfs2/mdt.c
fs/nilfs2/nilfs.h
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/dlm/dlmdebug.c
fs/ocfs2/super.c
fs/omfs/dir.c
fs/omfs/file.c
fs/omfs/omfs.h
fs/partitions/check.c
fs/select.c
include/asm-generic/gpio.h
include/linux/atmdev.h
include/linux/blkdev.h
include/linux/blktrace_api.h
include/linux/cgroup.h
include/linux/connector.h
include/linux/fs.h
include/linux/genhd.h
include/linux/mroute.h
include/linux/mroute6.h
include/linux/net.h
include/linux/netfilter.h
include/linux/poll.h
include/linux/res_counter.h
include/net/compat.h
include/net/inet_connection_sock.h
include/net/ip.h
include/net/ipv6.h
include/net/sctp/structs.h
include/net/sock.h
include/net/tcp.h
include/net/udp.h
include/trace/events/block.h
kernel/cgroup.c
kernel/kprobes.c
kernel/module.c
kernel/rcutree_trace.c
kernel/res_counter.c
kernel/sched.c
kernel/time/timer_list.c
kernel/time/timer_stats.c
kernel/trace/blktrace.c
lib/vsprintf.c
mm/memcontrol.c
mm/rmap.c
mm/swapfile.c
net/atm/common.c
net/atm/common.h
net/atm/pvc.c
net/atm/svc.c
net/ax25/af_ax25.c
net/bluetooth/hci_sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/can/raw.c
net/compat.c
net/core/dev.c
net/core/pktgen.c
net/core/sock.c
net/dccp/dccp.h
net/dccp/proto.c
net/decnet/af_decnet.c
net/ieee802154/dgram.c
net/ieee802154/raw.c
net/ipv4/af_inet.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipmr.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/udp_impl.h
net/ipv6/ip6mr.c
net/ipv6/ipv6_sockglue.c
net/ipv6/raw.c
net/ipv6/sit.c
net/ipv6/udp.c
net/ipv6/udp_impl.h
net/ipx/af_ipx.c
net/irda/af_irda.c
net/iucv/af_iucv.c
net/llc/af_llc.c
net/mac80211/tx.c
net/netfilter/nf_sockopt.c
net/netlink/af_netlink.c
net/netrom/af_netrom.c
net/packet/af_packet.c
net/phonet/pep.c
net/phonet/socket.c
net/rds/af_rds.c
net/rfkill/core.c
net/rose/af_rose.c
net/rxrpc/af_rxrpc.c
net/sctp/socket.c
net/socket.c
net/tipc/socket.c
net/x25/af_x25.c
samples/tracepoints/tracepoint-sample.c
security/integrity/ima/ima_fs.c
sound/aoa/codecs/tas.c
sound/mips/hal2.c
sound/mips/sgio2audio.c
sound/pci/ctxfi/ctatc.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/mia.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/intel8x0.c
sound/ppc/keywest.c
sound/soc/blackfin/Kconfig
sound/soc/blackfin/bf5xx-i2s.c
sound/soc/blackfin/bf5xx-tdm.c
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-mcasp.h
sound/soc/davinci/davinci-pcm.c
sound/soc/davinci/davinci-pcm.h
sound/soc/pxa/Kconfig
sound/usb/usbmixer.c
virt/kvm/kvm_main.c

index 0a92a7c93a62067f4526fe581f4604c3eb9f5ee0..4f29e5f1ebfa5b19cd7851e6148b80219911e9c2 100644 (file)
@@ -31,3 +31,31 @@ Date:                March 2009
 Kernel Version: 2.6.30
 Contact:       iss_storagedev@hp.com
 Description:   A symbolic link to /sys/block/cciss!cXdY
+
+Where:         /sys/bus/pci/devices/<dev>/ccissX/rescan
+Date:          August 2009
+Kernel Version:        2.6.31
+Contact:       iss_storagedev@hp.com
+Description:   Kicks of a rescan of the controller to discover logical
+               drive topology changes.
+
+Where:         /sys/bus/pci/devices/<dev>/ccissX/cXdY/lunid
+Date:          August 2009
+Kernel Version: 2.6.31
+Contact:       iss_storagedev@hp.com
+Description:   Displays the 8-byte LUN ID used to address logical
+               drive Y of controller X.
+
+Where:         /sys/bus/pci/devices/<dev>/ccissX/cXdY/raid_level
+Date:          August 2009
+Kernel Version: 2.6.31
+Contact:       iss_storagedev@hp.com
+Description:   Displays the RAID level of logical drive Y of
+               controller X.
+
+Where:         /sys/bus/pci/devices/<dev>/ccissX/cXdY/usage_count
+Date:          August 2009
+Kernel Version: 2.6.31
+Contact:       iss_storagedev@hp.com
+Description:   Displays the usage count (number of opens) of logical drive Y
+               of controller X.
index b7f9d3b4bbf6b15934091f55b20e327419cddd6b..72651f788f4e3536149ef5e7ddfbed96a8f14d2f 100644 (file)
@@ -232,7 +232,7 @@ your e-mail client so that it sends your patches untouched.
 When sending patches to Linus, always follow step #7.
 
 Large changes are not appropriate for mailing lists, and some
-maintainers.  If your patch, uncompressed, exceeds 40 kB in size,
+maintainers.  If your patch, uncompressed, exceeds 300 kB in size,
 it is preferred that you store your patch on an Internet-accessible
 server, and provide instead a URL (link) pointing to your patch.
 
index 074f4be6667fa902662fb195e35ccc3988015eee..77fd9376e6d73b4cc47d39afb8d7b01ad4b00120 100644 (file)
@@ -29,11 +29,13 @@ TCM location and size. Notice that this is not a MMU table: you
 actually move the physical location of the TCM around. At the
 place you put it, it will mask any underlying RAM from the
 CPU so it is usually wise not to overlap any physical RAM with
-the TCM. The TCM memory exists totally outside the MMU and will
-override any MMU mappings.
+the TCM.
 
-Code executing inside the ITCM does not "see" any MMU mappings
-and e.g. register accesses must be made to physical addresses.
+The TCM memory can then be remapped to another address again using
+the MMU, but notice that the TCM if often used in situations where
+the MMU is turned off. To avoid confusion the current Linux
+implementation will map the TCM 1 to 1 from physical to virtual
+memory in the location specified by the machine.
 
 TCM is used for a few things:
 
index 1711adc3337349ddfbc8d2bb0958123602193d14..b07add3467f1b4d84e07d95a43fece6b8ec7f83e 100644 (file)
@@ -34,7 +34,7 @@ static char cn_test_name[] = "cn_test";
 static struct sock *nls;
 static struct timer_list cn_test_timer;
 
-static void cn_test_callback(struct cn_msg *msg)
+static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
        pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
                __func__, jiffies, msg->id.idx, msg->id.val,
index 81e6bf6ead57b172ad0b8822ae9a1ad972e05839..78c9466a9aa8005c4171bdb160c60183042318d6 100644 (file)
@@ -23,7 +23,7 @@ handling, etc...  The Connector driver allows any kernelspace agents to use
 netlink based networking for inter-process communication in a significantly
 easier way:
 
-int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
+int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
 void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);
 
 struct cb_id
@@ -53,15 +53,15 @@ struct cn_msg
 Connector interfaces.
 /*****************************************/
 
-int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
+int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
 
  Registers new callback with connector core.
 
  struct cb_id *id              - unique connector's user identifier.
                                  It must be registered in connector.h for legal in-kernel users.
  char *name                    - connector's callback symbolic name.
- void (*callback) (void *)     - connector's callback.
-                                 Argument must be dereferenced to struct cn_msg *.
+ void (*callback) (struct cn..)        - connector's callback.
+                                 cn_msg and the sender's credentials
 
 
 void cn_del_callback(struct cb_id *id);
index 2e6a21eb656c556ce4e4c154a6e1229c35275938..c196a18462592f842d7637e3b443c295092cb78b 100644 (file)
@@ -22,12 +22,13 @@ Usage Notes
 -----------
 
 This driver does not probe for LTC4215 devices, due to the fact that some
-of the possible addresses are unfriendly to probing. You will need to use
-the "force" parameter to tell the driver where to find the device.
+of the possible addresses are unfriendly to probing. You will have to
+instantiate the devices explicitly.
 
 Example: the following will load the driver for an LTC4215 at address 0x44
 on I2C bus #0:
-$ modprobe ltc4215 force=0,0x44
+$ modprobe ltc4215
+$ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device
 
 
 Sysfs entries
index bae7a3adc5d8ff72aded4e8abbd07c30de454f59..02838a47d86210fa8bee469f595c94851594bd44 100644 (file)
@@ -23,12 +23,13 @@ Usage Notes
 -----------
 
 This driver does not probe for LTC4245 devices, due to the fact that some
-of the possible addresses are unfriendly to probing. You will need to use
-the "force" parameter to tell the driver where to find the device.
+of the possible addresses are unfriendly to probing. You will have to
+instantiate the devices explicitly.
 
 Example: the following will load the driver for an LTC4245 at address 0x23
 on I2C bus #1:
-$ modprobe ltc4245 force=1,0x23
+$ modprobe ltc4245
+$ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device
 
 
 Sysfs entries
index c740b7b410881a72f41256220c03b83c4796d523..e89490270abad1ece6f8003b16ac815490f8de17 100644 (file)
@@ -188,7 +188,7 @@ segment, the address is sufficient to uniquely identify the device to be
 deleted.
 
 Example:
-# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device
+# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
 
 While this interface should only be used when in-kernel device declaration
 can't be done, there is a variety of cases where it can be helpful:
similarity index 94%
rename from Documentation/i2c/chips/max6875
rename to Documentation/misc-devices/max6875
index 10ca43cd1a72aa9d2d5bafc77a1116c126d7d892..1e89ee3ccc1b0ce33a7cd089ae42215211edf201 100644 (file)
@@ -42,10 +42,12 @@ General Remarks
 
 Valid addresses for the MAX6875 are 0x50 and 0x52.
 Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.
-The driver does not probe any address, so you must force the address.
+The driver does not probe any address, so you explicitly instantiate the
+devices.
 
 Example:
-$ modprobe max6875 force=0,0x50
+$ modprobe max6875
+$ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device
 
 The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
 addresses.  For example, for address 0x50, it also reserves 0x51.
index 43d143104210186b5f627b6eba211a180914ebe2..a7936fe8444a1830b5f57eccaf4ca610a42db358 100644 (file)
@@ -381,7 +381,7 @@ int main(int argc, char **argv)
        memset(&hwtstamp, 0, sizeof(hwtstamp));
        strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
        hwtstamp.ifr_data = (void *)&hwconfig;
-       memset(&hwconfig, 0, sizeof(&hwconfig));
+       memset(&hwconfig, 0, sizeof(hwconfig));
        hwconfig.tx_type =
                (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
                HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
index f1708b79f9637a39fe2926bd519bb562a789b8d3..75fddb40f4163d44d33166a486094f1c593852a0 100644 (file)
@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B
   laptop       laptop with HP jack sensing
   mobile       mobile devices with HP jack sensing
   thinkpad     Lenovo Thinkpad X300
+  touchsmart   HP Touchsmart
 
 AD1884
 ======
index 9210d6fa50247a687e0e51e242c15e3ecbbaad28..299b91c7609f2a5d8cd439a3d71d0f2694fea1a8 100644 (file)
@@ -24,8 +24,8 @@ General Remarks
 
 Valid addresses are 0x18, 0x19, 0x1a, and 0x1b.
 However, the device cannot be detected without writing to the i2c bus, so no
-detection is done.
-You should force the device address.
+detection is done. You should instantiate the device explicitly.
 
-$ modprobe ds2482 force=0,0x18
+$ modprobe ds2482
+$ echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device
 
index c450f3abb8c9b5f1fb037b4788665419c0e1238b..09a2028bab7f78786266c10fe1d2f99b0e1e263c 100644 (file)
@@ -257,6 +257,13 @@ W: http://www.lesswatts.org/projects/acpi/
 S:     Supported
 F:     drivers/acpi/fan.c
 
+ACPI PROCESSOR AGGREGATOR DRIVER
+M:     Shaohua Li <shaohua.li@intel.com>
+L:     linux-acpi@vger.kernel.org
+W:     http://www.lesswatts.org/projects/acpi/
+S:     Supported
+F:     drivers/acpi/acpi_pad.c
+
 ACPI THERMAL DRIVER
 M:     Zhang Rui <rui.zhang@intel.com>
 L:     linux-acpi@vger.kernel.org
@@ -646,24 +653,24 @@ ARM/INTEL IOP32X ARM ARCHITECTURE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
+S:     Maintained
 
 ARM/INTEL IOP33X ARM ARCHITECTURE
 M:     Dan Williams <dan.j.williams@intel.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
+S:     Maintained
 
 ARM/INTEL IOP13XX ARM ARCHITECTURE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
+S:     Maintained
 
 ARM/INTEL IQ81342EX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
+S:     Maintained
 
 ARM/INTEL IXP2000 ARM ARCHITECTURE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
@@ -691,7 +698,7 @@ ARM/INTEL XSC3 (MANZANO) ARM CORE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
+S:     Maintained
 
 ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
@@ -741,23 +748,36 @@ M:        Dirk Opfer <dirk@opfer-online.de>
 S:     Maintained
 
 ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
-P:     Marek Vasut
-M:     marek.vasut@gmail.com
+M:     Marek Vasut <marek.vasut@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org
 W:     http://hackndev.com
 S:     Maintained
+F:     arch/arm/mach-pxa/include/mach/palmtx.h
+F:     arch/arm/mach-pxa/palmtx.c
+F:     arch/arm/mach-pxa/include/mach/palmt5.h
+F:     arch/arm/mach-pxa/palmt5.c
+F:     arch/arm/mach-pxa/include/mach/palmld.h
+F:     arch/arm/mach-pxa/palmld.c
+F:     arch/arm/mach-pxa/include/mach/palmte2.h
+F:     arch/arm/mach-pxa/palmte2.c
+F:     arch/arm/mach-pxa/include/mach/palmtc.h
+F:     arch/arm/mach-pxa/palmtc.c
 
 ARM/PALM TREO 680 SUPPORT
 M:     Tomas Cech <sleep_walker@suse.cz>
 L:     linux-arm-kernel@lists.infradead.org
 W:     http://hackndev.com
 S:     Maintained
+F:     arch/arm/mach-pxa/include/mach/treo680.h
+F:     arch/arm/mach-pxa/treo680.c
 
 ARM/PALMZ72 SUPPORT
 M:     Sergey Lapin <slapin@ossfans.org>
 L:     linux-arm-kernel@lists.infradead.org
 W:     http://hackndev.com
 S:     Maintained
+F:     arch/arm/mach-pxa/include/mach/palmz72.h
+F:     arch/arm/mach-pxa/palmz72.c
 
 ARM/PLEB SUPPORT
 M:     Peter Chubb <pleb@gelato.unsw.edu.au>
@@ -2682,7 +2702,7 @@ F:        include/linux/intel-iommu.h
 
 INTEL IOP-ADMA DMA DRIVER
 M:     Dan Williams <dan.j.williams@intel.com>
-S:     Supported
+S:     Maintained
 F:     drivers/dma/iop-adma.c
 
 INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
index 00444a8e304f04b67c9de2f29ea543912fd67f5d..e50569ab5fe8b656396afd38193fc9b847fe30b4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 32
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
index ef12794c3c68f7f2d6be4ec3dcda643540ed091d..8ba7044c554dc2d35b19bd2dbd8a98d6b3206162 100644 (file)
@@ -1032,6 +1032,7 @@ unsigned int sa1111_pll_clock(struct sa1111_dev *sadev)
 
        return __sa1111_pll_clock(sachip);
 }
+EXPORT_SYMBOL(sa1111_pll_clock);
 
 /**
  *     sa1111_select_audio_mode - select I2S or AC link mode
@@ -1059,6 +1060,7 @@ void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
 
        spin_unlock_irqrestore(&sachip->lock, flags);
 }
+EXPORT_SYMBOL(sa1111_select_audio_mode);
 
 /**
  *     sa1111_set_audio_rate - set the audio sample rate
@@ -1083,6 +1085,7 @@ int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
 
        return 0;
 }
+EXPORT_SYMBOL(sa1111_set_audio_rate);
 
 /**
  *     sa1111_get_audio_rate - get the audio sample rate
@@ -1100,6 +1103,7 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
 
        return __sa1111_pll_clock(sachip) / (256 * div);
 }
+EXPORT_SYMBOL(sa1111_get_audio_rate);
 
 void sa1111_set_io_dir(struct sa1111_dev *sadev,
                       unsigned int bits, unsigned int dir,
@@ -1128,6 +1132,7 @@ void sa1111_set_io_dir(struct sa1111_dev *sadev,
        MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
        spin_unlock_irqrestore(&sachip->lock, flags);
 }
+EXPORT_SYMBOL(sa1111_set_io_dir);
 
 void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
 {
@@ -1142,6 +1147,7 @@ void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
        MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
        spin_unlock_irqrestore(&sachip->lock, flags);
 }
+EXPORT_SYMBOL(sa1111_set_io);
 
 void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
 {
@@ -1156,6 +1162,7 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
        MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
        spin_unlock_irqrestore(&sachip->lock, flags);
 }
+EXPORT_SYMBOL(sa1111_set_sleep_io);
 
 /*
  * Individual device operations.
@@ -1176,6 +1183,7 @@ void sa1111_enable_device(struct sa1111_dev *sadev)
        sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
        spin_unlock_irqrestore(&sachip->lock, flags);
 }
+EXPORT_SYMBOL(sa1111_enable_device);
 
 /**
  *     sa1111_disable_device - disable an on-chip SA1111 function block
@@ -1192,6 +1200,7 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
        sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
        spin_unlock_irqrestore(&sachip->lock, flags);
 }
+EXPORT_SYMBOL(sa1111_disable_device);
 
 /*
  *     SA1111 "Register Access Bus."
@@ -1259,17 +1268,20 @@ struct bus_type sa1111_bus_type = {
        .suspend        = sa1111_bus_suspend,
        .resume         = sa1111_bus_resume,
 };
+EXPORT_SYMBOL(sa1111_bus_type);
 
 int sa1111_driver_register(struct sa1111_driver *driver)
 {
        driver->drv.bus = &sa1111_bus_type;
        return driver_register(&driver->drv);
 }
+EXPORT_SYMBOL(sa1111_driver_register);
 
 void sa1111_driver_unregister(struct sa1111_driver *driver)
 {
        driver_unregister(&driver->drv);
 }
+EXPORT_SYMBOL(sa1111_driver_unregister);
 
 static int __init sa1111_init(void)
 {
@@ -1290,16 +1302,3 @@ module_exit(sa1111_exit);
 
 MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
 MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(sa1111_select_audio_mode);
-EXPORT_SYMBOL(sa1111_set_audio_rate);
-EXPORT_SYMBOL(sa1111_get_audio_rate);
-EXPORT_SYMBOL(sa1111_set_io_dir);
-EXPORT_SYMBOL(sa1111_set_io);
-EXPORT_SYMBOL(sa1111_set_sleep_io);
-EXPORT_SYMBOL(sa1111_enable_device);
-EXPORT_SYMBOL(sa1111_disable_device);
-EXPORT_SYMBOL(sa1111_pll_clock);
-EXPORT_SYMBOL(sa1111_bus_type);
-EXPORT_SYMBOL(sa1111_driver_register);
-EXPORT_SYMBOL(sa1111_driver_unregister);
index 1502957db2c30eb801d8480703e7b318cf4b85b2..f6aed7747d4df59f15aa7af7fe0ac4a5d7021a43 100644 (file)
@@ -90,7 +90,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 CONFIG_SA1100_H3600=y
-CONFIG_SA1100_H3XXX=y
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
index eec488298267551fb2755c68c88b5880eb91cbd2..ed2d59d01829f88cd9e7f7a4c76377902ad9f968 100644 (file)
@@ -1,29 +1,26 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc5
-# Wed Dec 12 16:11:27 2007
+# Linux kernel version: 2.6.31-rc6
+# Tue Aug 18 13:41:41 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_GENERIC_GPIO=y
 CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -40,21 +37,39 @@ CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -67,29 +82,48 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -103,6 +137,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
 
 #
 # System Type
@@ -112,15 +147,15 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 CONFIG_ARCH_IOP33X=y
@@ -128,19 +163,26 @@ CONFIG_ARCH_IOP33X=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-CONFIG_IOP3XX_ATU=y
 
 #
 # IOP33x Implementation Options
@@ -151,14 +193,6 @@ CONFIG_IOP3XX_ATU=y
 #
 CONFIG_ARCH_IQ80331=y
 CONFIG_MACH_IQ80332=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
 CONFIG_PLAT_IOP=y
 
 #
@@ -168,6 +202,7 @@ CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
 CONFIG_CPU_CP15=y
@@ -178,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
 #
 # CONFIG_ARM_THUMB is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
 # CONFIG_IWMMXT is not set
 CONFIG_XSCALE_PMU=y
 
@@ -190,40 +224,54 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 
 #
 # Kernel Features
 #
-# CONFIG_TICK_ONESHOT is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
 # CONFIG_AEABI is not set
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc iop3xx_init_atu=y"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
 #
 # Floating point emulation
 #
@@ -239,6 +287,8 @@ CONFIG_FPE_NWFPE=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
 CONFIG_BINFMT_AOUT=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_ARTHUR is not set
@@ -247,11 +297,7 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 # CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-
-#
-# Networking
-#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
 #
@@ -264,6 +310,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -310,6 +357,7 @@ CONFIG_IPV6=y
 # CONFIG_IPV6_SIT is not set
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -317,6 +365,7 @@ CONFIG_IPV6=y
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -326,24 +375,31 @@ CONFIG_IPV6=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -357,7 +413,9 @@ CONFIG_IPV6=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -366,12 +424,14 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
 CONFIG_MTD_REDBOOT_PARTS_READONLY=y
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -421,9 +481,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
@@ -446,6 +504,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -463,14 +526,29 @@ CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -492,10 +570,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -512,6 +586,8 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -520,13 +596,18 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
@@ -543,15 +624,18 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=y
-# CONFIG_MD_RAID5_RESHAPE is not set
+CONFIG_MD_RAID6_PQ=y
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
@@ -568,27 +652,34 @@ CONFIG_BLK_DEV_DM=y
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 # CONFIG_NET_ETHERNET is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
-CONFIG_E1000_NAPI=y
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -596,23 +687,34 @@ CONFIG_E1000_NAPI=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -620,13 +722,16 @@ CONFIG_NETDEV_10000=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -670,10 +775,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -692,11 +800,12 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -705,16 +814,14 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# PC SMBus host controller drivers
 #
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
@@ -722,50 +829,82 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
-CONFIG_I2C_IOP3XX=y
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IOP3XX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
 
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
 
 #
-# SPI support
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -773,13 +912,17 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -794,16 +937,23 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -812,28 +962,38 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -854,15 +1014,16 @@ CONFIG_DAB=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -870,14 +1031,21 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
@@ -893,6 +1061,12 @@ CONFIG_DMA_ENGINE=y
 # DMA Clients
 #
 CONFIG_NET_DMA=y
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -901,10 +1075,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
@@ -913,16 +1088,22 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -941,15 +1122,13 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -959,29 +1138,31 @@ CONFIG_TMPFS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1013,9 +1194,6 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -1023,6 +1201,7 @@ CONFIG_INSTRUMENTATION=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
@@ -1030,10 +1209,17 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1047,16 +1233,41 @@ CONFIG_SCHED_DEBUG=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_FORCED_INLINING is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
 
@@ -1065,24 +1276,117 @@ CONFIG_DEBUG_LL=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
 CONFIG_ASYNC_XOR=y
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
+CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 # CONFIG_CRC32 is not set
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index a0e39d5d00c936a68ac4f99ca9a9b6559b61854f..234a3fc1c78ee43357dba69b4c850aa73c819541 100644 (file)
 #endif
 
 /*
- * Prefetch abort handler.  If the CPU has an IFAR use that, otherwise
- * use the address of the aborted instruction
+ *     Prefetch Abort Model
+ *     ================
+ *
+ *     We have the following to choose from:
+ *       legacy        - no IFSR, no IFAR
+ *       v6            - ARMv6: IFSR, no IFAR
+ *       v7            - ARMv7: IFSR and IFAR
  */
+
 #undef CPU_PABORT_HANDLER
 #undef MULTI_PABORT
 
-#ifdef CONFIG_CPU_PABRT_IFAR
+#ifdef CONFIG_CPU_PABRT_LEGACY
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER legacy_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V6
 # ifdef CPU_PABORT_HANDLER
 #  define MULTI_PABORT 1
 # else
-#  define CPU_PABORT_HANDLER(reg, insn)        mrc p15, 0, reg, cr6, cr0, 2
+#  define CPU_PABORT_HANDLER v6_pabort
 # endif
 #endif
 
-#ifdef CONFIG_CPU_PABRT_NOIFAR
+#ifdef CONFIG_CPU_PABRT_V7
 # ifdef CPU_PABORT_HANDLER
 #  define MULTI_PABORT 1
 # else
-#  define CPU_PABORT_HANDLER(reg, insn)        mov reg, insn
+#  define CPU_PABORT_HANDLER v7_pabort
 # endif
 #endif
 
index 4b8e7f559929970b739af0f080b67a6c16247602..8d60ad267e3a0ab244f05866da614b13aeb4d05d 100644 (file)
@@ -215,6 +215,7 @@ extern int iop3xx_get_init_atu(void);
  * IOP3XX I/O and Mem space regions for PCI autoconfiguration
  */
 #define IOP3XX_PCI_LOWER_MEM_PA        0x80000000
+#define IOP3XX_PCI_MEM_WINDOW_SIZE     0x08000000
 
 #define IOP3XX_PCI_IO_WINDOW_SIZE      0x00010000
 #define IOP3XX_PCI_LOWER_IO_PA         0x90000000
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
new file mode 100644 (file)
index 0000000..59303e2
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * ARM specific SMP header, this contains our implementation
+ * details.
+ */
+#ifndef __ASMARM_SMP_PLAT_H
+#define __ASMARM_SMP_PLAT_H
+
+#include <asm/cputype.h>
+
+/* all SMP configurations have the extended CPUID registers */
+static inline int tlb_ops_need_broadcast(void)
+{
+       return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
+}
+
+#endif
index 89f7eade20af86bda34d943963cef49d17b312f1..7020217fc49fb3919fda1bba63a7491c7b2dc85f 100644 (file)
  * Unimplemented (or alternatively implemented) syscalls
  */
 #define __IGNORE_fadvise64_64          1
+#define __IGNORE_migrate_pages         1
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_UNISTD_H */
index 0a2ba51cf35df1602db7d5a692c7c712a4bcf0d3..322410be573ca027bd8e03da67e134492423974d 100644 (file)
@@ -311,22 +311,16 @@ __pabt_svc:
        tst     r3, #PSR_I_BIT
        biceq   r9, r9, #PSR_I_BIT
 
-       @
-       @ set args, then call main handler
-       @
-       @  r0 - address of faulting instruction
-       @  r1 - pointer to registers on stack
-       @
-#ifdef MULTI_PABORT
        mov     r0, r2                  @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
        ldr     r4, .LCprocfns
        mov     lr, pc
        ldr     pc, [r4, #PROCESSOR_PABT_FUNC]
 #else
-       CPU_PABORT_HANDLER(r0, r2)
+       bl      CPU_PABORT_HANDLER
 #endif
        msr     cpsr_c, r9                      @ Maybe enable interrupts
-       mov     r1, sp                          @ regs
+       mov     r2, sp                          @ regs
        bl      do_PrefetchAbort                @ call abort handler
 
        @
@@ -701,16 +695,16 @@ ENDPROC(__und_usr_unknown)
 __pabt_usr:
        usr_entry
 
-#ifdef MULTI_PABORT
        mov     r0, r2                  @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
        ldr     r4, .LCprocfns
        mov     lr, pc
        ldr     pc, [r4, #PROCESSOR_PABT_FUNC]
 #else
-       CPU_PABORT_HANDLER(r0, r2)
+       bl      CPU_PABORT_HANDLER
 #endif
        enable_irq                              @ Enable interrupts
-       mov     r1, sp                          @ regs
+       mov     r2, sp                          @ regs
        bl      do_PrefetchAbort                @ call abort handler
  UNWIND(.fnend         )
        /* fall through */
index 807cfebb0f44486d5b19b7869cf3b155e630ac7e..f0fe95b7085d8020682b297915ba1910af476828 100644 (file)
@@ -126,7 +126,7 @@ ENTRY(__gnu_mcount_nc)
        cmp r0, r2
        bne gnu_trace
        ldmia sp!, {r0-r3, ip, lr}
-       bx ip
+       mov pc, ip
 
 gnu_trace:
        ldr r1, [sp, #20]                       @ lr of instrumented routine
@@ -135,7 +135,7 @@ gnu_trace:
        mov lr, pc
        mov pc, r2
        ldmia sp!, {r0-r3, ip, lr}
-       bx ip
+       mov pc, ip
 
 ENTRY(mcount)
        stmdb sp!, {r0-r3, lr}
@@ -425,13 +425,6 @@ sys_mmap2:
 #endif
 ENDPROC(sys_mmap2)
 
-ENTRY(pabort_ifar)
-               mrc     p15, 0, r0, cr6, cr0, 2
-ENTRY(pabort_noifar)
-               mov     pc, lr
-ENDPROC(pabort_ifar)
-ENDPROC(pabort_noifar)
-
 #ifdef CONFIG_OABI_COMPAT
 
 /*
index 93ad576b2d74b311331542f6a79fc4054a0306d8..885a7214418d81877d3cec0eb2f3c4d2f0d07133 100644 (file)
@@ -13,6 +13,7 @@
 
 #define ATAG_CORE 0x54410001
 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
+#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
 
        .align  2
        .type   __switch_data, %object
@@ -251,7 +252,8 @@ __vet_atags:
        bne     1f
 
        ldr     r5, [r2, #0]                    @ is first tag ATAG_CORE?
-       subs    r5, r5, #ATAG_CORE_SIZE
+       cmp     r5, #ATAG_CORE_SIZE
+       cmpne   r5, #ATAG_CORE_SIZE_EMPTY
        bne     1f
        ldr     r5, [r2, #4]
        ldr     r6, =ATAG_CORE
index e0d32770bb3d51c061554ba348c9c69beffd25ea..57162af53dc982cc0911e09537915eb1eddc1cbb 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
 #include <asm/localtimer.h>
+#include <asm/smp_plat.h>
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
@@ -153,7 +154,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 /*
  * __cpu_disable runs on the processor to be shutdown.
  */
-int __cpuexit __cpu_disable(void)
+int __cpu_disable(void)
 {
        unsigned int cpu = smp_processor_id();
        struct task_struct *p;
@@ -200,7 +201,7 @@ int __cpuexit __cpu_disable(void)
  * called on the thread which is asking for a CPU to be shutdown -
  * waits until shutdown has completed, or it is timed out.
  */
-void __cpuexit __cpu_die(unsigned int cpu)
+void __cpu_die(unsigned int cpu)
 {
        if (!platform_cpu_kill(cpu))
                printk("CPU%u: unable to kill\n", cpu);
@@ -214,7 +215,7 @@ void __cpuexit __cpu_die(unsigned int cpu)
  * of the other hotplug-cpu capable cores, so presumably coming
  * out of idle fixes this.
  */
-void __cpuexit cpu_die(void)
+void __ref cpu_die(void)
 {
        unsigned int cpu = smp_processor_id();
 
@@ -586,12 +587,6 @@ struct tlb_args {
        unsigned long ta_end;
 };
 
-/* all SMP configurations have the extended CPUID registers */
-static inline int tlb_ops_need_broadcast(void)
-{
-       return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
-}
-
 static inline void ipi_flush_tlb_all(void *ignored)
 {
        local_flush_tlb_all();
index d8c88c633c6f0a880f5015992be409ffa68226de..a73a34dccf2a6de247f20bb5fc4e9622b03561a1 100644 (file)
@@ -166,10 +166,12 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
        clockevents_register_device(clk);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * take a local timer down
  */
-void __cpuexit twd_timer_stop(void)
+void twd_timer_stop(void)
 {
        __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
 }
+#endif
index 57eb0f6f60053e6fd12fd48113e8a5fdb6b744b8..467b69ed1021b39fb87848b4009edfef9fb9f1d2 100644 (file)
@@ -418,12 +418,14 @@ static int bad_syscall(int n, struct pt_regs *regs)
 static inline void
 do_cache_op(unsigned long start, unsigned long end, int flags)
 {
+       struct mm_struct *mm = current->active_mm;
        struct vm_area_struct *vma;
 
        if (end < start || flags)
                return;
 
-       vma = find_vma(current->active_mm, start);
+       down_read(&mm->mmap_sem);
+       vma = find_vma(mm, start);
        if (vma && vma->vm_start < end) {
                if (start < vma->vm_start)
                        start = vma->vm_start;
@@ -432,6 +434,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
 
                flush_cache_user_range(vma, start, end);
        }
+       up_read(&mm->mmap_sem);
 }
 
 /*
index 492c649f451ec357089b0dce22408d66788e0f8e..4b4f69251b313a07676a6dcef5b19418c9c3c379 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 
-#include <linux/amba/bus.h>
 #include <mach/csp/mm_addr.h>
 #include <mach/hardware.h>
 #include <asm/clkdev.h>
@@ -45,7 +44,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <asm/mach/mmc.h>
 
 #include <cfg_global.h>
 
index a1d5e7dac741004b076a416ac271f60aac921b30..52dd8046b3051eb05fefd2140586e3f19f9182a2 100644 (file)
@@ -35,7 +35,6 @@
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
-#include <mach/common.h>
 #include <mach/mmc.h>
 #include <mach/nand.h>
 
index f1d72b225450951022aada4f49a50a46fb13d6cc..901cc205015e81a4149a4f56e87e056fe372951f 100644 (file)
@@ -486,7 +486,7 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
        return ret;
 }
 
-struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
+struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
 {
        return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
 }
index abd9eb49f1033773dd0ca92cb02b7ce51842cda6..941f363aca56411bb26505bb776ceb3772dbbfe9 100644 (file)
@@ -31,7 +31,5 @@
 #define IOP32X_MAX_RAM_SIZE            0x40000000UL
 #define IOP3XX_MAX_RAM_SIZE            IOP32X_MAX_RAM_SIZE
 #define IOP3XX_PCI_LOWER_MEM_BA        0x80000000
-#define IOP32X_PCI_MEM_WINDOW_SIZE     0x04000000
-#define IOP3XX_PCI_MEM_WINDOW_SIZE     IOP32X_PCI_MEM_WINDOW_SIZE
 
 #endif
index 24567316ec88cc01646f61422b9bb47d2820dc57..a89c0a234bffff05baee92e08eb23e6a703a0103 100644 (file)
@@ -36,8 +36,6 @@
 #define IOP33X_MAX_RAM_SIZE            0x80000000UL
 #define IOP3XX_MAX_RAM_SIZE            IOP33X_MAX_RAM_SIZE
 #define IOP3XX_PCI_LOWER_MEM_BA        (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE)
-#define IOP33X_PCI_MEM_WINDOW_SIZE     0x08000000
-#define IOP3XX_PCI_MEM_WINDOW_SIZE     IOP33X_PCI_MEM_WINDOW_SIZE
 
 
 #endif
index 44ed20d4a388a718bad140aeeabbfaeb70a1a04e..cf81cbc57544552970e88986efed07ad71f5c336 100644 (file)
@@ -195,7 +195,7 @@ static int clk_debugfs_open(struct inode *inode, struct file *file)
        return single_open(file, clk_debugfs_show, NULL);
 }
 
-static struct file_operations clk_debugfs_operations = {
+static const struct file_operations clk_debugfs_operations = {
        .open = clk_debugfs_open,
        .read = seq_read,
        .llseek = seq_lseek,
index 81ffff7ed498a1633dac73b69b088d5a3e64acc1..4e5c07f4e45654368e362a20794daa4c4c3709af 100644 (file)
@@ -71,11 +71,6 @@ config SA1100_H3600
          <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
          <http://www.compaq.com/products/handhelds/pocketpc/>
 
-config SA1100_H3XXX
-       bool
-       depends on SA1100_H3100 || SA1100_H3600
-       default y
-
 config SA1100_BADGE4
        bool "HP Labs BadgePAD 4"
        select SA1111
index 95d92e8e56a81c820979d373cd87e4d152b09235..b9cbb56d6e9d9dbd9c7605196488b0872fd8bc4d 100644 (file)
@@ -77,7 +77,7 @@ static struct clock_event_device ckevt_sa1100_osmr0 = {
        .set_mode       = sa1100_osmr0_set_mode,
 };
 
-static cycle_t sa1100_read_oscr(void)
+static cycle_t sa1100_read_oscr(struct clocksource *s)
 {
        return OSCR;
 }
index 63c8f27fb15a3bc6a5eba1ec4bb8742f02275081..0b35826b7d1d419a5daf875cdf1cfc215fac726c 100644 (file)
@@ -281,6 +281,16 @@ int gpio_unregister_callback(unsigned gpio)
 }
 EXPORT_SYMBOL(gpio_unregister_callback);
 
+/* Non-zero means valid */
+int gpio_is_valid(int number)
+{
+       if (number >= 0 &&
+           number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
+               return 1;
+       return 0;
+}
+EXPORT_SYMBOL(gpio_is_valid);
+
 int gpio_request(unsigned gpio, const char *label)
 {
        if (gpio_pin[gpio].users)
index c8174128d7ebc167ec0e700894348b5f33ab9029..7b1fc984abb64c85dd3124eba6b6b108000835b9 100644 (file)
 #define PIN_TO_PORT(val) (val >> 3)
 
 /* These can be found in arch/arm/mach-u300/gpio.c */
+extern int gpio_is_valid(int number);
 extern int gpio_request(unsigned gpio, const char *label);
 extern void gpio_free(unsigned gpio);
 extern int gpio_direction_input(unsigned gpio);
index 8d43e58f9244349601d6001ec6332d6909634017..e993140edd880e3f62be0eed4d6851f5496375ab 100644 (file)
@@ -17,7 +17,7 @@ config CPU_ARM610
        select CPU_CP15_MMU
        select CPU_COPY_V3 if MMU
        select CPU_TLB_V3 if MMU
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        help
          The ARM610 is the successor to the ARM3 processor
          and was produced by VLSI Technology Inc.
@@ -31,7 +31,7 @@ config CPU_ARM7TDMI
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_LV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4
        help
          A 32-bit RISC microprocessor based on the ARM7 processor core
@@ -49,7 +49,7 @@ config CPU_ARM710
        select CPU_CP15_MMU
        select CPU_COPY_V3 if MMU
        select CPU_TLB_V3 if MMU
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        help
          A 32-bit RISC microprocessor based on the ARM7 processor core
          designed by Advanced RISC Machines Ltd. The ARM710 is the
@@ -64,7 +64,7 @@ config CPU_ARM720T
        bool "Support ARM720T processor" if ARCH_INTEGRATOR
        select CPU_32v4T
        select CPU_ABRT_LV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -83,7 +83,7 @@ config CPU_ARM740T
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_LV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V3     # although the core is v4t
        select CPU_CP15_MPU
        help
@@ -100,7 +100,7 @@ config CPU_ARM9TDMI
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_NOMMU
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4
        help
          A 32-bit RISC microprocessor based on the ARM9 processor core
@@ -114,7 +114,7 @@ config CPU_ARM920T
        bool "Support ARM920T processor" if ARCH_INTEGRATOR
        select CPU_32v4T
        select CPU_ABRT_EV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -135,7 +135,7 @@ config CPU_ARM922T
        bool "Support ARM922T processor" if ARCH_INTEGRATOR
        select CPU_32v4T
        select CPU_ABRT_EV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -154,7 +154,7 @@ config CPU_ARM925T
        bool "Support ARM925T processor" if ARCH_OMAP1
        select CPU_32v4T
        select CPU_ABRT_EV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -173,7 +173,7 @@ config CPU_ARM926T
        bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
        select CPU_32v5
        select CPU_ABRT_EV5TJ
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
@@ -191,7 +191,7 @@ config CPU_FA526
        bool
        select CPU_32v4
        select CPU_ABRT_EV4
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_CACHE_FA
@@ -210,7 +210,7 @@ config CPU_ARM940T
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_NOMMU
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MPU
        help
@@ -228,7 +228,7 @@ config CPU_ARM946E
        depends on !MMU
        select CPU_32v5
        select CPU_ABRT_NOMMU
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MPU
        help
@@ -244,7 +244,7 @@ config CPU_ARM1020
        bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR
        select CPU_32v5
        select CPU_ABRT_EV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -262,7 +262,7 @@ config CPU_ARM1020E
        bool "Support ARM1020E processor" if ARCH_INTEGRATOR
        select CPU_32v5
        select CPU_ABRT_EV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -275,7 +275,7 @@ config CPU_ARM1022
        bool "Support ARM1022E processor" if ARCH_INTEGRATOR
        select CPU_32v5
        select CPU_ABRT_EV4T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU # can probably do better
@@ -293,7 +293,7 @@ config CPU_ARM1026
        bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR
        select CPU_32v5
        select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU # can probably do better
@@ -311,7 +311,7 @@ config CPU_SA110
        select CPU_32v3 if ARCH_RPC
        select CPU_32v4 if !ARCH_RPC
        select CPU_ABRT_EV4
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WB
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -331,7 +331,7 @@ config CPU_SA1100
        bool
        select CPU_32v4
        select CPU_ABRT_EV4
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_V4WB
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
@@ -342,7 +342,7 @@ config CPU_XSCALE
        bool
        select CPU_32v5
        select CPU_ABRT_EV5T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_TLB_V4WBI if MMU
@@ -352,7 +352,7 @@ config CPU_XSC3
        bool
        select CPU_32v5
        select CPU_ABRT_EV5T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_TLB_V4WBI if MMU
@@ -363,7 +363,7 @@ config CPU_MOHAWK
        bool
        select CPU_32v5
        select CPU_ABRT_EV5T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_TLB_V4WBI if MMU
@@ -374,7 +374,7 @@ config CPU_FEROCEON
        bool
        select CPU_32v5
        select CPU_ABRT_EV5T
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_LEGACY
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_COPY_FEROCEON if MMU
@@ -394,7 +394,7 @@ config CPU_V6
        bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
        select CPU_32v6
        select CPU_ABRT_EV6
-       select CPU_PABRT_NOIFAR
+       select CPU_PABRT_V6
        select CPU_CACHE_V6
        select CPU_CACHE_VIPT
        select CPU_CP15_MMU
@@ -420,7 +420,7 @@ config CPU_V7
        select CPU_32v6K
        select CPU_32v7
        select CPU_ABRT_EV7
-       select CPU_PABRT_IFAR
+       select CPU_PABRT_V7
        select CPU_CACHE_V7
        select CPU_CACHE_VIPT
        select CPU_CP15_MMU
@@ -482,10 +482,13 @@ config CPU_ABRT_EV6
 config CPU_ABRT_EV7
        bool
 
-config CPU_PABRT_IFAR
+config CPU_PABRT_LEGACY
        bool
 
-config CPU_PABRT_NOIFAR
+config CPU_PABRT_V6
+       bool
+
+config CPU_PABRT_V7
        bool
 
 # The cache model
index 63e3f6dd0e2196f96eed8be436e6cc287234b72f..055cb2aa8134c63fba47cdfbc6192e3ec3ffd2f6 100644 (file)
@@ -27,6 +27,10 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
 obj-$(CONFIG_CPU_ABRT_EV6)     += abort-ev6.o
 obj-$(CONFIG_CPU_ABRT_EV7)     += abort-ev7.o
 
+obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o
+obj-$(CONFIG_CPU_PABRT_V6)     += pabort-v6.o
+obj-$(CONFIG_CPU_PABRT_V7)     += pabort-v7.o
+
 obj-$(CONFIG_CPU_CACHE_V3)     += cache-v3.o
 obj-$(CONFIG_CPU_CACHE_V4)     += cache-v4.o
 obj-$(CONFIG_CPU_CACHE_V4WT)   += cache-v4wt.o
index 379f7855605554c9ae955cf7ffe44964374f297e..ae0e25f5a70eb57987c131f5fbfd4fe795df3302 100644 (file)
@@ -519,9 +519,58 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        arm_notify_die("", regs, &info, fsr, 0);
 }
 
+
+static struct fsr_info ifsr_info[] = {
+       { do_bad,               SIGBUS,  0,             "unknown 0"                        },
+       { do_bad,               SIGBUS,  0,             "unknown 1"                        },
+       { do_bad,               SIGBUS,  0,             "debug event"                      },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "section access flag fault"        },
+       { do_bad,               SIGBUS,  0,             "unknown 4"                        },
+       { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "section translation fault"        },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "page access flag fault"           },
+       { do_page_fault,        SIGSEGV, SEGV_MAPERR,   "page translation fault"           },
+       { do_bad,               SIGBUS,  0,             "external abort on non-linefetch"  },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "section domain fault"             },
+       { do_bad,               SIGBUS,  0,             "unknown 10"                       },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "page domain fault"                },
+       { do_bad,               SIGBUS,  0,             "external abort on translation"    },
+       { do_sect_fault,        SIGSEGV, SEGV_ACCERR,   "section permission fault"         },
+       { do_bad,               SIGBUS,  0,             "external abort on translation"    },
+       { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "page permission fault"            },
+       { do_bad,               SIGBUS,  0,             "unknown 16"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 17"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 18"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 19"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 20"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 21"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 22"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 23"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 24"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 25"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 26"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 27"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 28"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 29"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 30"                       },
+       { do_bad,               SIGBUS,  0,             "unknown 31"                       },
+};
+
 asmlinkage void __exception
-do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
 {
-       do_translation_fault(addr, FSR_LNX_PF, regs);
+       const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+       struct siginfo info;
+
+       if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+               return;
+
+       printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
+               inf->name, ifsr, addr);
+
+       info.si_signo = inf->sig;
+       info.si_errno = 0;
+       info.si_code  = inf->code;
+       info.si_addr  = (void __user *)addr;
+       arm_notify_die("", regs, &info, ifsr, 0);
 }
 
index f7457fea6de8e84c5aefe949412845550b1bfa5e..2b7996401b0f9f602dfa2d809f86e40b57f79117 100644 (file)
@@ -124,7 +124,7 @@ int valid_phys_addr_range(unsigned long addr, size_t size)
 {
        if (addr < PHYS_OFFSET)
                return 0;
-       if (addr + size >= __pa(high_memory - 1))
+       if (addr + size > __pa(high_memory - 1) + 1)
                return 0;
 
        return 1;
index 4426ee67ceca5d3d74c9b0dbe0f39c5b7e2b8538..02243eeccf50d79b9175e085fa77069a3f349862 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/cachetype.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
+#include <asm/smp_plat.h>
 #include <asm/tlb.h>
 #include <asm/highmem.h>
 
@@ -709,10 +710,6 @@ static void __init sanity_check_meminfo(void)
                        if (meminfo.nr_banks >= NR_BANKS) {
                                printk(KERN_CRIT "NR_BANKS too low, "
                                                 "ignoring high memory\n");
-                       } else if (cache_is_vipt_aliasing()) {
-                               printk(KERN_CRIT "HIGHMEM is not yet supported "
-                                                "with VIPT aliasing cache, "
-                                                "ignoring high memory\n");
                        } else {
                                memmove(bank + 1, bank,
                                        (meminfo.nr_banks - i) * sizeof(*bank));
@@ -726,6 +723,8 @@ static void __init sanity_check_meminfo(void)
                        bank->size = VMALLOC_MIN - __va(bank->start);
                }
 #else
+               bank->highmem = highmem;
+
                /*
                 * Check whether this memory bank would entirely overlap
                 * the vmalloc area.
@@ -754,6 +753,38 @@ static void __init sanity_check_meminfo(void)
 #endif
                j++;
        }
+#ifdef CONFIG_HIGHMEM
+       if (highmem) {
+               const char *reason = NULL;
+
+               if (cache_is_vipt_aliasing()) {
+                       /*
+                        * Interactions between kmap and other mappings
+                        * make highmem support with aliasing VIPT caches
+                        * rather difficult.
+                        */
+                       reason = "with VIPT aliasing cache";
+#ifdef CONFIG_SMP
+               } else if (tlb_ops_need_broadcast()) {
+                       /*
+                        * kmap_high needs to occasionally flush TLB entries,
+                        * however, if the TLB entries need to be broadcast
+                        * we may deadlock:
+                        *  kmap_high(irqs off)->flush_all_zero_pkmaps->
+                        *  flush_tlb_kernel_range->smp_call_function_many
+                        *   (must not be called with irqs off)
+                        */
+                       reason = "without hardware TLB ops broadcasting";
+#endif
+               }
+               if (reason) {
+                       printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
+                               reason);
+                       while (j > 0 && meminfo.bank[j - 1].highmem)
+                               j--;
+               }
+       }
+#endif
        meminfo.nr_banks = j;
 }
 
diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S
new file mode 100644 (file)
index 0000000..87970eb
--- /dev/null
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: legacy_pabort
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *        : r1 = Simulated IFSR with section translation fault status
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+       .align  5
+ENTRY(legacy_pabort)
+       mov     r1, #5
+       mov     pc, lr
+ENDPROC(legacy_pabort)
diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S
new file mode 100644 (file)
index 0000000..06e3d1e
--- /dev/null
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *        : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+       .align  5
+ENTRY(v6_pabort)
+       mrc     p15, 0, r1, c5, c0, 1           @ get IFSR
+       mov     pc, lr
+ENDPROC(v6_pabort)
diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S
new file mode 100644 (file)
index 0000000..a8b3b30
--- /dev/null
@@ -0,0 +1,20 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *        : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+       .align  5
+ENTRY(v7_pabort)
+       mrc     p15, 0, r0, c6, c0, 2           @ get IFAR
+       mrc     p15, 0, r1, c5, c0, 1           @ get IFSR
+       mov     pc, lr
+ENDPROC(v7_pabort)
index b5551bf010aa33668d938e09d184d3df2bc1ec5d..d9fb4b98c49ff8866a1d36288d431ce364ad1180 100644 (file)
@@ -449,7 +449,7 @@ arm1020_crval:
        .type   arm1020_processor_functions, #object
 arm1020_processor_functions:
        .word   v4t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm1020_proc_init
        .word   cpu_arm1020_proc_fin
        .word   cpu_arm1020_reset
index 8bc6740c29eb68d8bcfdb97111281ecca87e0f41..7453b75dcea5f1527790e940263f113a70aec417 100644 (file)
@@ -430,7 +430,7 @@ arm1020e_crval:
        .type   arm1020e_processor_functions, #object
 arm1020e_processor_functions:
        .word   v4t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm1020e_proc_init
        .word   cpu_arm1020e_proc_fin
        .word   cpu_arm1020e_reset
index 2cd03e66c0a318f9b28c14bdf0749571604de303..8eb72d75a8b6fe2757e0c6c8bcfa7325519c2a11 100644 (file)
@@ -413,7 +413,7 @@ arm1022_crval:
        .type   arm1022_processor_functions, #object
 arm1022_processor_functions:
        .word   v4t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm1022_proc_init
        .word   cpu_arm1022_proc_fin
        .word   cpu_arm1022_reset
index ad961a897f6eae5cfad3d3bee1fc6fcd0d8d865f..3b59f0d6713962d3e83222d1d05dc2c10606157c 100644 (file)
@@ -408,7 +408,7 @@ arm1026_crval:
        .type   arm1026_processor_functions, #object
 arm1026_processor_functions:
        .word   v5t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm1026_proc_init
        .word   cpu_arm1026_proc_fin
        .word   cpu_arm1026_reset
index 80d6e1de069ada45c74cf6b665b91292d5990019..3f9cd3d8f6d508c447e46c5cf29ca078dd1b630b 100644 (file)
@@ -278,7 +278,7 @@ __arm7_setup:       mov     r0, #0
                .type   arm6_processor_functions, #object
 ENTRY(arm6_processor_functions)
                .word   cpu_arm6_data_abort
-               .word   pabort_noifar
+               .word   legacy_pabort
                .word   cpu_arm6_proc_init
                .word   cpu_arm6_proc_fin
                .word   cpu_arm6_reset
@@ -295,7 +295,7 @@ ENTRY(arm6_processor_functions)
                .type   arm7_processor_functions, #object
 ENTRY(arm7_processor_functions)
                .word   cpu_arm7_data_abort
-               .word   pabort_noifar
+               .word   legacy_pabort
                .word   cpu_arm7_proc_init
                .word   cpu_arm7_proc_fin
                .word   cpu_arm7_reset
index 85ae18695f1021a4cf2299fbcad8f382b9f7c03d..0b62de24466646d8b7e8aa65b84e8ac5191335f5 100644 (file)
@@ -181,7 +181,7 @@ arm720_crval:
                .type   arm720_processor_functions, #object
 ENTRY(arm720_processor_functions)
                .word   v4t_late_abort
-               .word   pabort_noifar
+               .word   legacy_pabort
                .word   cpu_arm720_proc_init
                .word   cpu_arm720_proc_fin
                .word   cpu_arm720_reset
index 4f95bee63e95c0454cc1fc9224a686316db37368..01860cdeb2ec3df451947f325c7d132449820717 100644 (file)
@@ -126,7 +126,7 @@ __arm740_setup:
        .type   arm740_processor_functions, #object
 ENTRY(arm740_processor_functions)
        .word   v4t_late_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm740_proc_init
        .word   cpu_arm740_proc_fin
        .word   cpu_arm740_reset
index 93e05fa7bed44933341d6d4c42db7655b6fafb15..1201b98638298087063d3ec02eefd3a7e58d9aa6 100644 (file)
@@ -64,7 +64,7 @@ __arm7tdmi_setup:
                .type   arm7tdmi_processor_functions, #object
 ENTRY(arm7tdmi_processor_functions)
                .word   v4t_late_abort
-               .word   pabort_noifar
+               .word   legacy_pabort
                .word   cpu_arm7tdmi_proc_init
                .word   cpu_arm7tdmi_proc_fin
                .word   cpu_arm7tdmi_reset
index 914d688394fc150f26c9e4987542dae74a24205a..2b7c197cc58d2ab4babcf39920220b96a973570e 100644 (file)
@@ -395,7 +395,7 @@ arm920_crval:
        .type   arm920_processor_functions, #object
 arm920_processor_functions:
        .word   v4t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm920_proc_init
        .word   cpu_arm920_proc_fin
        .word   cpu_arm920_reset
index 51c9c9859e58475232851e89c7fa032af52d72ad..06a1aa4e33989976465155586fe0390e19109bb9 100644 (file)
@@ -399,7 +399,7 @@ arm922_crval:
        .type   arm922_processor_functions, #object
 arm922_processor_functions:
        .word   v4t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm922_proc_init
        .word   cpu_arm922_proc_fin
        .word   cpu_arm922_reset
index 2724526d89c1ccb302055ebf0ef52378497189bc..cb53435a85aee2120f2e97f6b01c24561f32e860 100644 (file)
@@ -462,7 +462,7 @@ arm925_crval:
        .type   arm925_processor_functions, #object
 arm925_processor_functions:
        .word   v4t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm925_proc_init
        .word   cpu_arm925_proc_fin
        .word   cpu_arm925_reset
index 54466937bff994ea288ba5ece9c7c39ddacecbd8..1c4848704bb358c98a0e4c87141f7326e802d3fb 100644 (file)
@@ -415,7 +415,7 @@ arm926_crval:
        .type   arm926_processor_functions, #object
 arm926_processor_functions:
        .word   v5tj_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm926_proc_init
        .word   cpu_arm926_proc_fin
        .word   cpu_arm926_reset
index f595117caf55bb7db716b29e477c7c0f9f49bb95..5b0f8464c8f29f9cc908cd2bbff5a820652f7751 100644 (file)
@@ -322,7 +322,7 @@ __arm940_setup:
        .type   arm940_processor_functions, #object
 ENTRY(arm940_processor_functions)
        .word   nommu_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm940_proc_init
        .word   cpu_arm940_proc_fin
        .word   cpu_arm940_reset
index e03f6ff1fb2631284176fd5cc08c164f592a6f4d..40c0449a139b829a709525984442b36561494e13 100644 (file)
@@ -377,7 +377,7 @@ __arm946_setup:
        .type   arm946_processor_functions, #object
 ENTRY(arm946_processor_functions)
        .word   nommu_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_arm946_proc_init
        .word   cpu_arm946_proc_fin
        .word   cpu_arm946_reset
index be6c11d2b3fbf10092be644df37aba7787387004..28545c29dbcda317db178a564a7a894f3a846f96 100644 (file)
@@ -64,7 +64,7 @@ __arm9tdmi_setup:
                .type   arm9tdmi_processor_functions, #object
 ENTRY(arm9tdmi_processor_functions)
                .word   nommu_early_abort
-               .word   pabort_noifar
+               .word   legacy_pabort
                .word   cpu_arm9tdmi_proc_init
                .word   cpu_arm9tdmi_proc_fin
                .word   cpu_arm9tdmi_reset
index 08b8a955d5d7843baad616afd342707714160a0b..08f5ac237ad4e83e67b7540a9680d28c619edc41 100644 (file)
@@ -191,7 +191,7 @@ fa526_cr1_set:
        .type   fa526_processor_functions, #object
 fa526_processor_functions:
        .word   v4_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_fa526_proc_init
        .word   cpu_fa526_proc_fin
        .word   cpu_fa526_reset
index 0fe1f8fc348802777a02e42da50c58f56e2a2d9e..d0d7795200fc143a0362312c960f334deb5f1957 100644 (file)
@@ -499,7 +499,7 @@ feroceon_crval:
        .type   feroceon_processor_functions, #object
 feroceon_processor_functions:
        .word   v5t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_feroceon_proc_init
        .word   cpu_feroceon_proc_fin
        .word   cpu_feroceon_reset
index 540f5078496ba155e2cc91c3656097ebaddd9c0e..52b5fd74fbb3fcbfe3295d570a2e121001318562 100644 (file)
@@ -359,7 +359,7 @@ mohawk_crval:
        .type   mohawk_processor_functions, #object
 mohawk_processor_functions:
        .word   v5t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_mohawk_proc_init
        .word   cpu_mohawk_proc_fin
        .word   cpu_mohawk_reset
index 90a7e5279f296c1193cc0a389c9b9d8b1f272186..7b706b38990625c08ca3595ff19b6657fcbb0648 100644 (file)
@@ -199,7 +199,7 @@ sa110_crval:
        .type   sa110_processor_functions, #object
 ENTRY(sa110_processor_functions)
        .word   v4_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_sa110_proc_init
        .word   cpu_sa110_proc_fin
        .word   cpu_sa110_reset
index 451e2d953e2a0389ed462b253ca904053b2b24ff..ee7700242c19567b94ad256984225c66d5e57872 100644 (file)
@@ -214,7 +214,7 @@ sa1100_crval:
        .type   sa1100_processor_functions, #object
 ENTRY(sa1100_processor_functions)
        .word   v4_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_sa1100_proc_init
        .word   cpu_sa1100_proc_fin
        .word   cpu_sa1100_reset
index 524ddae92595052c19ef0e015ab9ed09b24d4026..194737d60a22691c263daf1cba31b0f7ae189e0d 100644 (file)
@@ -191,7 +191,7 @@ v6_crval:
        .type   v6_processor_functions, #object
 ENTRY(v6_processor_functions)
        .word   v6_early_abort
-       .word   pabort_noifar
+       .word   v6_pabort
        .word   cpu_v6_proc_init
        .word   cpu_v6_proc_fin
        .word   cpu_v6_reset
index f3fa1c32fe923cb93f0e73fc14f883182b55df57..23ebcf6eab9f63241e3743170c168e2e38ec0ea2 100644 (file)
@@ -295,7 +295,7 @@ __v7_setup_stack:
        .type   v7_processor_functions, #object
 ENTRY(v7_processor_functions)
        .word   v7_early_abort
-       .word   pabort_ifar
+       .word   v7_pabort
        .word   cpu_v7_proc_init
        .word   cpu_v7_proc_fin
        .word   cpu_v7_reset
index 33515c214b92d5483e7257adf076be3758332993..2028f370288113507d2d5dcfa6e5599629270df5 100644 (file)
@@ -428,7 +428,7 @@ xsc3_crval:
        .type   xsc3_processor_functions, #object
 ENTRY(xsc3_processor_functions)
        .word   v5t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_xsc3_proc_init
        .word   cpu_xsc3_proc_fin
        .word   cpu_xsc3_reset
index 423394260bcbd17fc863deecd225bf85f617025c..f056c283682db09b37b3b282a1cded25d9683367 100644 (file)
@@ -511,7 +511,7 @@ xscale_crval:
        .type   xscale_processor_functions, #object
 ENTRY(xscale_processor_functions)
        .word   v5t_early_abort
-       .word   pabort_noifar
+       .word   legacy_pabort
        .word   cpu_xscale_proc_init
        .word   cpu_xscale_proc_fin
        .word   cpu_xscale_reset
index 77fa7cc7d162dc28b903211ff5c3691e7e613e2e..ce31f316ac75c1e72af3693a58633a10e50e7f7a 100644 (file)
@@ -257,7 +257,8 @@ void __init iop3xx_atu_setup(void)
        *IOP3XX_OUMWTVR0 = 0;
 
        /* Outbound window 1 */
-       *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA + IOP3XX_PCI_MEM_WINDOW_SIZE;
+       *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA +
+                         IOP3XX_PCI_MEM_WINDOW_SIZE / 2;
        *IOP3XX_OUMWTVR1 = 0;
 
        /* BAR 3 ( Disabled ) */
index 3695bbe3ee280960599532b013b9c33c30d3bc69..8da95d57c21f6beef36ce80438c355bc73dbdf6d 100644 (file)
@@ -85,7 +85,7 @@ void __init iop_init_time(unsigned long tick_rate)
 {
        u32 timer_ctl;
 
-       ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
+       ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
        ticks_per_usec = tick_rate / 1000000;
        next_jiffy_time = 0xffffffff;
        iop_tick_rate = tick_rate;
index 2d0852ac3b272d57a66271ce4edee234ccb53e96..c2cef6139683e6c5c68096272feba6fe8f6ee417 100644 (file)
@@ -2,8 +2,11 @@
 #define _ARCH_MCI_H
 
 struct s3c24xx_mci_pdata {
+       unsigned int    no_wprotect : 1;
+       unsigned int    no_detect : 1;
        unsigned int    wprotect_invert : 1;
        unsigned int    detect_invert : 1;   /* set => detect active high. */
+       unsigned int    use_dma : 1;
 
        unsigned int    gpio_detect;
        unsigned int    gpio_wprotect;
index 93635a766f9cded6c93e8cc011e47e35e62da0c1..1e60a92dd6028d21ec02cccf885ee1b8841bf980 100644 (file)
@@ -48,7 +48,7 @@ coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned l
        return ret;
 }
 
-static struct file_operations coreb_fops = {
+static const struct file_operations coreb_fops = {
        .owner   = THIS_MODULE,
        .ioctl   = coreb_ioctl,
 };
index 6cc1a0319a5d89cd6907df11572480675e296195..562b9a7feae776c5f9ef024726e82ff3dc66774a 100644 (file)
@@ -244,7 +244,7 @@ static unsigned sync_serial_prescale_shadow;
 
 #define NUMBER_OF_PORTS 2
 
-static struct file_operations sync_serial_fops = {
+static const struct file_operations sync_serial_fops = {
        .owner   = THIS_MODULE,
        .write   = sync_serial_write,
        .read    = sync_serial_read,
index fe1fde893887ea76f90c699dd180c94625a704b2..d89ab80498edcafa6327bd74d6b0f404f54e5d32 100644 (file)
@@ -855,7 +855,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
        return 0;
 }
 
-struct file_operations gpio_fops = {
+static const struct file_operations gpio_fops = {
        .owner       = THIS_MODULE,
        .poll        = gpio_poll,
        .ioctl       = gpio_ioctl,
index d06933bd631825cfbbb096b92ecd0a166649aedc..4010f1fc5b65ba1fc01217f071d897af5a33c125 100644 (file)
@@ -162,6 +162,13 @@ static inline void _writel(unsigned long l, unsigned long addr)
 #define __raw_writew writew
 #define __raw_writel writel
 
+#define ioread8 read
+#define ioread16 readw
+#define ioread32 readl
+#define iowrite8 writeb
+#define iowrite16 writew
+#define iowrite32 writel
+
 #define mmiowb()
 
 #define flush_write_buffers() do { } while (0)  /* M32R_FIXME */
index 22624b51d4d3ecf3222ce82de0464719bb731d49..700570747a906ce5c3f4eb4218d2301723f5b4a5 100644 (file)
@@ -23,12 +23,6 @@ EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(kernel_thread);
 
-/* Networking helper routines. */
-/* Delay loops */
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(__delay);
-EXPORT_SYMBOL(__const_udelay);
-
 EXPORT_SYMBOL(strncpy_from_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(clear_user);
index ba61c4c73202769f947c87ace55c3d8453b2f336..e7fee0f198d51a22947a7ff4817a6d4e35d27438 100644 (file)
 
 #include <asm/hw_irq.h>
 
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+/* this needs a better home */
+DEFINE_SPINLOCK(rtc_lock);
+
+#ifdef CONFIG_RTC_DRV_CMOS_MODULE
+EXPORT_SYMBOL(rtc_lock);
+#endif
+#endif  /* pc-style 'CMOS' RTC support */
+
 #ifdef CONFIG_SMP
 extern void smp_local_timer_interrupt(void);
 #endif
index 03b14e55cd894791ab25e25fb5bfbc8827baf140..fbd109031df3aca4c83851494044492a0cc20965 100644 (file)
@@ -104,8 +104,8 @@ static void set_eit_vector_entries(void)
        eit_vector[186] = (unsigned long)smp_call_function_interrupt;
        eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
        eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
-       eit_vector[189] = (unsigned long)smp_call_function_single_interrupt;
-       eit_vector[190] = 0;
+       eit_vector[189] = 0;    /* CPU_BOOT_IPI */
+       eit_vector[190] = (unsigned long)smp_call_function_single_interrupt;
        eit_vector[191] = 0;
 #endif
        _flush_cache_copyback_all();
index ced549be80f5e9055528918394caaeca6d04270f..940f4837e42b92a359fe7d56fcdcda555f22e504 100644 (file)
@@ -122,4 +122,8 @@ void __ndelay(unsigned long nsecs)
 {
        __const_udelay(nsecs * 0x00005);  /* 2**32 / 1000000000 (rounded up) */
 }
+
+EXPORT_SYMBOL(__delay);
+EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
index b7a78ad429b78f270913e620ea875083467141d0..5d2858f6eede4283bbb7c61717d021e3cf60797c 100644 (file)
@@ -32,6 +32,9 @@ typedef struct {
 } mem_prof_t;
 static mem_prof_t mem_prof[MAX_NUMNODES];
 
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
 static void __init mem_prof_init(void)
 {
        unsigned long start_pfn, holes, free_pfn;
@@ -42,7 +45,7 @@ static void __init mem_prof_init(void)
        /* Node#0 SDRAM */
        mp = &mem_prof[0];
        mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
-       mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE);
+       mp->pages = PFN_DOWN(memory_end - memory_start);
        mp->holes = 0;
        mp->free_pfn = PFN_UP(__pa(_end));
 
index 49a6d16a3d585d5b2a4d567ce7256162340130cc..e9491a5ae827a99f530afd409f1800ff4e54a9fd 100644 (file)
@@ -150,9 +150,13 @@ ENTRY(tme_handler)
 
        ; pmd = pmd_offset(pgd, address);
        ld      r3, @r3                 ; r3: pmd data
-       ldi     r2, #-4096
        beqz    r3, 3f                  ; pmd_none(*pmd) ?
 
+       and3    r2, r3, #0xfff
+       add3    r2, r2, #-355           ; _KERNPG_TABLE(=0x163)
+       bnez    r2, 3f                  ; pmd_bad(*pmd) ?
+       ldi     r2, #-4096
+
        ; pte = pte_offset(pmd, address);
        and     r2, r3                  ; r2: pte base addr
        srl3    r3, r0, #10
@@ -263,9 +267,9 @@ ENTRY(tme_handler)
        ld      r1, @r3                 ; r1: pmd
        beqz    r1, 3f                  ; pmd_none(*pmd) ?
 ;
-       and3    r1, r1, #0xeff
-       ldi     r4, #611                ; _KERNPG_TABLE(=611)
-       bne     r1, r4, 3f              ; !pmd_bad(*pmd) ?
+       and3    r1, r1, #0x3ff
+       ldi     r4, #0x163              ; _KERNPG_TABLE(=0x163)
+       bne     r1, r4, 3f              ; pmd_bad(*pmd) ?
 
        .fillinsn
 4:
index 554f65b6cd3b38e7ba0575def0c56ce2083189e3..394ee946015c4284eea9ee0f668e1851ccfdd38b 100644 (file)
@@ -1,8 +1,16 @@
 #ifndef __M68K_HARDIRQ_H
 #define __M68K_HARDIRQ_H
 
-#define HARDIRQ_BITS   8
+#include <linux/threads.h>
+#include <linux/cache.h>
+
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
 
-#include <asm-generic/hardirq.h>
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define HARDIRQ_BITS   8
 
 #endif
index 594ee0e657fe0da77cbd20740c202b044e0d7ded..9a8876f715d81d73214c97079d2a601460fe6234 100644 (file)
@@ -45,25 +45,25 @@ int main(void)
        DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
 
        /* offsets into the pt_regs */
-       DEFINE(PT_D0, offsetof(struct pt_regs, d0));
-       DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
-       DEFINE(PT_D1, offsetof(struct pt_regs, d1));
-       DEFINE(PT_D2, offsetof(struct pt_regs, d2));
-       DEFINE(PT_D3, offsetof(struct pt_regs, d3));
-       DEFINE(PT_D4, offsetof(struct pt_regs, d4));
-       DEFINE(PT_D5, offsetof(struct pt_regs, d5));
-       DEFINE(PT_A0, offsetof(struct pt_regs, a0));
-       DEFINE(PT_A1, offsetof(struct pt_regs, a1));
-       DEFINE(PT_A2, offsetof(struct pt_regs, a2));
-       DEFINE(PT_PC, offsetof(struct pt_regs, pc));
-       DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+       DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
+       DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+       DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
+       DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
+       DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
+       DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
+       DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
+       DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
+       DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
+       DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
+       DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
+       DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
 
 #ifdef CONFIG_COLDFIRE
        /* bitfields are a bit difficult */
-       DEFINE(PT_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
+       DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
 #else
        /* bitfields are a bit difficult */
-       DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+       DEFINE(PT_OFF_VECTOR, offsetof(struct pt_regs, pc) + 4);
 #endif
 
        /* signal defines */
index f56faa5c9cd91a06e2c24e153c3fd54fa72a183e..56043ade394197ebb011fcfcd94a50df9d181179 100644 (file)
@@ -46,7 +46,7 @@
 ENTRY(buserr)
        SAVE_ALL
        moveq   #-1,%d0
-       movel   %d0,%sp@(PT_ORIG_D0)
+       movel   %d0,%sp@(PT_OFF_ORIG_D0)
        movel   %sp,%sp@-               /* stack frame pointer argument */
        jsr     buserr_c
        addql   #4,%sp
@@ -55,7 +55,7 @@ ENTRY(buserr)
 ENTRY(trap)
        SAVE_ALL
        moveq   #-1,%d0
-       movel   %d0,%sp@(PT_ORIG_D0)
+       movel   %d0,%sp@(PT_OFF_ORIG_D0)
        movel   %sp,%sp@-               /* stack frame pointer argument */
        jsr     trap_c
        addql   #4,%sp
@@ -67,7 +67,7 @@ ENTRY(trap)
 ENTRY(dbginterrupt)
        SAVE_ALL
        moveq   #-1,%d0
-       movel   %d0,%sp@(PT_ORIG_D0)
+       movel   %d0,%sp@(PT_OFF_ORIG_D0)
        movel   %sp,%sp@-               /* stack frame pointer argument */
        jsr     dbginterrupt_c
        addql   #4,%sp
index b1703c67a4f195f54203e8cbeed93c3441b8d9a8..f3236d0b522ddceaa39a9a468b7cc4f02d27b5d1 100644 (file)
@@ -162,7 +162,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                totalram_pages++;
                pages++;
        }
-       printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+       printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages * (PAGE_SIZE / 1024));
 }
 #endif
 
index 0f41ba82a3b533d1ff6a3815f59916c6d3e5f77e..942397984c66ca685bd93e1d559585ecbabf71f5 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
 #include <asm/mcfdma.h>
-#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
index b1aef72f3bafb23dcb5e3285be12029de801542b..9d80d2c4286668f2715d64a5026026e5f98cfae7 100644 (file)
 .globl inthandler7
 
 badsys:
-       movel   #-ENOSYS,%sp@(PT_D0)
+       movel   #-ENOSYS,%sp@(PT_OFF_D0)
        jra     ret_from_exception
 
 do_trace:
-       movel   #-ENOSYS,%sp@(PT_D0)    /* needed for strace*/
+       movel   #-ENOSYS,%sp@(PT_OFF_D0)        /* needed for strace*/
        subql   #4,%sp
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
        RESTORE_SWITCH_STACK
        addql   #4,%sp
-       movel   %sp@(PT_ORIG_D0),%d1
+       movel   %sp@(PT_OFF_ORIG_D0),%d1
        movel   #-ENOSYS,%d0
        cmpl    #NR_syscalls,%d1
        jcc     1f
@@ -57,7 +57,7 @@ do_trace:
        lea     sys_call_table, %a0
        jbsr    %a0@(%d1)
 
-1:     movel   %d0,%sp@(PT_D0)         /* save the return value */
+1:     movel   %d0,%sp@(PT_OFF_D0)             /* save the return value */
        subql   #4,%sp                  /* dummy return address */
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
@@ -75,7 +75,7 @@ ENTRY(system_call)
        jbsr    set_esp0
        addql   #4,%sp
 
-       movel   %sp@(PT_ORIG_D0),%d0
+       movel   %sp@(PT_OFF_ORIG_D0),%d0
 
        movel   %sp,%d1                 /* get thread_info pointer */
        andl    #-THREAD_SIZE,%d1
@@ -88,10 +88,10 @@ ENTRY(system_call)
        lea     sys_call_table,%a0
        movel   %a0@(%d0), %a0
        jbsr    %a0@
-       movel   %d0,%sp@(PT_D0)         /* save the return value*/
+       movel   %d0,%sp@(PT_OFF_D0)             /* save the return value*/
 
 ret_from_exception:
-       btst    #5,%sp@(PT_SR)          /* check if returning to kernel*/
+       btst    #5,%sp@(PT_OFF_SR)              /* check if returning to kernel*/
        jeq     Luser_return            /* if so, skip resched, signals*/
 
 Lkernel_return:
@@ -133,7 +133,7 @@ Lreturn:
  */
 inthandler1:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -144,7 +144,7 @@ inthandler1:
 
 inthandler2:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -155,7 +155,7 @@ inthandler2:
 
 inthandler3:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -166,7 +166,7 @@ inthandler3:
 
 inthandler4:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -177,7 +177,7 @@ inthandler4:
 
 inthandler5:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -188,7 +188,7 @@ inthandler5:
 
 inthandler6:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -199,7 +199,7 @@ inthandler6:
 
 inthandler7:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -210,7 +210,7 @@ inthandler7:
 
 inthandler:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and     #0x3ff, %d0
 
        movel   %sp,%sp@-
@@ -224,7 +224,7 @@ ret_from_interrupt:
 2:
        RESTORE_ALL
 1:
-       moveb   %sp@(PT_SR), %d0
+       moveb   %sp@(PT_OFF_SR), %d0
        and     #7, %d0
        jhi     2b
 
index 55dfefe386427ea875bbf96b39dae967095ff514..6d3460a39cacf1383a16f2e66146c60aeecf6509 100644 (file)
 .globl inthandler
 
 badsys:
-       movel   #-ENOSYS,%sp@(PT_D0)
+       movel   #-ENOSYS,%sp@(PT_OFF_D0)
        jra     ret_from_exception
 
 do_trace:
-       movel   #-ENOSYS,%sp@(PT_D0)    /* needed for strace*/
+       movel   #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
        subql   #4,%sp
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
        RESTORE_SWITCH_STACK
        addql   #4,%sp
-       movel   %sp@(PT_ORIG_D0),%d1
+       movel   %sp@(PT_OFF_ORIG_D0),%d1
        movel   #-ENOSYS,%d0
        cmpl    #NR_syscalls,%d1
        jcc     1f
@@ -53,7 +53,7 @@ do_trace:
        lea     sys_call_table, %a0
        jbsr    %a0@(%d1)
 
-1:     movel   %d0,%sp@(PT_D0)         /* save the return value */
+1:     movel   %d0,%sp@(PT_OFF_D0)     /* save the return value */
        subql   #4,%sp                  /* dummy return address */
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
@@ -79,10 +79,10 @@ ENTRY(system_call)
        lea     sys_call_table,%a0
        movel   %a0@(%d0), %a0
        jbsr    %a0@
-       movel   %d0,%sp@(PT_D0)         /* save the return value*/
+       movel   %d0,%sp@(PT_OFF_D0)     /* save the return value*/
 
 ret_from_exception:
-       btst    #5,%sp@(PT_SR)          /* check if returning to kernel*/
+       btst    #5,%sp@(PT_OFF_SR)      /* check if returning to kernel*/
        jeq     Luser_return            /* if so, skip resched, signals*/
 
 Lkernel_return:
@@ -124,7 +124,7 @@ Lreturn:
  */
 inthandler:
        SAVE_ALL
-       movew   %sp@(PT_VECTOR), %d0
+       movew   %sp@(PT_OFF_VECTOR), %d0
        and.l   #0x3ff, %d0
        lsr.l   #0x02,  %d0
 
@@ -139,7 +139,7 @@ ret_from_interrupt:
 2:
        RESTORE_ALL
 1:
-       moveb   %sp@(PT_SR), %d0
+       moveb   %sp@(PT_OFF_SR), %d0
        and     #7, %d0
        jhi     2b
        /* check if we need to do software interrupts */
index 3b471c0da24a0bd6232acbf98d5b7b6b0135217b..dd7d591f70eae6df0af6504428f2afbba503140d 100644 (file)
@@ -81,11 +81,11 @@ ENTRY(system_call)
 
        movel   %d3,%a0
        jbsr    %a0@
-       movel   %d0,%sp@(PT_D0)         /* save the return value */
+       movel   %d0,%sp@(PT_OFF_D0)     /* save the return value */
        jra     ret_from_exception
 1:
-       movel   #-ENOSYS,%d2            /* strace needs -ENOSYS in PT_D0 */
-       movel   %d2,PT_D0(%sp)          /* on syscall entry */
+       movel   #-ENOSYS,%d2            /* strace needs -ENOSYS in PT_OFF_D0 */
+       movel   %d2,PT_OFF_D0(%sp)      /* on syscall entry */
        subql   #4,%sp
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
@@ -93,7 +93,7 @@ ENTRY(system_call)
        addql   #4,%sp
        movel   %d3,%a0
        jbsr    %a0@
-       movel   %d0,%sp@(PT_D0)         /* save the return value */
+       movel   %d0,%sp@(PT_OFF_D0)             /* save the return value */
        subql   #4,%sp                  /* dummy return address */
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
@@ -104,7 +104,7 @@ ret_from_signal:
 
 ret_from_exception:
        move    #0x2700,%sr             /* disable intrs */
-       btst    #5,%sp@(PT_SR)          /* check if returning to kernel */
+       btst    #5,%sp@(PT_OFF_SR)      /* check if returning to kernel */
        jeq     Luser_return            /* if so, skip resched, signals */
 
 #ifdef CONFIG_PREEMPT
@@ -142,8 +142,8 @@ Luser_return:
 Lreturn:
        move    #0x2700,%sr             /* disable intrs */
        movel   sw_usp,%a0              /* get usp */
-       movel   %sp@(PT_PC),%a0@-       /* copy exception program counter */
-       movel   %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */
+       movel   %sp@(PT_OFF_PC),%a0@-   /* copy exception program counter */
+       movel   %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */
        moveml  %sp@,%d1-%d5/%a0-%a2
        lea     %sp@(32),%sp            /* space for 8 regs */
        movel   %sp@+,%d0
@@ -181,9 +181,9 @@ Lsignal_return:
 ENTRY(inthandler)
        SAVE_ALL
        moveq   #-1,%d0
-       movel   %d0,%sp@(PT_ORIG_D0)
+       movel   %d0,%sp@(PT_OFF_ORIG_D0)
 
-       movew   %sp@(PT_FORMATVEC),%d0  /* put exception # in d0 */
+       movew   %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
        andl    #0x03fc,%d0             /* mask out vector only */
 
        movel   %sp,%sp@-               /* push regs arg */
@@ -203,7 +203,7 @@ ENTRY(inthandler)
 ENTRY(fasthandler)
        SAVE_LOCAL
 
-       movew   %sp@(PT_FORMATVEC),%d0
+       movew   %sp@(PT_OFF_FORMATVEC),%d0
        andl    #0x03fc,%d0             /* mask out vector only */
 
        movel   %sp,%sp@-               /* push regs arg */
index 8a3a4dd55763eba744552c46c825831569e90610..167e10ff06d99ddb57175117e552bb9b4835faa1 100644 (file)
@@ -129,42 +129,47 @@ extern int fixup_exception(struct pt_regs *regs);
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
 
-#define __get_user_nocheck(x, ptr, size)       \
-({                                             \
-       __typeof(*(ptr)) __gu_val;              \
-       unsigned long __gu_addr;                \
-       int __gu_err;                           \
-       __gu_addr = (unsigned long) (ptr);      \
-       switch (size) {                         \
-       case 1:  __get_user_asm("bu"); break;   \
-       case 2:  __get_user_asm("hu"); break;   \
-       case 4:  __get_user_asm(""  ); break;   \
-       default: __get_user_unknown(); break;   \
-       }                                       \
-       x = (__typeof__(*(ptr))) __gu_val;      \
-       __gu_err;                               \
+#define __get_user_nocheck(x, ptr, size)                               \
+({                                                                     \
+       unsigned long __gu_addr;                                        \
+       int __gu_err;                                                   \
+       __gu_addr = (unsigned long) (ptr);                              \
+       switch (size) {                                                 \
+       case 1: {                                                       \
+               unsigned char __gu_val;                                 \
+               __get_user_asm("bu");                                   \
+               (x) = *(__force __typeof__(*(ptr))*) &__gu_val;         \
+               break;                                                  \
+       }                                                               \
+       case 2: {                                                       \
+               unsigned short __gu_val;                                \
+               __get_user_asm("hu");                                   \
+               (x) = *(__force __typeof__(*(ptr))*) &__gu_val;         \
+               break;                                                  \
+       }                                                               \
+       case 4: {                                                       \
+               unsigned int __gu_val;                                  \
+               __get_user_asm("");                                     \
+               (x) = *(__force __typeof__(*(ptr))*) &__gu_val;         \
+               break;                                                  \
+       }                                                               \
+       default:                                                        \
+               __get_user_unknown();                                   \
+               break;                                                  \
+       }                                                               \
+       __gu_err;                                                       \
 })
 
-#define __get_user_check(x, ptr, size)                 \
-({                                                     \
-       __typeof__(*(ptr)) __gu_val;                    \
-       unsigned long __gu_addr;                        \
-       int __gu_err;                                   \
-       __gu_addr = (unsigned long) (ptr);              \
-       if (likely(__access_ok(__gu_addr,size))) {      \
-               switch (size) {                         \
-               case 1:  __get_user_asm("bu"); break;   \
-               case 2:  __get_user_asm("hu"); break;   \
-               case 4:  __get_user_asm(""  ); break;   \
-               default: __get_user_unknown(); break;   \
-               }                                       \
-       }                                               \
-       else {                                          \
-               __gu_err = -EFAULT;                     \
-               __gu_val = 0;                           \
-       }                                               \
-       x = (__typeof__(*(ptr))) __gu_val;              \
-       __gu_err;                                       \
+#define __get_user_check(x, ptr, size)                                 \
+({                                                                     \
+       int _e;                                                         \
+       if (likely(__access_ok((unsigned long) (ptr), (size))))         \
+               _e = __get_user_nocheck((x), (ptr), (size));            \
+       else {                                                          \
+               _e = -EFAULT;                                           \
+               (x) = (__typeof__(x))0;                                 \
+       }                                                               \
+       _e;                                                             \
 })
 
 #define __get_user_asm(INSN)                                   \
index 8b450e920af1503132b1b73ac05a023043843c51..2a0bf79ab968162eb514c2190dc9a8e136845645 100644 (file)
@@ -20,9 +20,9 @@ extern unsigned long mn10300_ioclk;   /* IOCLK (crystal speed) in HZ */
 extern unsigned long mn10300_iobclk;
 extern unsigned long mn10300_tsc_per_HZ;
 
-#define MN10300_IOCLK          ((unsigned long)mn10300_ioclk)
+#define MN10300_IOCLK          mn10300_ioclk
 /* If this processors has a another clock, uncomment the below. */
-/* #define MN10300_IOBCLK      ((unsigned long)mn10300_iobclk) */
+/* #define MN10300_IOBCLK      mn10300_iobclk */
 
 #else /* !CONFIG_MN10300_RTC */
 
@@ -35,7 +35,7 @@ extern unsigned long mn10300_tsc_per_HZ;
 #define MN10300_TSCCLK         MN10300_IOCLK
 
 #ifdef CONFIG_MN10300_RTC
-#define MN10300_TSC_PER_HZ     ((unsigned long)mn10300_tsc_per_HZ)
+#define MN10300_TSC_PER_HZ     mn10300_tsc_per_HZ
 #else /* !CONFIG_MN10300_RTC */
 #define MN10300_TSC_PER_HZ     (MN10300_TSCCLK/HZ)
 #endif /* !CONFIG_MN10300_RTC */
index 7d514841ffda7ca790fdd07ee1a6522f4ce39203..67be3f2eb18e928b68363601ae5440bb737b9e2b 100644 (file)
@@ -20,9 +20,9 @@ extern unsigned long mn10300_ioclk;   /* IOCLK (crystal speed) in HZ */
 extern unsigned long mn10300_iobclk;
 extern unsigned long mn10300_tsc_per_HZ;
 
-#define MN10300_IOCLK          ((unsigned long)mn10300_ioclk)
+#define MN10300_IOCLK          mn10300_ioclk
 /* If this processors has a another clock, uncomment the below. */
-/* #define MN10300_IOBCLK      ((unsigned long)mn10300_iobclk) */
+/* #define MN10300_IOBCLK      mn10300_iobclk */
 
 #else /* !CONFIG_MN10300_RTC */
 
@@ -35,7 +35,7 @@ extern unsigned long mn10300_tsc_per_HZ;
 #define MN10300_TSCCLK         MN10300_IOCLK
 
 #ifdef CONFIG_MN10300_RTC
-#define MN10300_TSC_PER_HZ     ((unsigned long)mn10300_tsc_per_HZ)
+#define MN10300_TSC_PER_HZ     mn10300_tsc_per_HZ
 #else /* !CONFIG_MN10300_RTC */
 #define MN10300_TSC_PER_HZ     (MN10300_TSCCLK/HZ)
 #endif /* !CONFIG_MN10300_RTC */
index 47ee603f558ed1022f4ce466b232b2b92a544eb6..2aa371e30079ced2c7938133b355ae7ca54b7343 100644 (file)
@@ -201,7 +201,7 @@ static int kvmppc_exit_timing_open(struct inode *inode, struct file *file)
        return single_open(file, kvmppc_exit_timing_show, inode->i_private);
 }
 
-static struct file_operations kvmppc_exit_timing_fops = {
+static const struct file_operations kvmppc_exit_timing_fops = {
        .owner   = THIS_MODULE,
        .open    = kvmppc_exit_timing_open,
        .read    = seq_read,
index 961309446170b6550f96ac471ea428fd75cfee49..884e8bcec499ff13718b7bb09f4148467cb6d22d 100644 (file)
@@ -147,7 +147,7 @@ static int __fops ## _open(struct inode *inode, struct file *file)  \
        __simple_attr_check_format(__fmt, 0ull);                        \
        return spufs_attr_open(inode, file, __get, __set, __fmt);       \
 }                                                                      \
-static struct file_operations __fops = {                               \
+static const struct file_operations __fops = {                         \
        .owner   = THIS_MODULE,                                         \
        .open    = __fops ## _open,                                     \
        .release = spufs_attr_release,                                  \
index ab69925d579b7c8fe586a1cc1357cab2dbd83fb3..937a544a236d5e1a58be64b821d23bb20e965c63 100644 (file)
@@ -209,7 +209,7 @@ static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
        return n_read * sizeof(struct dtl_entry);
 }
 
-static struct file_operations dtl_fops = {
+static const struct file_operations dtl_fops = {
        .open           = dtl_file_open,
        .release        = dtl_file_release,
        .read           = dtl_file_read,
index b53225d2cac39e690d2648d717c34fe8b872d7c5..e133ce25e29022d20bdd5e954c9a6697bfc7ab91 100644 (file)
@@ -100,7 +100,7 @@ static int xen_array_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations u32_array_fops = {
+static const struct file_operations u32_array_fops = {
        .owner  = THIS_MODULE,
        .open   = u32_array_open,
        .release= xen_array_release,
index 6593ab39cfe9223b106d3b5a897937e58176e6b1..8873b9b439ffdb0bf695b0077f84bb28c1046a38 100644 (file)
@@ -350,6 +350,7 @@ static void blkdev_discard_end_io(struct bio *bio, int err)
 
        if (bio->bi_private)
                complete(bio->bi_private);
+       __free_page(bio_page(bio));
 
        bio_put(bio);
 }
@@ -372,30 +373,50 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        struct request_queue *q = bdev_get_queue(bdev);
        int type = flags & DISCARD_FL_BARRIER ?
                DISCARD_BARRIER : DISCARD_NOBARRIER;
+       struct bio *bio;
+       struct page *page;
        int ret = 0;
 
        if (!q)
                return -ENXIO;
 
-       if (!q->prepare_discard_fn)
+       if (!blk_queue_discard(q))
                return -EOPNOTSUPP;
 
        while (nr_sects && !ret) {
-               struct bio *bio = bio_alloc(gfp_mask, 0);
-               if (!bio)
-                       return -ENOMEM;
+               unsigned int sector_size = q->limits.logical_block_size;
+               unsigned int max_discard_sectors =
+                       min(q->limits.max_discard_sectors, UINT_MAX >> 9);
 
+               bio = bio_alloc(gfp_mask, 1);
+               if (!bio)
+                       goto out;
+               bio->bi_sector = sector;
                bio->bi_end_io = blkdev_discard_end_io;
                bio->bi_bdev = bdev;
                if (flags & DISCARD_FL_WAIT)
                        bio->bi_private = &wait;
 
-               bio->bi_sector = sector;
+               /*
+                * Add a zeroed one-sector payload as that's what
+                * our current implementations need.  If we'll ever need
+                * more the interface will need revisiting.
+                */
+               page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+               if (!page)
+                       goto out_free_bio;
+               if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size)
+                       goto out_free_page;
 
-               if (nr_sects > queue_max_hw_sectors(q)) {
-                       bio->bi_size = queue_max_hw_sectors(q) << 9;
-                       nr_sects -= queue_max_hw_sectors(q);
-                       sector += queue_max_hw_sectors(q);
+               /*
+                * And override the bio size - the way discard works we
+                * touch many more blocks on disk than the actual payload
+                * length.
+                */
+               if (nr_sects > max_discard_sectors) {
+                       bio->bi_size = max_discard_sectors << 9;
+                       nr_sects -= max_discard_sectors;
+                       sector += max_discard_sectors;
                } else {
                        bio->bi_size = nr_sects << 9;
                        nr_sects = 0;
@@ -414,5 +435,11 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
                bio_put(bio);
        }
        return ret;
+out_free_page:
+       __free_page(page);
+out_free_bio:
+       bio_put(bio);
+out:
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(blkdev_issue_discard);
index 8135228e4b2907e15f8a8ff5199de3fa8e5f40cd..81f34311659a21cc172d3ce3dde996643941e5eb 100644 (file)
@@ -34,6 +34,7 @@
 #include "blk.h"
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
 
 static int __make_request(struct request_queue *q, struct bio *bio);
@@ -69,7 +70,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
                part_stat_inc(cpu, part, merges[rw]);
        else {
                part_round_stats(cpu, part);
-               part_inc_in_flight(part, rw);
+               part_inc_in_flight(part);
        }
 
        part_stat_unlock();
@@ -1031,7 +1032,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
 
        if (part->in_flight) {
                __part_stat_add(cpu, part, time_in_queue,
-                               part_in_flight(part) * (now - part->stamp));
+                               part->in_flight * (now - part->stamp));
                __part_stat_add(cpu, part, io_ticks, (now - part->stamp));
        }
        part->stamp = now;
@@ -1124,7 +1125,6 @@ void init_request_from_bio(struct request *req, struct bio *bio)
                req->cmd_flags |= REQ_DISCARD;
                if (bio_rw_flagged(bio, BIO_RW_BARRIER))
                        req->cmd_flags |= REQ_SOFTBARRIER;
-               req->q->prepare_discard_fn(req->q, req);
        } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)))
                req->cmd_flags |= REQ_HARDBARRIER;
 
@@ -1437,7 +1437,8 @@ static inline void __generic_make_request(struct bio *bio)
                        goto end_io;
                }
 
-               if (unlikely(nr_sectors > queue_max_hw_sectors(q))) {
+               if (unlikely(!bio_rw_flagged(bio, BIO_RW_DISCARD) &&
+                            nr_sectors > queue_max_hw_sectors(q))) {
                        printk(KERN_ERR "bio too big device %s (%u > %u)\n",
                               bdevname(bio->bi_bdev, b),
                               bio_sectors(bio),
@@ -1470,7 +1471,7 @@ static inline void __generic_make_request(struct bio *bio)
                        goto end_io;
 
                if (bio_rw_flagged(bio, BIO_RW_DISCARD) &&
-                   !q->prepare_discard_fn) {
+                   !blk_queue_discard(q)) {
                        err = -EOPNOTSUPP;
                        goto end_io;
                }
@@ -1738,7 +1739,7 @@ static void blk_account_io_done(struct request *req)
                part_stat_inc(cpu, part, ios[rw]);
                part_stat_add(cpu, part, ticks[rw], duration);
                part_round_stats(cpu, part);
-               part_dec_in_flight(part, rw);
+               part_dec_in_flight(part);
 
                part_stat_unlock();
        }
@@ -2491,6 +2492,14 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work)
 }
 EXPORT_SYMBOL(kblockd_schedule_work);
 
+int kblockd_schedule_delayed_work(struct request_queue *q,
+                                 struct delayed_work *work,
+                                 unsigned long delay)
+{
+       return queue_delayed_work(kblockd_workqueue, work, delay);
+}
+EXPORT_SYMBOL(kblockd_schedule_delayed_work);
+
 int __init blk_dev_init(void)
 {
        BUILD_BUG_ON(__REQ_NR_BITS > 8 *
index 99cb5cf1f447fa8759d73f06bf64fe4b20eec580..b0de8574fdc84e40e1bdf87dea4eb1af98769bb4 100644 (file)
@@ -351,7 +351,7 @@ static void blk_account_io_merge(struct request *req)
                part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
 
                part_round_stats(cpu, part);
-               part_dec_in_flight(part, rq_data_dir(req));
+               part_dec_in_flight(part);
 
                part_stat_unlock();
        }
index 83413ff837397a88bf8e5a8bbc1cb9652c0dd50f..e0695bca702777d7455e9d4266590be47977443e 100644 (file)
@@ -33,23 +33,6 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn)
 }
 EXPORT_SYMBOL(blk_queue_prep_rq);
 
-/**
- * blk_queue_set_discard - set a discard_sectors function for queue
- * @q:         queue
- * @dfn:       prepare_discard function
- *
- * It's possible for a queue to register a discard callback which is used
- * to transform a discard request into the appropriate type for the
- * hardware. If none is registered, then discard requests are failed
- * with %EOPNOTSUPP.
- *
- */
-void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn)
-{
-       q->prepare_discard_fn = dfn;
-}
-EXPORT_SYMBOL(blk_queue_set_discard);
-
 /**
  * blk_queue_merge_bvec - set a merge_bvec function for queue
  * @q:         queue
@@ -111,7 +94,9 @@ void blk_set_default_limits(struct queue_limits *lim)
        lim->max_hw_segments = MAX_HW_SEGMENTS;
        lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
        lim->max_segment_size = MAX_SEGMENT_SIZE;
-       lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS;
+       lim->max_sectors = BLK_DEF_MAX_SECTORS;
+       lim->max_hw_sectors = INT_MAX;
+       lim->max_discard_sectors = SAFE_MAX_SECTORS;
        lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
        lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
        lim->alignment_offset = 0;
@@ -164,6 +149,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
        q->unplug_timer.data = (unsigned long)q;
 
        blk_set_default_limits(&q->limits);
+       blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
 
        /*
         * If the caller didn't supply a lock, fall back to our embedded
@@ -253,6 +239,18 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
 }
 EXPORT_SYMBOL(blk_queue_max_hw_sectors);
 
+/**
+ * blk_queue_max_discard_sectors - set max sectors for a single discard
+ * @q:  the request queue for the device
+ * @max_discard: maximum number of sectors to discard
+ **/
+void blk_queue_max_discard_sectors(struct request_queue *q,
+               unsigned int max_discard_sectors)
+{
+       q->limits.max_discard_sectors = max_discard_sectors;
+}
+EXPORT_SYMBOL(blk_queue_max_discard_sectors);
+
 /**
  * blk_queue_max_phys_segments - set max phys segments for a request for this queue
  * @q:  the request queue for the device
index b78c9c3e26705f45fb1e90ac116dc8bb96c8122b..8a6d81afb284ebbf7111653393b6594d91924491 100644 (file)
@@ -452,6 +452,7 @@ int blk_register_queue(struct gendisk *disk)
        if (ret) {
                kobject_uevent(&q->kobj, KOBJ_REMOVE);
                kobject_del(&q->kobj);
+               blk_trace_remove_sysfs(disk_to_dev(disk));
                return ret;
        }
 
@@ -465,11 +466,11 @@ void blk_unregister_queue(struct gendisk *disk)
        if (WARN_ON(!q))
                return;
 
-       if (q->request_fn) {
+       if (q->request_fn)
                elv_unregister_queue(q);
 
-               kobject_uevent(&q->kobj, KOBJ_REMOVE);
-               kobject_del(&q->kobj);
-               kobject_put(&disk_to_dev(disk)->kobj);
-       }
+       kobject_uevent(&q->kobj, KOBJ_REMOVE);
+       kobject_del(&q->kobj);
+       blk_trace_remove_sysfs(disk_to_dev(disk));
+       kobject_put(&disk_to_dev(disk)->kobj);
 }
index 1ca813b16e7840cf10086d79b7e2bb7b0c07005e..9c4b679908f41cf034cdddc79a9bff8bcb1f4e85 100644 (file)
@@ -150,7 +150,7 @@ struct cfq_data {
         * idle window management
         */
        struct timer_list idle_slice_timer;
-       struct work_struct unplug_work;
+       struct delayed_work unplug_work;
 
        struct cfq_queue *active_queue;
        struct cfq_io_context *active_cic;
@@ -173,6 +173,7 @@ struct cfq_data {
        unsigned int cfq_slice[2];
        unsigned int cfq_slice_async_rq;
        unsigned int cfq_slice_idle;
+       unsigned int cfq_latency;
 
        struct list_head cic_list;
 
@@ -180,6 +181,8 @@ struct cfq_data {
         * Fallback dummy cfqq for extreme OOM conditions
         */
        struct cfq_queue oom_cfqq;
+
+       unsigned long last_end_sync_rq;
 };
 
 enum cfqq_state_flags {
@@ -265,11 +268,13 @@ static inline int cfq_bio_sync(struct bio *bio)
  * scheduler run of queue, if there are requests pending and no one in the
  * driver that will restart queueing
  */
-static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
+static inline void cfq_schedule_dispatch(struct cfq_data *cfqd,
+                                        unsigned long delay)
 {
        if (cfqd->busy_queues) {
                cfq_log(cfqd, "schedule dispatch");
-               kblockd_schedule_work(cfqd->queue, &cfqd->unplug_work);
+               kblockd_schedule_delayed_work(cfqd->queue, &cfqd->unplug_work,
+                                               delay);
        }
 }
 
@@ -1326,12 +1331,30 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
                        return 0;
 
                /*
-                * we are the only queue, allow up to 4 times of 'quantum'
+                * Sole queue user, allow bigger slice
                 */
-               if (cfqq->dispatched >= 4 * max_dispatch)
-                       return 0;
+               max_dispatch *= 4;
+       }
+
+       /*
+        * Async queues must wait a bit before being allowed dispatch.
+        * We also ramp up the dispatch depth gradually for async IO,
+        * based on the last sync IO we serviced
+        */
+       if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) {
+               unsigned long last_sync = jiffies - cfqd->last_end_sync_rq;
+               unsigned int depth;
+
+               depth = last_sync / cfqd->cfq_slice[1];
+               if (!depth && !cfqq->dispatched)
+                       depth = 1;
+               if (depth < max_dispatch)
+                       max_dispatch = depth;
        }
 
+       if (cfqq->dispatched >= max_dispatch)
+               return 0;
+
        /*
         * Dispatch a request from this cfqq
         */
@@ -1376,7 +1399,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
 
        if (unlikely(cfqd->active_queue == cfqq)) {
                __cfq_slice_expired(cfqd, cfqq, 0);
-               cfq_schedule_dispatch(cfqd);
+               cfq_schedule_dispatch(cfqd, 0);
        }
 
        kmem_cache_free(cfq_pool, cfqq);
@@ -1471,7 +1494,7 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
        if (unlikely(cfqq == cfqd->active_queue)) {
                __cfq_slice_expired(cfqd, cfqq, 0);
-               cfq_schedule_dispatch(cfqd);
+               cfq_schedule_dispatch(cfqd, 0);
        }
 
        cfq_put_queue(cfqq);
@@ -1951,7 +1974,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
        enable_idle = old_idle = cfq_cfqq_idle_window(cfqq);
 
        if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
-           (cfqd->hw_tag && CIC_SEEKY(cic)))
+           (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic)))
                enable_idle = 0;
        else if (sample_valid(cic->ttime_samples)) {
                if (cic->ttime_mean > cfqd->cfq_slice_idle)
@@ -2157,8 +2180,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
        if (cfq_cfqq_sync(cfqq))
                cfqd->sync_flight--;
 
-       if (sync)
+       if (sync) {
                RQ_CIC(rq)->last_end_request = now;
+               cfqd->last_end_sync_rq = now;
+       }
 
        /*
         * If this is the active queue, check if it needs to be expired,
@@ -2186,7 +2211,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
        }
 
        if (!rq_in_driver(cfqd))
-               cfq_schedule_dispatch(cfqd);
+               cfq_schedule_dispatch(cfqd, 0);
 }
 
 /*
@@ -2316,7 +2341,7 @@ queue_fail:
        if (cic)
                put_io_context(cic->ioc);
 
-       cfq_schedule_dispatch(cfqd);
+       cfq_schedule_dispatch(cfqd, 0);
        spin_unlock_irqrestore(q->queue_lock, flags);
        cfq_log(cfqd, "set_request fail");
        return 1;
@@ -2325,7 +2350,7 @@ queue_fail:
 static void cfq_kick_queue(struct work_struct *work)
 {
        struct cfq_data *cfqd =
-               container_of(work, struct cfq_data, unplug_work);
+               container_of(work, struct cfq_data, unplug_work.work);
        struct request_queue *q = cfqd->queue;
 
        spin_lock_irq(q->queue_lock);
@@ -2379,7 +2404,7 @@ static void cfq_idle_slice_timer(unsigned long data)
 expire:
        cfq_slice_expired(cfqd, timed_out);
 out_kick:
-       cfq_schedule_dispatch(cfqd);
+       cfq_schedule_dispatch(cfqd, 0);
 out_cont:
        spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
@@ -2387,7 +2412,7 @@ out_cont:
 static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
 {
        del_timer_sync(&cfqd->idle_slice_timer);
-       cancel_work_sync(&cfqd->unplug_work);
+       cancel_delayed_work_sync(&cfqd->unplug_work);
 }
 
 static void cfq_put_async_queues(struct cfq_data *cfqd)
@@ -2469,7 +2494,7 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->idle_slice_timer.function = cfq_idle_slice_timer;
        cfqd->idle_slice_timer.data = (unsigned long) cfqd;
 
-       INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
+       INIT_DELAYED_WORK(&cfqd->unplug_work, cfq_kick_queue);
 
        cfqd->cfq_quantum = cfq_quantum;
        cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
@@ -2480,8 +2505,9 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->cfq_slice[1] = cfq_slice_sync;
        cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
        cfqd->cfq_slice_idle = cfq_slice_idle;
+       cfqd->cfq_latency = 1;
        cfqd->hw_tag = 1;
-
+       cfqd->last_end_sync_rq = jiffies;
        return cfqd;
 }
 
@@ -2549,6 +2575,7 @@ SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1);
 SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
 SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
 SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
+SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
 #undef SHOW_FUNCTION
 
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)                        \
@@ -2580,6 +2607,7 @@ STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1);
 STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
 STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
                UINT_MAX, 0);
+STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
 #undef STORE_FUNCTION
 
 #define CFQ_ATTR(name) \
@@ -2595,6 +2623,7 @@ static struct elv_fs_entry cfq_attrs[] = {
        CFQ_ATTR(slice_async),
        CFQ_ATTR(slice_async_rq),
        CFQ_ATTR(slice_idle),
+       CFQ_ATTR(low_latency),
        __ATTR_NULL
 };
 
index 7865a34e0faaaba07cb9e4946dca6406b303bef1..9bd086c1a4d591b59eea0e684debac6e6b8e52d9 100644 (file)
@@ -21,6 +21,11 @@ static int compat_put_int(unsigned long arg, int val)
        return put_user(val, (compat_int_t __user *)compat_ptr(arg));
 }
 
+static int compat_put_uint(unsigned long arg, unsigned int val)
+{
+       return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
+}
+
 static int compat_put_long(unsigned long arg, long val)
 {
        return put_user(val, (compat_long_t __user *)compat_ptr(arg));
@@ -734,6 +739,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
        switch (cmd) {
        case HDIO_GETGEO:
                return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
+       case BLKPBSZGET:
+               return compat_put_uint(arg, bdev_physical_block_size(bdev));
+       case BLKIOMIN:
+               return compat_put_uint(arg, bdev_io_min(bdev));
+       case BLKIOOPT:
+               return compat_put_uint(arg, bdev_io_opt(bdev));
+       case BLKALIGNOFF:
+               return compat_put_int(arg, bdev_alignment_offset(bdev));
        case BLKFLSBUF:
        case BLKROSET:
        case BLKDISCARD:
index 517e4332cb37481dcad965e8f9986f029b42e64a..5a0861da324d76f975e2cb281f1fcc4e88f98606 100644 (file)
@@ -869,7 +869,6 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
 static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
-static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
        __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -889,7 +888,6 @@ static struct attribute *disk_attrs[] = {
        &dev_attr_alignment_offset.attr,
        &dev_attr_capability.attr,
        &dev_attr_stat.attr,
-       &dev_attr_inflight.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
        &dev_attr_fail.attr,
 #endif
@@ -1055,7 +1053,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
                           part_stat_read(hd, merges[1]),
                           (unsigned long long)part_stat_read(hd, sectors[1]),
                           jiffies_to_msecs(part_stat_read(hd, ticks[1])),
-                          part_in_flight(hd),
+                          hd->in_flight,
                           jiffies_to_msecs(part_stat_read(hd, io_ticks)),
                           jiffies_to_msecs(part_stat_read(hd, time_in_queue))
                        );
index d3e6b5827a3425de1871ec4dfa9f5ca04e8744f4..1f4d1de12b0957c9e8a2897f1aa89d5b96f170a5 100644 (file)
@@ -138,6 +138,11 @@ static int put_int(unsigned long arg, int val)
        return put_user(val, (int __user *)arg);
 }
 
+static int put_uint(unsigned long arg, unsigned int val)
+{
+       return put_user(val, (unsigned int __user *)arg);
+}
+
 static int put_long(unsigned long arg, long val)
 {
        return put_user(val, (long __user *)arg);
@@ -263,10 +268,18 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
        case BLKROGET:
                return put_int(arg, bdev_read_only(bdev) != 0);
-       case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
+       case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
                return put_int(arg, block_size(bdev));
-       case BLKSSZGET: /* get block device hardware sector size */
+       case BLKSSZGET: /* get block device logical block size */
                return put_int(arg, bdev_logical_block_size(bdev));
+       case BLKPBSZGET: /* get block device physical block size */
+               return put_uint(arg, bdev_physical_block_size(bdev));
+       case BLKIOMIN:
+               return put_uint(arg, bdev_io_min(bdev));
+       case BLKIOOPT:
+               return put_uint(arg, bdev_io_opt(bdev));
+       case BLKALIGNOFF:
+               return put_int(arg, bdev_alignment_offset(bdev));
        case BLKSECTGET:
                return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
        case BLKRASET:
index dd8729d674e56ef2dfcdc7a7fa320f399b4542c6..0ed42d8870c7cdde61dfa686475a4b45edd469e4 100644 (file)
@@ -211,6 +211,18 @@ config ACPI_HOTPLUG_CPU
        select ACPI_CONTAINER
        default y
 
+config ACPI_PROCESSOR_AGGREGATOR
+       tristate "Processor Aggregator"
+       depends on ACPI_PROCESSOR
+       depends on EXPERIMENTAL
+       depends on X86
+       help
+         ACPI 4.0 defines processor Aggregator, which enables OS to perform
+         specfic processor configuration and control that applies to all
+         processors in the platform. Currently only logical processor idling
+         is defined, which is to reduce power consumption. This driver
+         support the new device.
+
 config ACPI_THERMAL
        tristate "Thermal Zone"
        depends on ACPI_PROCESSOR
index 82cd49dc603b6a5712a380eddbb54237a33a4ec2..7702118509a0a6e848bee454a983f0ec42e9522b 100644 (file)
@@ -62,3 +62,5 @@ obj-$(CONFIG_ACPI_POWER_METER)        += power_meter.o
 processor-y                    := processor_core.o processor_throttling.o
 processor-y                    += processor_idle.o processor_thermal.o
 processor-$(CONFIG_CPU_FREQ)   += processor_perflib.o
+
+obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
new file mode 100644 (file)
index 0000000..0d2cdb8
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ * acpi_pad.c ACPI Processor Aggregator Driver
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/cpu.h>
+#include <linux/clockchips.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_PROCESSOR_AGGREGATOR_CLASS        "processor_aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
+static DEFINE_MUTEX(isolated_cpus_lock);
+
+#define MWAIT_SUBSTATE_MASK    (0xf)
+#define MWAIT_CSTATE_MASK      (0xf)
+#define MWAIT_SUBSTATE_SIZE    (4)
+#define CPUID_MWAIT_LEAF (5)
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
+#define CPUID5_ECX_INTERRUPT_BREAK     (0x2)
+static unsigned long power_saving_mwait_eax;
+static void power_saving_mwait_init(void)
+{
+       unsigned int eax, ebx, ecx, edx;
+       unsigned int highest_cstate = 0;
+       unsigned int highest_subcstate = 0;
+       int i;
+
+       if (!boot_cpu_has(X86_FEATURE_MWAIT))
+               return;
+       if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+               return;
+
+       cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
+
+       if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
+           !(ecx & CPUID5_ECX_INTERRUPT_BREAK))
+               return;
+
+       edx >>= MWAIT_SUBSTATE_SIZE;
+       for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
+               if (edx & MWAIT_SUBSTATE_MASK) {
+                       highest_cstate = i;
+                       highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
+               }
+       }
+       power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
+               (highest_subcstate - 1);
+
+       for_each_online_cpu(i)
+               clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i);
+
+#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
+       switch (boot_cpu_data.x86_vendor) {
+       case X86_VENDOR_AMD:
+       case X86_VENDOR_INTEL:
+               /*
+                * AMD Fam10h TSC will tick in all
+                * C/P/S0/S1 states when this bit is set.
+                */
+               if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
+                       return;
+
+               /*FALL THROUGH*/
+       default:
+               /* TSC could halt in idle, so notify users */
+               mark_tsc_unstable("TSC halts in idle");
+       }
+#endif
+}
+
+static unsigned long cpu_weight[NR_CPUS];
+static int tsk_in_cpu[NR_CPUS] = {[0 ... NR_CPUS-1] = -1};
+static DECLARE_BITMAP(pad_busy_cpus_bits, NR_CPUS);
+static void round_robin_cpu(unsigned int tsk_index)
+{
+       struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
+       cpumask_var_t tmp;
+       int cpu;
+       unsigned long min_weight = -1, preferred_cpu;
+
+       if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+               return;
+
+       mutex_lock(&isolated_cpus_lock);
+       cpumask_clear(tmp);
+       for_each_cpu(cpu, pad_busy_cpus)
+               cpumask_or(tmp, tmp, topology_thread_cpumask(cpu));
+       cpumask_andnot(tmp, cpu_online_mask, tmp);
+       /* avoid HT sibilings if possible */
+       if (cpumask_empty(tmp))
+               cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
+       if (cpumask_empty(tmp)) {
+               mutex_unlock(&isolated_cpus_lock);
+               return;
+       }
+       for_each_cpu(cpu, tmp) {
+               if (cpu_weight[cpu] < min_weight) {
+                       min_weight = cpu_weight[cpu];
+                       preferred_cpu = cpu;
+               }
+       }
+
+       if (tsk_in_cpu[tsk_index] != -1)
+               cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
+       tsk_in_cpu[tsk_index] = preferred_cpu;
+       cpumask_set_cpu(preferred_cpu, pad_busy_cpus);
+       cpu_weight[preferred_cpu]++;
+       mutex_unlock(&isolated_cpus_lock);
+
+       set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
+}
+
+static void exit_round_robin(unsigned int tsk_index)
+{
+       struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
+       cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
+       tsk_in_cpu[tsk_index] = -1;
+}
+
+static unsigned int idle_pct = 5; /* percentage */
+static unsigned int round_robin_time = 10; /* second */
+static int power_saving_thread(void *data)
+{
+       struct sched_param param = {.sched_priority = 1};
+       int do_sleep;
+       unsigned int tsk_index = (unsigned long)data;
+       u64 last_jiffies = 0;
+
+       sched_setscheduler(current, SCHED_RR, &param);
+
+       while (!kthread_should_stop()) {
+               int cpu;
+               u64 expire_time;
+
+               try_to_freeze();
+
+               /* round robin to cpus */
+               if (last_jiffies + round_robin_time * HZ < jiffies) {
+                       last_jiffies = jiffies;
+                       round_robin_cpu(tsk_index);
+               }
+
+               do_sleep = 0;
+
+               current_thread_info()->status &= ~TS_POLLING;
+               /*
+                * TS_POLLING-cleared state must be visible before we test
+                * NEED_RESCHED:
+                */
+               smp_mb();
+
+               expire_time = jiffies + HZ * (100 - idle_pct) / 100;
+
+               while (!need_resched()) {
+                       local_irq_disable();
+                       cpu = smp_processor_id();
+                       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+                               &cpu);
+                       stop_critical_timings();
+
+                       __monitor((void *)&current_thread_info()->flags, 0, 0);
+                       smp_mb();
+                       if (!need_resched())
+                               __mwait(power_saving_mwait_eax, 1);
+
+                       start_critical_timings();
+                       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+                               &cpu);
+                       local_irq_enable();
+
+                       if (jiffies > expire_time) {
+                               do_sleep = 1;
+                               break;
+                       }
+               }
+
+               current_thread_info()->status |= TS_POLLING;
+
+               /*
+                * current sched_rt has threshold for rt task running time.
+                * When a rt task uses 95% CPU time, the rt thread will be
+                * scheduled out for 5% CPU time to not starve other tasks. But
+                * the mechanism only works when all CPUs have RT task running,
+                * as if one CPU hasn't RT task, RT task from other CPUs will
+                * borrow CPU time from this CPU and cause RT task use > 95%
+                * CPU time. To make 'avoid staration' work, takes a nap here.
+                */
+               if (do_sleep)
+                       schedule_timeout_killable(HZ * idle_pct / 100);
+       }
+
+       exit_round_robin(tsk_index);
+       return 0;
+}
+
+static struct task_struct *ps_tsks[NR_CPUS];
+static unsigned int ps_tsk_num;
+static int create_power_saving_task(void)
+{
+       ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
+               (void *)(unsigned long)ps_tsk_num,
+               "power_saving/%d", ps_tsk_num);
+       if (ps_tsks[ps_tsk_num]) {
+               ps_tsk_num++;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static void destroy_power_saving_task(void)
+{
+       if (ps_tsk_num > 0) {
+               ps_tsk_num--;
+               kthread_stop(ps_tsks[ps_tsk_num]);
+       }
+}
+
+static void set_power_saving_task_num(unsigned int num)
+{
+       if (num > ps_tsk_num) {
+               while (ps_tsk_num < num) {
+                       if (create_power_saving_task())
+                               return;
+               }
+       } else if (num < ps_tsk_num) {
+               while (ps_tsk_num > num)
+                       destroy_power_saving_task();
+       }
+}
+
+static int acpi_pad_idle_cpus(unsigned int num_cpus)
+{
+       get_online_cpus();
+
+       num_cpus = min_t(unsigned int, num_cpus, num_online_cpus());
+       set_power_saving_task_num(num_cpus);
+
+       put_online_cpus();
+       return 0;
+}
+
+static uint32_t acpi_pad_idle_cpus_num(void)
+{
+       return ps_tsk_num;
+}
+
+static ssize_t acpi_pad_rrtime_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long num;
+       if (strict_strtoul(buf, 0, &num))
+               return -EINVAL;
+       if (num < 1 || num >= 100)
+               return -EINVAL;
+       mutex_lock(&isolated_cpus_lock);
+       round_robin_time = num;
+       mutex_unlock(&isolated_cpus_lock);
+       return count;
+}
+
+static ssize_t acpi_pad_rrtime_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time);
+}
+static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR,
+       acpi_pad_rrtime_show,
+       acpi_pad_rrtime_store);
+
+static ssize_t acpi_pad_idlepct_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long num;
+       if (strict_strtoul(buf, 0, &num))
+               return -EINVAL;
+       if (num < 1 || num >= 100)
+               return -EINVAL;
+       mutex_lock(&isolated_cpus_lock);
+       idle_pct = num;
+       mutex_unlock(&isolated_cpus_lock);
+       return count;
+}
+
+static ssize_t acpi_pad_idlepct_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return scnprintf(buf, PAGE_SIZE, "%d", idle_pct);
+}
+static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR,
+       acpi_pad_idlepct_show,
+       acpi_pad_idlepct_store);
+
+static ssize_t acpi_pad_idlecpus_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long num;
+       if (strict_strtoul(buf, 0, &num))
+               return -EINVAL;
+       mutex_lock(&isolated_cpus_lock);
+       acpi_pad_idle_cpus(num);
+       mutex_unlock(&isolated_cpus_lock);
+       return count;
+}
+
+static ssize_t acpi_pad_idlecpus_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return cpumask_scnprintf(buf, PAGE_SIZE,
+               to_cpumask(pad_busy_cpus_bits));
+}
+static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR,
+       acpi_pad_idlecpus_show,
+       acpi_pad_idlecpus_store);
+
+static int acpi_pad_add_sysfs(struct acpi_device *device)
+{
+       int result;
+
+       result = device_create_file(&device->dev, &dev_attr_idlecpus);
+       if (result)
+               return -ENODEV;
+       result = device_create_file(&device->dev, &dev_attr_idlepct);
+       if (result) {
+               device_remove_file(&device->dev, &dev_attr_idlecpus);
+               return -ENODEV;
+       }
+       result = device_create_file(&device->dev, &dev_attr_rrtime);
+       if (result) {
+               device_remove_file(&device->dev, &dev_attr_idlecpus);
+               device_remove_file(&device->dev, &dev_attr_idlepct);
+               return -ENODEV;
+       }
+       return 0;
+}
+
+static void acpi_pad_remove_sysfs(struct acpi_device *device)
+{
+       device_remove_file(&device->dev, &dev_attr_idlecpus);
+       device_remove_file(&device->dev, &dev_attr_idlepct);
+       device_remove_file(&device->dev, &dev_attr_rrtime);
+}
+
+/* Query firmware how many CPUs should be idle */
+static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
+{
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       acpi_status status;
+       union acpi_object *package;
+       int rev, num, ret = -EINVAL;
+
+       status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
+       if (ACPI_FAILURE(status))
+               return -EINVAL;
+       package = buffer.pointer;
+       if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
+               goto out;
+       rev = package->package.elements[0].integer.value;
+       num = package->package.elements[1].integer.value;
+       if (rev != 1)
+               goto out;
+       *num_cpus = num;
+       ret = 0;
+out:
+       kfree(buffer.pointer);
+       return ret;
+}
+
+/* Notify firmware how many CPUs are idle */
+static void acpi_pad_ost(acpi_handle handle, int stat,
+       uint32_t idle_cpus)
+{
+       union acpi_object params[3] = {
+               {.type = ACPI_TYPE_INTEGER,},
+               {.type = ACPI_TYPE_INTEGER,},
+               {.type = ACPI_TYPE_BUFFER,},
+       };
+       struct acpi_object_list arg_list = {3, params};
+
+       params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY;
+       params[1].integer.value =  stat;
+       params[2].buffer.length = 4;
+       params[2].buffer.pointer = (void *)&idle_cpus;
+       acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
+}
+
+static void acpi_pad_handle_notify(acpi_handle handle)
+{
+       int num_cpus, ret;
+       uint32_t idle_cpus;
+
+       mutex_lock(&isolated_cpus_lock);
+       if (acpi_pad_pur(handle, &num_cpus)) {
+               mutex_unlock(&isolated_cpus_lock);
+               return;
+       }
+       ret = acpi_pad_idle_cpus(num_cpus);
+       idle_cpus = acpi_pad_idle_cpus_num();
+       if (!ret)
+               acpi_pad_ost(handle, 0, idle_cpus);
+       else
+               acpi_pad_ost(handle, 1, 0);
+       mutex_unlock(&isolated_cpus_lock);
+}
+
+static void acpi_pad_notify(acpi_handle handle, u32 event,
+       void *data)
+{
+       struct acpi_device *device = data;
+
+       switch (event) {
+       case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
+               acpi_pad_handle_notify(handle);
+               acpi_bus_generate_proc_event(device, event, 0);
+               acpi_bus_generate_netlink_event(device->pnp.device_class,
+                       dev_name(&device->dev), event, 0);
+               break;
+       default:
+               printk(KERN_WARNING"Unsupported event [0x%x]\n", event);
+               break;
+       }
+}
+
+static int acpi_pad_add(struct acpi_device *device)
+{
+       acpi_status status;
+
+       strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
+       strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS);
+
+       if (acpi_pad_add_sysfs(device))
+               return -ENODEV;
+
+       status = acpi_install_notify_handler(device->handle,
+               ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
+       if (ACPI_FAILURE(status)) {
+               acpi_pad_remove_sysfs(device);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int acpi_pad_remove(struct acpi_device *device,
+       int type)
+{
+       mutex_lock(&isolated_cpus_lock);
+       acpi_pad_idle_cpus(0);
+       mutex_unlock(&isolated_cpus_lock);
+
+       acpi_remove_notify_handler(device->handle,
+               ACPI_DEVICE_NOTIFY, acpi_pad_notify);
+       acpi_pad_remove_sysfs(device);
+       return 0;
+}
+
+static const struct acpi_device_id pad_device_ids[] = {
+       {"ACPI000C", 0},
+       {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, pad_device_ids);
+
+static struct acpi_driver acpi_pad_driver = {
+       .name = "processor_aggregator",
+       .class = ACPI_PROCESSOR_AGGREGATOR_CLASS,
+       .ids = pad_device_ids,
+       .ops = {
+               .add = acpi_pad_add,
+               .remove = acpi_pad_remove,
+       },
+};
+
+static int __init acpi_pad_init(void)
+{
+       power_saving_mwait_init();
+       if (power_saving_mwait_eax == 0)
+               return -EINVAL;
+
+       return acpi_bus_register_driver(&acpi_pad_driver);
+}
+
+static void __exit acpi_pad_exit(void)
+{
+       acpi_bus_unregister_driver(&acpi_pad_driver);
+}
+
+module_init(acpi_pad_init);
+module_exit(acpi_pad_exit);
+MODULE_AUTHOR("Shaohua Li<shaohua.li@intel.com>");
+MODULE_DESCRIPTION("ACPI Processor Aggregator Driver");
+MODULE_LICENSE("GPL");
index 3a2cfefc71ab1ab5da484b47bd9bd7f28aee988a..7338b6a3e049aa061d00bf13b469ffb086d5276a 100644 (file)
@@ -67,7 +67,7 @@ struct dock_station {
        struct list_head dependent_devices;
        struct list_head hotplug_devices;
 
-       struct list_head sibiling;
+       struct list_head sibling;
        struct platform_device *dock_device;
 };
 static LIST_HEAD(dock_stations);
@@ -275,7 +275,7 @@ int is_dock_device(acpi_handle handle)
 
        if (is_dock(handle))
                return 1;
-       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+       list_for_each_entry(dock_station, &dock_stations, sibling) {
                if (find_dock_dependent_device(dock_station, handle))
                        return 1;
        }
@@ -619,7 +619,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
         * make sure this handle is for a device dependent on the dock,
         * this would include the dock station itself
         */
-       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+       list_for_each_entry(dock_station, &dock_stations, sibling) {
                /*
                 * An ATA bay can be in a dock and itself can be ejected
                 * seperately, so there are two 'dock stations' which need the
@@ -651,7 +651,7 @@ void unregister_hotplug_dock_device(acpi_handle handle)
        if (!dock_station_count)
                return;
 
-       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+       list_for_each_entry(dock_station, &dock_stations, sibling) {
                dd = find_dock_dependent_device(dock_station, handle);
                if (dd)
                        dock_del_hotplug_device(dock_station, dd);
@@ -787,7 +787,7 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
        if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
           && event != ACPI_NOTIFY_EJECT_REQUEST)
                return 0;
-       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+       list_for_each_entry(dock_station, &dock_stations, sibling) {
                if (dock_station->handle == handle) {
                        struct dock_data *dock_data;
 
@@ -958,7 +958,7 @@ static int dock_add(acpi_handle handle)
        dock_station->last_dock_time = jiffies - HZ;
        INIT_LIST_HEAD(&dock_station->dependent_devices);
        INIT_LIST_HEAD(&dock_station->hotplug_devices);
-       INIT_LIST_HEAD(&dock_station->sibiling);
+       INIT_LIST_HEAD(&dock_station->sibling);
        spin_lock_init(&dock_station->dd_lock);
        mutex_init(&dock_station->hp_lock);
        ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
@@ -1044,7 +1044,7 @@ static int dock_add(acpi_handle handle)
        add_dock_dependent_device(dock_station, dd);
 
        dock_station_count++;
-       list_add(&dock_station->sibiling, &dock_stations);
+       list_add(&dock_station->sibling, &dock_stations);
        return 0;
 
 dock_add_err_unregister:
@@ -1149,7 +1149,7 @@ static void __exit dock_exit(void)
        struct dock_station *tmp;
 
        unregister_acpi_bus_notifier(&dock_acpi_notifier);
-       list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
+       list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)
                dock_remove(dock_station);
 }
 
index f70796081c4c0ad93c0e5c751cc2297b81dea9f4..baef28c1e63090c8b10c5e661257390c52f275b7 100644 (file)
@@ -119,6 +119,8 @@ static struct acpi_ec {
 } *boot_ec, *first_ec;
 
 static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
+static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
+static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
 
 /* --------------------------------------------------------------------------
                              Transaction Management
@@ -232,10 +234,8 @@ static int ec_poll(struct acpi_ec *ec)
                        }
                        advance_transaction(ec, acpi_ec_read_status(ec));
                } while (time_before(jiffies, delay));
-               if (!ec->curr->irq_count ||
-                   (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
+               if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
                        break;
-               /* try restart command if we get any false interrupts */
                pr_debug(PREFIX "controller reset, restart transaction\n");
                spin_lock_irqsave(&ec->curr_lock, flags);
                start_transaction(ec);
@@ -899,6 +899,44 @@ static const struct acpi_device_id ec_device_ids[] = {
        {"", 0},
 };
 
+/* Some BIOS do not survive early DSDT scan, skip it */
+static int ec_skip_dsdt_scan(const struct dmi_system_id *id)
+{
+       EC_FLAGS_SKIP_DSDT_SCAN = 1;
+       return 0;
+}
+
+/* ASUStek often supplies us with broken ECDT, validate it */
+static int ec_validate_ecdt(const struct dmi_system_id *id)
+{
+       EC_FLAGS_VALIDATE_ECDT = 1;
+       return 0;
+}
+
+/* MSI EC needs special treatment, enable it */
+static int ec_flag_msi(const struct dmi_system_id *id)
+{
+       EC_FLAGS_MSI = 1;
+       EC_FLAGS_VALIDATE_ECDT = 1;
+       return 0;
+}
+
+static struct dmi_system_id __initdata ec_dmi_table[] = {
+       {
+       ec_skip_dsdt_scan, "Compal JFL92", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+       DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL},
+       {
+       ec_flag_msi, "MSI hardware", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
+       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
+       {
+       ec_validate_ecdt, "ASUS hardware", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
+       {},
+};
+
+
 int __init acpi_ec_ecdt_probe(void)
 {
        acpi_status status;
@@ -911,11 +949,7 @@ int __init acpi_ec_ecdt_probe(void)
        /*
         * Generate a boot ec context
         */
-       if (dmi_name_in_vendors("Micro-Star") ||
-           dmi_name_in_vendors("Notebook")) {
-               pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
-               EC_FLAGS_MSI = 1;
-       }
+       dmi_check_system(ec_dmi_table);
        status = acpi_get_table(ACPI_SIG_ECDT, 1,
                                (struct acpi_table_header **)&ecdt_ptr);
        if (ACPI_SUCCESS(status)) {
@@ -926,7 +960,7 @@ int __init acpi_ec_ecdt_probe(void)
                boot_ec->handle = ACPI_ROOT_OBJECT;
                acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
                /* Don't trust ECDT, which comes from ASUSTek */
-               if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
+               if (!EC_FLAGS_VALIDATE_ECDT)
                        goto install;
                saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
                if (!saved_ec)
@@ -934,6 +968,10 @@ int __init acpi_ec_ecdt_probe(void)
                memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
        /* fall through */
        }
+
+       if (EC_FLAGS_SKIP_DSDT_SCAN)
+               return -ENODEV;
+
        /* This workaround is needed only on some broken machines,
         * which require early EC, but fail to provide ECDT */
        printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
index d0d550d22a6d43a14ccecec6658e9fb2773d6b70..f8b6f555ba52ba328d43efca6c5926831a663d06 100644 (file)
@@ -398,6 +398,8 @@ acpi_system_write_wakeup_device(struct file *file,
 
        if (len > 4)
                len = 4;
+       if (len < 0)
+               return -EFAULT;
 
        if (copy_from_user(strbuf, buffer, len))
                return -EFAULT;
index c2d4d6e0936469a8ef5e80a11dd36a99d7be761e..c567b46dfa0f78a83bc1e0d0feb77e79516cfb42 100644 (file)
@@ -863,13 +863,6 @@ static int acpi_processor_add(struct acpi_device *device)
                goto err_remove_sysfs;
        }
 
-       if (pr->flags.throttling) {
-               printk(KERN_INFO PREFIX "%s [%s] (supports",
-                      acpi_device_name(device), acpi_device_bid(device));
-               printk(" %d throttling states", pr->throttling.state_count);
-               printk(")\n");
-       }
-
        return 0;
 
 err_remove_sysfs:
index 468921bed22f4e33f9012592fe906c3ca9ba3a1d..14a7481c97d71bdc2abd18e3c695cf72e8a9aee5 100644 (file)
@@ -1052,6 +1052,8 @@ static void acpi_device_set_id(struct acpi_device *device)
                        device->flags.bus_address = 1;
                }
 
+               kfree(info);
+
                /*
                 * Some devices don't reliably have _HIDs & _CIDs, so add
                 * synthetic HIDs to make sure drivers can find them.
@@ -1325,13 +1327,8 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
                         struct acpi_device **child)
 {
        acpi_status status;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        void *device = NULL;
 
-       acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-       printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n",
-              (char *) buffer.pointer);
-
        status = acpi_bus_check_add(handle, 0, ops, &device);
        if (ACPI_SUCCESS(status))
                acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
index a4fddb24476fdba0bc1ebbafd510aaa3544595d1..f6e54bf8dd96e5d5767547bad753a22da03a52e0 100644 (file)
@@ -285,7 +285,7 @@ static int acpi_video_device_brightness_open_fs(struct inode *inode,
                                                struct file *file);
 static ssize_t acpi_video_device_write_brightness(struct file *file,
        const char __user *buffer, size_t count, loff_t *data);
-static struct file_operations acpi_video_device_brightness_fops = {
+static const struct file_operations acpi_video_device_brightness_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_brightness_open_fs,
        .read = seq_read,
index 703364b52170fa2f4728ff135d38bc2be8cb6e48..66e181345b3af8355287f006a622b874cb2a2f78 100644 (file)
@@ -1306,14 +1306,6 @@ static void amb_close (struct atm_vcc * atm_vcc) {
   return;
 }
 
-/********** Set socket options for a VC **********/
-
-// int amb_getsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);
-
-/********** Set socket options for a VC **********/
-
-// int amb_setsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);
-
 /********** Send **********/
 
 static int amb_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
index 5503bfc8e1320e0a362b2f4ffd57e043104ca1d7..0c302614544382992bf67fb656a001cffa9c5edd 100644 (file)
@@ -2031,7 +2031,7 @@ static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
 
 
 static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
-    void __user *optval,int optlen)
+    void __user *optval,unsigned int optlen)
 {
        return -EINVAL;
 }
index b119640e1ee9d0f6403aae0a3156405e6a72c7bc..cd5049af47a9a11144d58e8cceed873c2bfb2483 100644 (file)
@@ -1244,7 +1244,7 @@ static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
 
 
 static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
-                        void __user *optval,int optlen)
+                        void __user *optval,unsigned int optlen)
 {
        func_enter ();
        func_exit ();
index 10f000dbe448e149e599caf2eeda9f7ec1b2a6bf..f766cc46b4c4346ae3a08897af1563097001ec0a 100644 (file)
@@ -1795,7 +1795,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *op
 
 
 static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
+fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
 {
     /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
     
index 01ce241dbeae81423aed5bd2a49e784f9cff057c..4e49021e67ee465b5ecc8ffb312e1c7a88399431 100644 (file)
@@ -2590,7 +2590,7 @@ static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
 }
 
 static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
-                          void *optval, int optlen) {
+                          void *optval, unsigned int optlen) {
   hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
   PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
   switch (level) {
index 78c9736c3579beba974dc546cbd4bfbe8298bcf4..b2c1b37ab2e4dbb2ea5370a8637c9975af9e3146 100644 (file)
@@ -2862,7 +2862,7 @@ static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
 }  
   
 static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,   
-       void __user *optval, int optlen)  
+       void __user *optval, unsigned int optlen)  
 {  
        IF_EVENT(printk(">ia_setsockopt\n");)  
        return -EINVAL;  
index 752b1ba81f7e9bbd5ff56944723ae6740318dad5..2e9635be048c2fdb4e8b4773a49464558ba4f351 100644 (file)
@@ -1517,7 +1517,7 @@ static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
 
 
 static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
-    void __user *optval,int optlen)
+    void __user *optval,unsigned int optlen)
 {
        return -EINVAL;
 }
index 6fa7b0fdbdfd172f2e10f27bc82660c9201f3234..eb4fa19439444097875d8492ceb6996569e40d45 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/reboot.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
@@ -6422,16 +6423,10 @@ static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
   return true;
 }
 
-
-/*
-  DAC960_ProcReadStatus implements reading /proc/rd/status.
-*/
-
-static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
-                                int Count, int *EOF, void *Data)
+static int dac960_proc_show(struct seq_file *m, void *v)
 {
   unsigned char *StatusMessage = "OK\n";
-  int ControllerNumber, BytesAvailable;
+  int ControllerNumber;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
@@ -6444,52 +6439,49 @@ static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
          break;
        }
     }
-  BytesAvailable = strlen(StatusMessage) - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &StatusMessage[Offset], Count);
-  return Count;
+  seq_puts(m, StatusMessage);
+  return 0;
 }
 
+static int dac960_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_proc_show, NULL);
+}
 
-/*
-  DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
-*/
+static const struct file_operations dac960_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
-                                       int Count, int *EOF, void *Data)
+static int dac960_initial_status_proc_show(struct seq_file *m, void *v)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
-  int BytesAvailable = Controller->InitialStatusLength - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
-  return Count;
+       DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
+       seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer);
+       return 0;
 }
 
+static int dac960_initial_status_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data);
+}
 
-/*
-  DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
-*/
+static const struct file_operations dac960_initial_status_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_initial_status_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
-                                       int Count, int *EOF, void *Data)
+static int dac960_current_status_proc_show(struct seq_file *m, void *v)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private;
   unsigned char *StatusMessage =
     "No Rebuild or Consistency Check in Progress\n";
   int ProgressMessageLength = strlen(StatusMessage);
-  int BytesAvailable;
   if (jiffies != Controller->LastCurrentStatusTime)
     {
       Controller->CurrentStatusLength = 0;
@@ -6513,49 +6505,41 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
        }
       Controller->LastCurrentStatusTime = jiffies;
     }
-  BytesAvailable = Controller->CurrentStatusLength - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
-  return Count;
+       seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer);
+       return 0;
 }
 
+static int dac960_current_status_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_current_status_proc_show, PDE(inode)->data);
+}
 
-/*
-  DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
-*/
+static const struct file_operations dac960_current_status_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_current_status_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
-                                     int Count, int *EOF, void *Data)
+static int dac960_user_command_proc_show(struct seq_file *m, void *v)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
-  int BytesAvailable = Controller->UserStatusLength - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
-  return Count;
-}
+       DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
 
+       seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer);
+       return 0;
+}
 
-/*
-  DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
-*/
+static int dac960_user_command_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_user_command_proc_show, PDE(inode)->data);
+}
 
-static int DAC960_ProcWriteUserCommand(struct file *file,
+static ssize_t dac960_user_command_proc_write(struct file *file,
                                       const char __user *Buffer,
-                                      unsigned long Count, void *Data)
+                                      size_t Count, loff_t *pos)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data;
   unsigned char CommandBuffer[80];
   int Length;
   if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
@@ -6572,6 +6556,14 @@ static int DAC960_ProcWriteUserCommand(struct file *file,
            ? Count : -EBUSY);
 }
 
+static const struct file_operations dac960_user_command_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_user_command_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = dac960_user_command_proc_write,
+};
 
 /*
   DAC960_CreateProcEntries creates the /proc/rd/... entries for the
@@ -6586,23 +6578,17 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
 
        if (DAC960_ProcDirectoryEntry == NULL) {
                DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
-               StatusProcEntry = create_proc_read_entry("status", 0,
+               StatusProcEntry = proc_create("status", 0,
                                           DAC960_ProcDirectoryEntry,
-                                          DAC960_ProcReadStatus, NULL);
+                                          &dac960_proc_fops);
        }
 
       sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
       ControllerProcEntry = proc_mkdir(Controller->ControllerName,
                                       DAC960_ProcDirectoryEntry);
-      create_proc_read_entry("initial_status", 0, ControllerProcEntry,
-                            DAC960_ProcReadInitialStatus, Controller);
-      create_proc_read_entry("current_status", 0, ControllerProcEntry,
-                            DAC960_ProcReadCurrentStatus, Controller);
-      UserCommandProcEntry =
-       create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
-                              ControllerProcEntry, DAC960_ProcReadUserCommand,
-                              Controller);
-      UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
+      proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);
+      proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller);
+      UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller);
       Controller->ControllerProcEntry = ControllerProcEntry;
 }
 
index 24c3e21ab263a6a685356f7d17ac5c0c097e60b6..fb5be2d95d52c57a8ac8aab4f0375579a8852de6 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
 #include <linux/compat.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -155,6 +157,10 @@ static struct board_type products[] = {
 
 static ctlr_info_t *hba[MAX_CTLR];
 
+static struct task_struct *cciss_scan_thread;
+static DEFINE_MUTEX(scan_mutex);
+static LIST_HEAD(scan_q);
+
 static void do_cciss_request(struct request_queue *q);
 static irqreturn_t do_cciss_intr(int irq, void *dev_id);
 static int cciss_open(struct block_device *bdev, fmode_t mode);
@@ -164,9 +170,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
 static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 static int cciss_revalidate(struct gendisk *disk);
-static int rebuild_lun_table(ctlr_info_t *h, int first_time);
+static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl);
 static int deregister_disk(ctlr_info_t *h, int drv_index,
-                          int clear_all);
+                          int clear_all, int via_ioctl);
 
 static void cciss_read_capacity(int ctlr, int logvol, int withirq,
                        sector_t *total_size, unsigned int *block_size);
@@ -189,8 +195,13 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c,
 static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c);
 
 static void fail_all_cmds(unsigned long ctlr);
+static int add_to_scan_list(struct ctlr_info *h);
 static int scan_thread(void *data);
 static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
+static void cciss_hba_release(struct device *dev);
+static void cciss_device_release(struct device *dev);
+static void cciss_free_gendisk(ctlr_info_t *h, int drv_index);
+static void cciss_free_drive_info(ctlr_info_t *h, int drv_index);
 
 #ifdef CONFIG_PROC_FS
 static void cciss_procinit(int i);
@@ -245,7 +256,10 @@ static inline void removeQ(CommandList_struct *c)
 
 #include "cciss_scsi.c"                /* For SCSI tape support */
 
-#define RAID_UNKNOWN 6
+static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
+       "UNKNOWN"
+};
+#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1)
 
 #ifdef CONFIG_PROC_FS
 
@@ -255,9 +269,6 @@ static inline void removeQ(CommandList_struct *c)
 #define ENG_GIG 1000000000
 #define ENG_GIG_FACTOR (ENG_GIG/512)
 #define ENGAGE_SCSI    "engage scsi"
-static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
-       "UNKNOWN"
-};
 
 static struct proc_dir_entry *proc_cciss;
 
@@ -318,7 +329,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
        ctlr_info_t *h = seq->private;
        unsigned ctlr = h->ctlr;
        loff_t *pos = v;
-       drive_info_struct *drv = &h->drv[*pos];
+       drive_info_struct *drv = h->drv[*pos];
 
        if (*pos > h->highest_lun)
                return 0;
@@ -331,7 +342,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
        vol_sz_frac *= 100;
        sector_div(vol_sz_frac, ENG_GIG_FACTOR);
 
-       if (drv->raid_level > 5)
+       if (drv->raid_level < 0 || drv->raid_level > RAID_UNKNOWN)
                drv->raid_level = RAID_UNKNOWN;
        seq_printf(seq, "cciss/c%dd%d:"
                        "\t%4u.%02uGB\tRAID %s\n",
@@ -426,7 +437,7 @@ out:
        return err;
 }
 
-static struct file_operations cciss_proc_fops = {
+static const struct file_operations cciss_proc_fops = {
        .owner   = THIS_MODULE,
        .open    = cciss_seq_open,
        .read    = seq_read,
@@ -454,9 +465,19 @@ static void __devinit cciss_procinit(int i)
 #define to_hba(n) container_of(n, struct ctlr_info, dev)
 #define to_drv(n) container_of(n, drive_info_struct, dev)
 
-static struct device_type cciss_host_type = {
-       .name           = "cciss_host",
-};
+static ssize_t host_store_rescan(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t count)
+{
+       struct ctlr_info *h = to_hba(dev);
+
+       add_to_scan_list(h);
+       wake_up_process(cciss_scan_thread);
+       wait_for_completion_interruptible(&h->scan_wait);
+
+       return count;
+}
+DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
 
 static ssize_t dev_show_unique_id(struct device *dev,
                                 struct device_attribute *attr,
@@ -560,11 +581,101 @@ static ssize_t dev_show_rev(struct device *dev,
 }
 DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
 
+static ssize_t cciss_show_lunid(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       drive_info_struct *drv = to_drv(dev);
+       struct ctlr_info *h = to_hba(drv->dev.parent);
+       unsigned long flags;
+       unsigned char lunid[8];
+
+       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       if (h->busy_configuring) {
+               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               return -EBUSY;
+       }
+       if (!drv->heads) {
+               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               return -ENOTTY;
+       }
+       memcpy(lunid, drv->LunID, sizeof(lunid));
+       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+               lunid[0], lunid[1], lunid[2], lunid[3],
+               lunid[4], lunid[5], lunid[6], lunid[7]);
+}
+DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
+
+static ssize_t cciss_show_raid_level(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       drive_info_struct *drv = to_drv(dev);
+       struct ctlr_info *h = to_hba(drv->dev.parent);
+       int raid;
+       unsigned long flags;
+
+       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       if (h->busy_configuring) {
+               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               return -EBUSY;
+       }
+       raid = drv->raid_level;
+       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       if (raid < 0 || raid > RAID_UNKNOWN)
+               raid = RAID_UNKNOWN;
+
+       return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n",
+                       raid_label[raid]);
+}
+DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
+
+static ssize_t cciss_show_usage_count(struct device *dev,
+                                     struct device_attribute *attr, char *buf)
+{
+       drive_info_struct *drv = to_drv(dev);
+       struct ctlr_info *h = to_hba(drv->dev.parent);
+       unsigned long flags;
+       int count;
+
+       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       if (h->busy_configuring) {
+               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               return -EBUSY;
+       }
+       count = drv->usage_count;
+       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       return snprintf(buf, 20, "%d\n", count);
+}
+DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
+
+static struct attribute *cciss_host_attrs[] = {
+       &dev_attr_rescan.attr,
+       NULL
+};
+
+static struct attribute_group cciss_host_attr_group = {
+       .attrs = cciss_host_attrs,
+};
+
+static const struct attribute_group *cciss_host_attr_groups[] = {
+       &cciss_host_attr_group,
+       NULL
+};
+
+static struct device_type cciss_host_type = {
+       .name           = "cciss_host",
+       .groups         = cciss_host_attr_groups,
+       .release        = cciss_hba_release,
+};
+
 static struct attribute *cciss_dev_attrs[] = {
        &dev_attr_unique_id.attr,
        &dev_attr_model.attr,
        &dev_attr_vendor.attr,
        &dev_attr_rev.attr,
+       &dev_attr_lunid.attr,
+       &dev_attr_raid_level.attr,
+       &dev_attr_usage_count.attr,
        NULL
 };
 
@@ -580,12 +691,24 @@ static const struct attribute_group *cciss_dev_attr_groups[] = {
 static struct device_type cciss_dev_type = {
        .name           = "cciss_device",
        .groups         = cciss_dev_attr_groups,
+       .release        = cciss_device_release,
 };
 
 static struct bus_type cciss_bus_type = {
        .name           = "cciss",
 };
 
+/*
+ * cciss_hba_release is called when the reference count
+ * of h->dev goes to zero.
+ */
+static void cciss_hba_release(struct device *dev)
+{
+       /*
+        * nothing to do, but need this to avoid a warning
+        * about not having a release handler from lib/kref.c.
+        */
+}
 
 /*
  * Initialize sysfs entry for each controller.  This sets up and registers
@@ -609,6 +732,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h)
 static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
 {
        device_del(&h->dev);
+       put_device(&h->dev); /* final put. */
+}
+
+/* cciss_device_release is called when the reference count
+ * of h->drv[x]dev goes to zero.
+ */
+static void cciss_device_release(struct device *dev)
+{
+       drive_info_struct *drv = to_drv(dev);
+       kfree(drv);
 }
 
 /*
@@ -617,24 +750,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
  * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
  * /sys/block/cciss!c#d# to this entry.
  */
-static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
-                                      drive_info_struct *drv,
+static long cciss_create_ld_sysfs_entry(struct ctlr_info *h,
                                       int drv_index)
 {
-       device_initialize(&drv->dev);
-       drv->dev.type = &cciss_dev_type;
-       drv->dev.bus = &cciss_bus_type;
-       dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
-       drv->dev.parent = &h->dev;
-       return device_add(&drv->dev);
+       struct device *dev;
+
+       if (h->drv[drv_index]->device_initialized)
+               return 0;
+
+       dev = &h->drv[drv_index]->dev;
+       device_initialize(dev);
+       dev->type = &cciss_dev_type;
+       dev->bus = &cciss_bus_type;
+       dev_set_name(dev, "c%dd%d", h->ctlr, drv_index);
+       dev->parent = &h->dev;
+       h->drv[drv_index]->device_initialized = 1;
+       return device_add(dev);
 }
 
 /*
  * Remove sysfs entries for a logical drive.
  */
-static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv)
+static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index,
+       int ctlr_exiting)
 {
-       device_del(&drv->dev);
+       struct device *dev = &h->drv[drv_index]->dev;
+
+       /* special case for c*d0, we only destroy it on controller exit */
+       if (drv_index == 0 && !ctlr_exiting)
+               return;
+
+       device_del(dev);
+       put_device(dev); /* the "final" put. */
+       h->drv[drv_index] = NULL;
 }
 
 /*
@@ -751,7 +899,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
        printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
 #endif                         /* CCISS_DEBUG */
 
-       if (host->busy_initializing || drv->busy_configuring)
+       if (drv->busy_configuring)
                return -EBUSY;
        /*
         * Root is allowed to open raw volume zero even if it's not configured
@@ -767,7 +915,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
                        if (MINOR(bdev->bd_dev) & 0x0f) {
                                return -ENXIO;
                                /* if it is, make sure we have a LUN ID */
-                       } else if (drv->LunID == 0) {
+                       } else if (memcmp(drv->LunID, CTLR_LUNID,
+                               sizeof(drv->LunID))) {
                                return -ENXIO;
                        }
                }
@@ -1132,12 +1281,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
        case CCISS_DEREGDISK:
        case CCISS_REGNEWD:
        case CCISS_REVALIDVOLS:
-               return rebuild_lun_table(host, 0);
+               return rebuild_lun_table(host, 0, 1);
 
        case CCISS_GETLUNINFO:{
                        LogvolInfo_struct luninfo;
 
-                       luninfo.LunID = drv->LunID;
+                       memcpy(&luninfo.LunID, drv->LunID,
+                               sizeof(luninfo.LunID));
                        luninfo.num_opens = drv->usage_count;
                        luninfo.num_parts = 0;
                        if (copy_to_user(argp, &luninfo,
@@ -1475,7 +1625,10 @@ static void cciss_check_queues(ctlr_info_t *h)
                /* make sure the disk has been added and the drive is real
                 * because this can be called from the middle of init_one.
                 */
-               if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
+               if (!h->drv[curr_queue])
+                       continue;
+               if (!(h->drv[curr_queue]->queue) ||
+                       !(h->drv[curr_queue]->heads))
                        continue;
                blk_start_queue(h->gendisk[curr_queue]->queue);
 
@@ -1532,13 +1685,11 @@ static void cciss_softirq_done(struct request *rq)
        spin_unlock_irqrestore(&h->lock, flags);
 }
 
-static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[],
-       uint32_t log_unit)
+static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
+       unsigned char scsi3addr[], uint32_t log_unit)
 {
-       log_unit = h->drv[log_unit].LunID & 0x03fff;
-       memset(&scsi3addr[4], 0, 4);
-       memcpy(&scsi3addr[0], &log_unit, 4);
-       scsi3addr[3] |= 0x40;
+       memcpy(scsi3addr, h->drv[log_unit]->LunID,
+               sizeof(h->drv[log_unit]->LunID));
 }
 
 /* This function gets the SCSI vendor, model, and revision of a logical drive
@@ -1615,16 +1766,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq,
        return;
 }
 
-static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
+/*
+ * cciss_add_disk sets up the block device queue for a logical drive
+ */
+static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
                                int drv_index)
 {
        disk->queue = blk_init_queue(do_cciss_request, &h->lock);
+       if (!disk->queue)
+               goto init_queue_failure;
        sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index);
        disk->major = h->major;
        disk->first_minor = drv_index << NWD_SHIFT;
        disk->fops = &cciss_fops;
-       disk->private_data = &h->drv[drv_index];
-       disk->driverfs_dev = &h->drv[drv_index].dev;
+       if (cciss_create_ld_sysfs_entry(h, drv_index))
+               goto cleanup_queue;
+       disk->private_data = h->drv[drv_index];
+       disk->driverfs_dev = &h->drv[drv_index]->dev;
 
        /* Set up queue information */
        blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
@@ -1642,14 +1800,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
        disk->queue->queuedata = h;
 
        blk_queue_logical_block_size(disk->queue,
-                                    h->drv[drv_index].block_size);
+                                    h->drv[drv_index]->block_size);
 
        /* Make sure all queue data is written out before */
-       /* setting h->drv[drv_index].queue, as setting this */
+       /* setting h->drv[drv_index]->queue, as setting this */
        /* allows the interrupt handler to start the queue */
        wmb();
-       h->drv[drv_index].queue = disk->queue;
+       h->drv[drv_index]->queue = disk->queue;
        add_disk(disk);
+       return 0;
+
+cleanup_queue:
+       blk_cleanup_queue(disk->queue);
+       disk->queue = NULL;
+init_queue_failure:
+       return -1;
 }
 
 /* This function will check the usage_count of the drive to be updated/added.
@@ -1662,7 +1827,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
  * is also the controller node.  Any changes to disk 0 will show up on
  * the next reboot.
  */
-static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
+static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
+       int via_ioctl)
 {
        ctlr_info_t *h = hba[ctlr];
        struct gendisk *disk;
@@ -1672,21 +1838,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
        unsigned long flags = 0;
        int ret = 0;
        drive_info_struct *drvinfo;
-       int was_only_controller_node;
 
        /* Get information about the disk and modify the driver structure */
        inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
-       drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL);
+       drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL);
        if (inq_buff == NULL || drvinfo == NULL)
                goto mem_msg;
 
-       /* See if we're trying to update the "controller node"
-        * this will happen the when the first logical drive gets
-        * created by ACU.
-        */
-       was_only_controller_node = (drv_index == 0 &&
-                               h->drv[0].raid_level == -1);
-
        /* testing to see if 16-byte CDBs are already being used */
        if (h->cciss_read == CCISS_READ_16) {
                cciss_read_capacity_16(h->ctlr, drv_index, 1,
@@ -1719,16 +1877,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
                                drvinfo->model, drvinfo->rev);
        cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
                        sizeof(drvinfo->serial_no));
+       /* Save the lunid in case we deregister the disk, below. */
+       memcpy(drvinfo->LunID, h->drv[drv_index]->LunID,
+               sizeof(drvinfo->LunID));
 
        /* Is it the same disk we already know, and nothing's changed? */
-       if (h->drv[drv_index].raid_level != -1 &&
+       if (h->drv[drv_index]->raid_level != -1 &&
                ((memcmp(drvinfo->serial_no,
-                               h->drv[drv_index].serial_no, 16) == 0) &&
-               drvinfo->block_size == h->drv[drv_index].block_size &&
-               drvinfo->nr_blocks == h->drv[drv_index].nr_blocks &&
-               drvinfo->heads == h->drv[drv_index].heads &&
-               drvinfo->sectors == h->drv[drv_index].sectors &&
-               drvinfo->cylinders == h->drv[drv_index].cylinders))
+                               h->drv[drv_index]->serial_no, 16) == 0) &&
+               drvinfo->block_size == h->drv[drv_index]->block_size &&
+               drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks &&
+               drvinfo->heads == h->drv[drv_index]->heads &&
+               drvinfo->sectors == h->drv[drv_index]->sectors &&
+               drvinfo->cylinders == h->drv[drv_index]->cylinders))
                        /* The disk is unchanged, nothing to update */
                        goto freeret;
 
@@ -1738,18 +1899,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
         * If the disk already exists then deregister it before proceeding
         * (unless it's the first disk (for the controller node).
         */
-       if (h->drv[drv_index].raid_level != -1 && drv_index != 0) {
+       if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) {
                printk(KERN_WARNING "disk %d has changed.\n", drv_index);
                spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
-               h->drv[drv_index].busy_configuring = 1;
+               h->drv[drv_index]->busy_configuring = 1;
                spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 
-               /* deregister_disk sets h->drv[drv_index].queue = NULL
+               /* deregister_disk sets h->drv[drv_index]->queue = NULL
                 * which keeps the interrupt handler from starting
                 * the queue.
                 */
-               ret = deregister_disk(h, drv_index, 0);
-               h->drv[drv_index].busy_configuring = 0;
+               ret = deregister_disk(h, drv_index, 0, via_ioctl);
        }
 
        /* If the disk is in use return */
@@ -1757,22 +1917,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
                goto freeret;
 
        /* Save the new information from cciss_geometry_inquiry
-        * and serial number inquiry.
+        * and serial number inquiry.  If the disk was deregistered
+        * above, then h->drv[drv_index] will be NULL.
         */
-       h->drv[drv_index].block_size = drvinfo->block_size;
-       h->drv[drv_index].nr_blocks = drvinfo->nr_blocks;
-       h->drv[drv_index].heads = drvinfo->heads;
-       h->drv[drv_index].sectors = drvinfo->sectors;
-       h->drv[drv_index].cylinders = drvinfo->cylinders;
-       h->drv[drv_index].raid_level = drvinfo->raid_level;
-       memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16);
-       memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1);
-       memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1);
-       memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1);
+       if (h->drv[drv_index] == NULL) {
+               drvinfo->device_initialized = 0;
+               h->drv[drv_index] = drvinfo;
+               drvinfo = NULL; /* so it won't be freed below. */
+       } else {
+               /* special case for cxd0 */
+               h->drv[drv_index]->block_size = drvinfo->block_size;
+               h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks;
+               h->drv[drv_index]->heads = drvinfo->heads;
+               h->drv[drv_index]->sectors = drvinfo->sectors;
+               h->drv[drv_index]->cylinders = drvinfo->cylinders;
+               h->drv[drv_index]->raid_level = drvinfo->raid_level;
+               memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16);
+               memcpy(h->drv[drv_index]->vendor, drvinfo->vendor,
+                       VENDOR_LEN + 1);
+               memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1);
+               memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1);
+       }
 
        ++h->num_luns;
        disk = h->gendisk[drv_index];
-       set_capacity(disk, h->drv[drv_index].nr_blocks);
+       set_capacity(disk, h->drv[drv_index]->nr_blocks);
 
        /* If it's not disk 0 (drv_index != 0)
         * or if it was disk 0, but there was previously
@@ -1780,8 +1949,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
         * (raid_leve == -1) then we want to update the
         * logical drive's information.
         */
-       if (drv_index || first_time)
-               cciss_add_disk(h, disk, drv_index);
+       if (drv_index || first_time) {
+               if (cciss_add_disk(h, disk, drv_index) != 0) {
+                       cciss_free_gendisk(h, drv_index);
+                       cciss_free_drive_info(h, drv_index);
+                       printk(KERN_WARNING "cciss:%d could not update "
+                               "disk %d\n", h->ctlr, drv_index);
+                       --h->num_luns;
+               }
+       }
 
 freeret:
        kfree(inq_buff);
@@ -1793,28 +1969,70 @@ mem_msg:
 }
 
 /* This function will find the first index of the controllers drive array
- * that has a -1 for the raid_level and will return that index.  This is
- * where new drives will be added.  If the index to be returned is greater
- * than the highest_lun index for the controller then highest_lun is set
- * to this new index.  If there are no available indexes then -1 is returned.
- * "controller_node" is used to know if this is a real logical drive, or just
- * the controller node, which determines if this counts towards highest_lun.
+ * that has a null drv pointer and allocate the drive info struct and
+ * will return that index   This is where new drives will be added.
+ * If the index to be returned is greater than the highest_lun index for
+ * the controller then highest_lun is set * to this new index.
+ * If there are no available indexes or if tha allocation fails, then -1
+ * is returned.  * "controller_node" is used to know if this is a real
+ * logical drive, or just the controller node, which determines if this
+ * counts towards highest_lun.
  */
-static int cciss_find_free_drive_index(int ctlr, int controller_node)
+static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node)
 {
        int i;
+       drive_info_struct *drv;
 
+       /* Search for an empty slot for our drive info */
        for (i = 0; i < CISS_MAX_LUN; i++) {
-               if (hba[ctlr]->drv[i].raid_level == -1) {
-                       if (i > hba[ctlr]->highest_lun)
-                               if (!controller_node)
-                                       hba[ctlr]->highest_lun = i;
+
+               /* if not cxd0 case, and it's occupied, skip it. */
+               if (h->drv[i] && i != 0)
+                       continue;
+               /*
+                * If it's cxd0 case, and drv is alloc'ed already, and a
+                * disk is configured there, skip it.
+                */
+               if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1)
+                       continue;
+
+               /*
+                * We've found an empty slot.  Update highest_lun
+                * provided this isn't just the fake cxd0 controller node.
+                */
+               if (i > h->highest_lun && !controller_node)
+                       h->highest_lun = i;
+
+               /* If adding a real disk at cxd0, and it's already alloc'ed */
+               if (i == 0 && h->drv[i] != NULL)
                        return i;
-               }
+
+               /*
+                * Found an empty slot, not already alloc'ed.  Allocate it.
+                * Mark it with raid_level == -1, so we know it's new later on.
+                */
+               drv = kzalloc(sizeof(*drv), GFP_KERNEL);
+               if (!drv)
+                       return -1;
+               drv->raid_level = -1; /* so we know it's new */
+               h->drv[i] = drv;
+               return i;
        }
        return -1;
 }
 
+static void cciss_free_drive_info(ctlr_info_t *h, int drv_index)
+{
+       kfree(h->drv[drv_index]);
+       h->drv[drv_index] = NULL;
+}
+
+static void cciss_free_gendisk(ctlr_info_t *h, int drv_index)
+{
+       put_disk(h->gendisk[drv_index]);
+       h->gendisk[drv_index] = NULL;
+}
+
 /* cciss_add_gendisk finds a free hba[]->drv structure
  * and allocates a gendisk if needed, and sets the lunid
  * in the drvinfo structure.   It returns the index into
@@ -1824,13 +2042,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node)
  * a means to talk to the controller in case no logical
  * drives have yet been configured.
  */
-static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
+static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[],
+       int controller_node)
 {
        int drv_index;
 
-       drv_index = cciss_find_free_drive_index(h->ctlr, controller_node);
+       drv_index = cciss_alloc_drive_info(h, controller_node);
        if (drv_index == -1)
                return -1;
+
        /*Check if the gendisk needs to be allocated */
        if (!h->gendisk[drv_index]) {
                h->gendisk[drv_index] =
@@ -1839,23 +2059,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
                        printk(KERN_ERR "cciss%d: could not "
                                "allocate a new disk %d\n",
                                h->ctlr, drv_index);
-                       return -1;
+                       goto err_free_drive_info;
                }
        }
-       h->drv[drv_index].LunID = lunid;
-       if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index))
+       memcpy(h->drv[drv_index]->LunID, lunid,
+               sizeof(h->drv[drv_index]->LunID));
+       if (cciss_create_ld_sysfs_entry(h, drv_index))
                goto err_free_disk;
-
        /* Don't need to mark this busy because nobody */
        /* else knows about this disk yet to contend */
        /* for access to it. */
-       h->drv[drv_index].busy_configuring = 0;
+       h->drv[drv_index]->busy_configuring = 0;
        wmb();
        return drv_index;
 
 err_free_disk:
-       put_disk(h->gendisk[drv_index]);
-       h->gendisk[drv_index] = NULL;
+       cciss_free_gendisk(h, drv_index);
+err_free_drive_info:
+       cciss_free_drive_info(h, drv_index);
        return -1;
 }
 
@@ -1872,21 +2093,25 @@ static void cciss_add_controller_node(ctlr_info_t *h)
        if (h->gendisk[0] != NULL) /* already did this? Then bail. */
                return;
 
-       drv_index = cciss_add_gendisk(h, 0, 1);
-       if (drv_index == -1) {
-               printk(KERN_WARNING "cciss%d: could not "
-                       "add disk 0.\n", h->ctlr);
-               return;
-       }
-       h->drv[drv_index].block_size = 512;
-       h->drv[drv_index].nr_blocks = 0;
-       h->drv[drv_index].heads = 0;
-       h->drv[drv_index].sectors = 0;
-       h->drv[drv_index].cylinders = 0;
-       h->drv[drv_index].raid_level = -1;
-       memset(h->drv[drv_index].serial_no, 0, 16);
+       drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1);
+       if (drv_index == -1)
+               goto error;
+       h->drv[drv_index]->block_size = 512;
+       h->drv[drv_index]->nr_blocks = 0;
+       h->drv[drv_index]->heads = 0;
+       h->drv[drv_index]->sectors = 0;
+       h->drv[drv_index]->cylinders = 0;
+       h->drv[drv_index]->raid_level = -1;
+       memset(h->drv[drv_index]->serial_no, 0, 16);
        disk = h->gendisk[drv_index];
-       cciss_add_disk(h, disk, drv_index);
+       if (cciss_add_disk(h, disk, drv_index) == 0)
+               return;
+       cciss_free_gendisk(h, drv_index);
+       cciss_free_drive_info(h, drv_index);
+error:
+       printk(KERN_WARNING "cciss%d: could not "
+               "add disk 0.\n", h->ctlr);
+       return;
 }
 
 /* This function will add and remove logical drives from the Logical
@@ -1897,7 +2122,8 @@ static void cciss_add_controller_node(ctlr_info_t *h)
  * INPUT
  * h           = The controller to perform the operations on
  */
-static int rebuild_lun_table(ctlr_info_t *h, int first_time)
+static int rebuild_lun_table(ctlr_info_t *h, int first_time,
+       int via_ioctl)
 {
        int ctlr = h->ctlr;
        int num_luns;
@@ -1907,7 +2133,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
        int i;
        int drv_found;
        int drv_index = 0;
-       __u32 lunid = 0;
+       unsigned char lunid[8] = CTLR_LUNID;
        unsigned long flags;
 
        if (!capable(CAP_SYS_RAWIO))
@@ -1960,13 +2186,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
                drv_found = 0;
 
                /* skip holes in the array from already deleted drives */
-               if (h->drv[i].raid_level == -1)
+               if (h->drv[i] == NULL)
                        continue;
 
                for (j = 0; j < num_luns; j++) {
-                       memcpy(&lunid, &ld_buff->LUN[j][0], 4);
-                       lunid = le32_to_cpu(lunid);
-                       if (h->drv[i].LunID == lunid) {
+                       memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid));
+                       if (memcmp(h->drv[i]->LunID, lunid,
+                               sizeof(lunid)) == 0) {
                                drv_found = 1;
                                break;
                        }
@@ -1974,11 +2200,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
                if (!drv_found) {
                        /* Deregister it from the OS, it's gone. */
                        spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
-                       h->drv[i].busy_configuring = 1;
+                       h->drv[i]->busy_configuring = 1;
                        spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
-                       return_code = deregister_disk(h, i, 1);
-                       cciss_destroy_ld_sysfs_entry(&h->drv[i]);
-                       h->drv[i].busy_configuring = 0;
+                       return_code = deregister_disk(h, i, 1, via_ioctl);
+                       if (h->drv[i] != NULL)
+                               h->drv[i]->busy_configuring = 0;
                }
        }
 
@@ -1992,17 +2218,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
 
                drv_found = 0;
 
-               memcpy(&lunid, &ld_buff->LUN[i][0], 4);
-               lunid = le32_to_cpu(lunid);
-
+               memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid));
                /* Find if the LUN is already in the drive array
                 * of the driver.  If so then update its info
                 * if not in use.  If it does not exist then find
                 * the first free index and add it.
                 */
                for (j = 0; j <= h->highest_lun; j++) {
-                       if (h->drv[j].raid_level != -1 &&
-                               h->drv[j].LunID == lunid) {
+                       if (h->drv[j] != NULL &&
+                               memcmp(h->drv[j]->LunID, lunid,
+                                       sizeof(h->drv[j]->LunID)) == 0) {
                                drv_index = j;
                                drv_found = 1;
                                break;
@@ -2015,7 +2240,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
                        if (drv_index == -1)
                                goto freeret;
                }
-               cciss_update_drive_info(ctlr, drv_index, first_time);
+               cciss_update_drive_info(ctlr, drv_index, first_time,
+                       via_ioctl);
        }               /* end for */
 
 freeret:
@@ -2032,6 +2258,25 @@ mem_msg:
        goto freeret;
 }
 
+static void cciss_clear_drive_info(drive_info_struct *drive_info)
+{
+       /* zero out the disk size info */
+       drive_info->nr_blocks = 0;
+       drive_info->block_size = 0;
+       drive_info->heads = 0;
+       drive_info->sectors = 0;
+       drive_info->cylinders = 0;
+       drive_info->raid_level = -1;
+       memset(drive_info->serial_no, 0, sizeof(drive_info->serial_no));
+       memset(drive_info->model, 0, sizeof(drive_info->model));
+       memset(drive_info->rev, 0, sizeof(drive_info->rev));
+       memset(drive_info->vendor, 0, sizeof(drive_info->vendor));
+       /*
+        * don't clear the LUNID though, we need to remember which
+        * one this one is.
+        */
+}
+
 /* This function will deregister the disk and it's queue from the
  * kernel.  It must be called with the controller lock held and the
  * drv structures busy_configuring flag set.  It's parameters are:
@@ -2046,43 +2291,48 @@ mem_msg:
  *             the disk in preparation for re-adding it.  In this case
  *             the highest_lun should be left unchanged and the LunID
  *             should not be cleared.
+ * via_ioctl
+ *    This indicates whether we've reached this path via ioctl.
+ *    This affects the maximum usage count allowed for c0d0 to be messed with.
+ *    If this path is reached via ioctl(), then the max_usage_count will
+ *    be 1, as the process calling ioctl() has got to have the device open.
+ *    If we get here via sysfs, then the max usage count will be zero.
 */
 static int deregister_disk(ctlr_info_t *h, int drv_index,
-                          int clear_all)
+                          int clear_all, int via_ioctl)
 {
        int i;
        struct gendisk *disk;
        drive_info_struct *drv;
+       int recalculate_highest_lun;
 
        if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
 
-       drv = &h->drv[drv_index];
+       drv = h->drv[drv_index];
        disk = h->gendisk[drv_index];
 
        /* make sure logical volume is NOT is use */
        if (clear_all || (h->gendisk[0] == disk)) {
-               if (drv->usage_count > 1)
+               if (drv->usage_count > via_ioctl)
                        return -EBUSY;
        } else if (drv->usage_count > 0)
                return -EBUSY;
 
+       recalculate_highest_lun = (drv == h->drv[h->highest_lun]);
+
        /* invalidate the devices and deregister the disk.  If it is disk
         * zero do not deregister it but just zero out it's values.  This
         * allows us to delete disk zero but keep the controller registered.
         */
        if (h->gendisk[0] != disk) {
                struct request_queue *q = disk->queue;
-               if (disk->flags & GENHD_FL_UP)
+               if (disk->flags & GENHD_FL_UP) {
+                       cciss_destroy_ld_sysfs_entry(h, drv_index, 0);
                        del_gendisk(disk);
-               if (q) {
-                       blk_cleanup_queue(q);
-                       /* Set drv->queue to NULL so that we do not try
-                        * to call blk_start_queue on this queue in the
-                        * interrupt handler
-                        */
-                       drv->queue = NULL;
                }
+               if (q)
+                       blk_cleanup_queue(q);
                /* If clear_all is set then we are deleting the logical
                 * drive, not just refreshing its info.  For drives
                 * other than disk 0 we will call put_disk.  We do not
@@ -2105,34 +2355,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
                }
        } else {
                set_capacity(disk, 0);
+               cciss_clear_drive_info(drv);
        }
 
        --h->num_luns;
-       /* zero out the disk size info */
-       drv->nr_blocks = 0;
-       drv->block_size = 0;
-       drv->heads = 0;
-       drv->sectors = 0;
-       drv->cylinders = 0;
-       drv->raid_level = -1;   /* This can be used as a flag variable to
-                                * indicate that this element of the drive
-                                * array is free.
-                                */
-
-       if (clear_all) {
-               /* check to see if it was the last disk */
-               if (drv == h->drv + h->highest_lun) {
-                       /* if so, find the new hightest lun */
-                       int i, newhighest = -1;
-                       for (i = 0; i <= h->highest_lun; i++) {
-                               /* if the disk has size > 0, it is available */
-                               if (h->drv[i].heads)
-                                       newhighest = i;
-                       }
-                       h->highest_lun = newhighest;
-               }
 
-               drv->LunID = 0;
+       /* if it was the last disk, find the new hightest lun */
+       if (clear_all && recalculate_highest_lun) {
+               int i, newhighest = -1;
+               for (i = 0; i <= h->highest_lun; i++) {
+                       /* if the disk has size > 0, it is available */
+                       if (h->drv[i] && h->drv[i]->heads)
+                               newhighest = i;
+               }
+               h->highest_lun = newhighest;
        }
        return 0;
 }
@@ -2479,8 +2715,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
        } else {                /* Get geometry failed */
                printk(KERN_WARNING "cciss: reading geometry failed\n");
        }
-       printk(KERN_INFO "      heads=%d, sectors=%d, cylinders=%d\n\n",
-              drv->heads, drv->sectors, drv->cylinders);
 }
 
 static void
@@ -2514,9 +2748,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
                *total_size = 0;
                *block_size = BLOCK_SIZE;
        }
-       if (*total_size != 0)
-               printk(KERN_INFO "      blocks= %llu block_size= %d\n",
-               (unsigned long long)*total_size+1, *block_size);
        kfree(buf);
 }
 
@@ -2568,7 +2799,8 @@ static int cciss_revalidate(struct gendisk *disk)
        InquiryData_struct *inq_buff = NULL;
 
        for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
-               if (h->drv[logvol].LunID == drv->LunID) {
+               if (memcmp(h->drv[logvol]->LunID, drv->LunID,
+                       sizeof(drv->LunID)) == 0) {
                        FOUND = 1;
                        break;
                }
@@ -3053,8 +3285,7 @@ static void do_cciss_request(struct request_queue *q)
        /* The first 2 bits are reserved for controller error reporting. */
        c->Header.Tag.lower = (c->cmdindex << 3);
        c->Header.Tag.lower |= 0x04;    /* flag for direct lookup. */
-       c->Header.LUN.LogDev.VolId = drv->LunID;
-       c->Header.LUN.LogDev.Mode = 1;
+       memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
        c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
        c->Request.Type.Type = TYPE_CMD;        // It is a command.
        c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -3232,20 +3463,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+/**
+ * add_to_scan_list() - add controller to rescan queue
+ * @h:               Pointer to the controller.
+ *
+ * Adds the controller to the rescan queue if not already on the queue.
+ *
+ * returns 1 if added to the queue, 0 if skipped (could be on the
+ * queue already, or the controller could be initializing or shutting
+ * down).
+ **/
+static int add_to_scan_list(struct ctlr_info *h)
+{
+       struct ctlr_info *test_h;
+       int found = 0;
+       int ret = 0;
+
+       if (h->busy_initializing)
+               return 0;
+
+       if (!mutex_trylock(&h->busy_shutting_down))
+               return 0;
+
+       mutex_lock(&scan_mutex);
+       list_for_each_entry(test_h, &scan_q, scan_list) {
+               if (test_h == h) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found && !h->busy_scanning) {
+               INIT_COMPLETION(h->scan_wait);
+               list_add_tail(&h->scan_list, &scan_q);
+               ret = 1;
+       }
+       mutex_unlock(&scan_mutex);
+       mutex_unlock(&h->busy_shutting_down);
+
+       return ret;
+}
+
+/**
+ * remove_from_scan_list() - remove controller from rescan queue
+ * @h:                    Pointer to the controller.
+ *
+ * Removes the controller from the rescan queue if present. Blocks if
+ * the controller is currently conducting a rescan.
+ **/
+static void remove_from_scan_list(struct ctlr_info *h)
+{
+       struct ctlr_info *test_h, *tmp_h;
+       int scanning = 0;
+
+       mutex_lock(&scan_mutex);
+       list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) {
+               if (test_h == h) {
+                       list_del(&h->scan_list);
+                       complete_all(&h->scan_wait);
+                       mutex_unlock(&scan_mutex);
+                       return;
+               }
+       }
+       if (&h->busy_scanning)
+               scanning = 0;
+       mutex_unlock(&scan_mutex);
+
+       if (scanning)
+               wait_for_completion(&h->scan_wait);
+}
+
+/**
+ * scan_thread() - kernel thread used to rescan controllers
+ * @data:       Ignored.
+ *
+ * A kernel thread used scan for drive topology changes on
+ * controllers. The thread processes only one controller at a time
+ * using a queue.  Controllers are added to the queue using
+ * add_to_scan_list() and removed from the queue either after done
+ * processing or using remove_from_scan_list().
+ *
+ * returns 0.
+ **/
 static int scan_thread(void *data)
 {
-       ctlr_info_t *h = data;
-       int rc;
-       DECLARE_COMPLETION_ONSTACK(wait);
-       h->rescan_wait = &wait;
+       struct ctlr_info *h;
 
-       for (;;) {
-               rc = wait_for_completion_interruptible(&wait);
+       while (1) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule();
                if (kthread_should_stop())
                        break;
-               if (!rc)
-                       rebuild_lun_table(h, 0);
+
+               while (1) {
+                       mutex_lock(&scan_mutex);
+                       if (list_empty(&scan_q)) {
+                               mutex_unlock(&scan_mutex);
+                               break;
+                       }
+
+                       h = list_entry(scan_q.next,
+                                      struct ctlr_info,
+                                      scan_list);
+                       list_del(&h->scan_list);
+                       h->busy_scanning = 1;
+                       mutex_unlock(&scan_mutex);
+
+                       if (h) {
+                               rebuild_lun_table(h, 0, 0);
+                               complete_all(&h->scan_wait);
+                               mutex_lock(&scan_mutex);
+                               h->busy_scanning = 0;
+                               mutex_unlock(&scan_mutex);
+                       }
+               }
        }
+
        return 0;
 }
 
@@ -3268,8 +3600,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
        case REPORT_LUNS_CHANGED:
                printk(KERN_WARNING "cciss%d: report LUN data "
                        "changed\n", h->ctlr);
-               if (h->rescan_wait)
-                       complete(h->rescan_wait);
+               add_to_scan_list(h);
+               wake_up_process(cciss_scan_thread);
                return 1;
        break;
        case POWER_OR_RESET:
@@ -3489,7 +3821,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                if (scratchpad == CCISS_FIRMWARE_READY)
                        break;
                set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ / 10);      /* wait 100ms */
+               schedule_timeout(msecs_to_jiffies(100));        /* wait 100ms */
        }
        if (scratchpad != CCISS_FIRMWARE_READY) {
                printk(KERN_WARNING "cciss: Board not ready.  Timed out.\n");
@@ -3615,7 +3947,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                        break;
                /* delay and try again */
                set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(10);
+               schedule_timeout(msecs_to_jiffies(1));
        }
 
 #ifdef CCISS_DEBUG
@@ -3669,15 +4001,16 @@ Enomem:
        return -1;
 }
 
-static void free_hba(int i)
+static void free_hba(int n)
 {
-       ctlr_info_t *p = hba[i];
-       int n;
+       ctlr_info_t *h = hba[n];
+       int i;
 
-       hba[i] = NULL;
-       for (n = 0; n < CISS_MAX_LUN; n++)
-               put_disk(p->gendisk[n]);
-       kfree(p);
+       hba[n] = NULL;
+       for (i = 0; i < h->highest_lun + 1; i++)
+               if (h->gendisk[i] != NULL)
+                       put_disk(h->gendisk[i]);
+       kfree(h);
 }
 
 /* Send a message CDB to the firmware. */
@@ -3918,6 +4251,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        hba[i]->busy_initializing = 1;
        INIT_HLIST_HEAD(&hba[i]->cmpQ);
        INIT_HLIST_HEAD(&hba[i]->reqQ);
+       mutex_init(&hba[i]->busy_shutting_down);
 
        if (cciss_pci_init(hba[i], pdev) != 0)
                goto clean0;
@@ -3926,6 +4260,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        hba[i]->ctlr = i;
        hba[i]->pdev = pdev;
 
+       init_completion(&hba[i]->scan_wait);
+
        if (cciss_create_hba_sysfs_entry(hba[i]))
                goto clean0;
 
@@ -4001,8 +4337,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        hba[i]->num_luns = 0;
        hba[i]->highest_lun = -1;
        for (j = 0; j < CISS_MAX_LUN; j++) {
-               hba[i]->drv[j].raid_level = -1;
-               hba[i]->drv[j].queue = NULL;
+               hba[i]->drv[j] = NULL;
                hba[i]->gendisk[j] = NULL;
        }
 
@@ -4035,14 +4370,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 
        hba[i]->cciss_max_sectors = 2048;
 
+       rebuild_lun_table(hba[i], 1, 0);
        hba[i]->busy_initializing = 0;
-
-       rebuild_lun_table(hba[i], 1);
-       hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i],
-                               "cciss_scan%02d", i);
-       if (IS_ERR(hba[i]->cciss_scan_thread))
-               return PTR_ERR(hba[i]->cciss_scan_thread);
-
        return 1;
 
 clean4:
@@ -4063,12 +4392,7 @@ clean1:
        cciss_destroy_hba_sysfs_entry(hba[i]);
 clean0:
        hba[i]->busy_initializing = 0;
-       /* cleanup any queues that may have been initialized */
-       for (j=0; j <= hba[i]->highest_lun; j++){
-               drive_info_struct *drv = &(hba[i]->drv[j]);
-               if (drv->queue)
-                       blk_cleanup_queue(drv->queue);
-       }
+
        /*
         * Deliberately omit pci_disable_device(): it does something nasty to
         * Smart Array controllers that pci_enable_device does not undo
@@ -4125,8 +4449,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
                return;
        }
 
-       kthread_stop(hba[i]->cciss_scan_thread);
+       mutex_lock(&hba[i]->busy_shutting_down);
 
+       remove_from_scan_list(hba[i]);
        remove_proc_entry(hba[i]->devname, proc_cciss);
        unregister_blkdev(hba[i]->major, hba[i]->devname);
 
@@ -4136,8 +4461,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
                if (disk) {
                        struct request_queue *q = disk->queue;
 
-                       if (disk->flags & GENHD_FL_UP)
+                       if (disk->flags & GENHD_FL_UP) {
+                               cciss_destroy_ld_sysfs_entry(hba[i], j, 1);
                                del_gendisk(disk);
+                       }
                        if (q)
                                blk_cleanup_queue(q);
                }
@@ -4170,6 +4497,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
        pci_release_regions(pdev);
        pci_set_drvdata(pdev, NULL);
        cciss_destroy_hba_sysfs_entry(hba[i]);
+       mutex_unlock(&hba[i]->busy_shutting_down);
        free_hba(i);
 }
 
@@ -4202,15 +4530,25 @@ static int __init cciss_init(void)
        if (err)
                return err;
 
+       /* Start the scan thread */
+       cciss_scan_thread = kthread_run(scan_thread, NULL, "cciss_scan");
+       if (IS_ERR(cciss_scan_thread)) {
+               err = PTR_ERR(cciss_scan_thread);
+               goto err_bus_unregister;
+       }
+
        /* Register for our PCI devices */
        err = pci_register_driver(&cciss_pci_driver);
        if (err)
-               goto err_bus_register;
+               goto err_thread_stop;
 
-       return 0;
+       return err;
 
-err_bus_register:
+err_thread_stop:
+       kthread_stop(cciss_scan_thread);
+err_bus_unregister:
        bus_unregister(&cciss_bus_type);
+
        return err;
 }
 
@@ -4227,6 +4565,7 @@ static void __exit cciss_cleanup(void)
                        cciss_remove_one(hba[i]->pdev);
                }
        }
+       kthread_stop(cciss_scan_thread);
        remove_proc_entry("driver/cciss", NULL);
        bus_unregister(&cciss_bus_type);
 }
index 06a5db25b298ebf400c99ac1c8fa200e208d10ae..31524cf42c77360645424a9c85e68a9651ba8422 100644 (file)
@@ -2,6 +2,7 @@
 #define CCISS_H
 
 #include <linux/genhd.h>
+#include <linux/mutex.h>
 
 #include "cciss_cmd.h"
 
@@ -29,7 +30,7 @@ struct access_method {
 };
 typedef struct _drive_info_struct
 {
-       __u32   LunID;  
+       unsigned char LunID[8];
        int     usage_count;
        struct request_queue *queue;
        sector_t nr_blocks;
@@ -51,6 +52,7 @@ typedef struct _drive_info_struct
        char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
        char model[MODEL_LEN + 1];   /* SCSI model string */
        char rev[REV_LEN + 1];       /* SCSI revision string */
+       char device_initialized;     /* indicates whether dev is initialized */
 } drive_info_struct;
 
 struct ctlr_info 
@@ -86,7 +88,7 @@ struct ctlr_info
        BYTE    cciss_read_capacity;
 
        // information about each logical volume
-       drive_info_struct drv[CISS_MAX_LUN];
+       drive_info_struct *drv[CISS_MAX_LUN];
 
        struct access_method access;
 
@@ -108,6 +110,8 @@ struct ctlr_info
        int                     nr_frees; 
        int                     busy_configuring;
        int                     busy_initializing;
+       int                     busy_scanning;
+       struct mutex            busy_shutting_down;
 
        /* This element holds the zero based queue number of the last
         * queue to be started.  It is used for fairness.
@@ -122,8 +126,8 @@ struct ctlr_info
        /* and saved for later processing */
 #endif
        unsigned char alive;
-       struct completion *rescan_wait;
-       struct task_struct *cciss_scan_thread;
+       struct list_head scan_list;
+       struct completion scan_wait;
        struct device dev;
 };
 
index b82d438e2607cc2c430e4b170470ac29e47c3fb2..6422651ec364197ed9418f4a3bafb966208a8417 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/blkpg.h>
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
@@ -177,7 +178,6 @@ static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev);
 
 #ifdef CONFIG_PROC_FS
 static void ida_procinit(int i);
-static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 #else
 static void ida_procinit(int i) {}
 #endif
@@ -206,6 +206,7 @@ static const struct block_device_operations ida_fops  = {
 #ifdef CONFIG_PROC_FS
 
 static struct proc_dir_entry *proc_array;
+static const struct file_operations ida_proc_fops;
 
 /*
  * Get us a file in /proc/array that says something about each controller.
@@ -218,19 +219,16 @@ static void __init ida_procinit(int i)
                if (!proc_array) return;
        }
 
-       create_proc_read_entry(hba[i]->devname, 0, proc_array,
-                              ida_proc_get_info, hba[i]);
+       proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]);
 }
 
 /*
  * Report information about this controller.
  */
-static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+static int ida_proc_show(struct seq_file *m, void *v)
 {
-       off_t pos = 0;
-       off_t len = 0;
-       int size, i, ctlr;
-       ctlr_info_t *h = (ctlr_info_t*)data;
+       int i, ctlr;
+       ctlr_info_t *h = (ctlr_info_t*)m->private;
        drv_info_t *drv;
 #ifdef CPQ_PROC_PRINT_QUEUES
        cmdlist_t *c;
@@ -238,7 +236,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
 #endif
 
        ctlr = h->ctlr;
-       size = sprintf(buffer, "%s:  Compaq %s Controller\n"
+       seq_printf(m, "%s:  Compaq %s Controller\n"
                "       Board ID: 0x%08lx\n"
                "       Firmware Revision: %c%c%c%c\n"
                "       Controller Sig: 0x%08lx\n"
@@ -258,55 +256,54 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
                h->log_drives, h->phys_drives,
                h->Qdepth, h->maxQsinceinit);
 
-       pos += size; len += size;
-       
-       size = sprintf(buffer+len, "Logical Drive Info:\n");
-       pos += size; len += size;
+       seq_puts(m, "Logical Drive Info:\n");
 
        for(i=0; i<h->log_drives; i++) {
                drv = &h->drv[i];
-               size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
+               seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
                                ctlr, i, drv->blk_size, drv->nr_blks);
-               pos += size; len += size;
        }
 
 #ifdef CPQ_PROC_PRINT_QUEUES
        spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); 
-       size = sprintf(buffer+len, "\nCurrent Queues:\n");
-       pos += size; len += size;
+       seq_puts(m, "\nCurrent Queues:\n");
 
        c = h->reqQ;
-       size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size;
+       seq_printf(m, "reqQ = %p", c);
        if (c) c=c->next;
        while(c && c != h->reqQ) {
-               size = sprintf(buffer+len, "->%p", c);
-               pos += size; len += size;
+               seq_printf(m, "->%p", c);
                c=c->next;
        }
 
        c = h->cmpQ;
-       size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size;
+       seq_printf(m, "\ncmpQ = %p", c);
        if (c) c=c->next;
        while(c && c != h->cmpQ) {
-               size = sprintf(buffer+len, "->%p", c);
-               pos += size; len += size;
+               seq_printf(m, "->%p", c);
                c=c->next;
        }
 
-       size = sprintf(buffer+len, "\n"); pos += size; len += size;
+       seq_putc(m, '\n');
        spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); 
 #endif
-       size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n",
+       seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n",
                        h->nr_allocs, h->nr_frees);
-       pos += size; len += size;
-
-       *eof = 1;
-       *start = buffer+offset;
-       len -= offset;
-       if (len>length)
-               len = length;
-       return len;
+       return 0;
+}
+
+static int ida_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ida_proc_show, PDE(inode)->data);
 }
+
+static const struct file_operations ida_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = ida_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif /* CONFIG_PROC_FS */
 
 module_param_array(eisa, int, NULL, 0);
index aaca40283be932811cefe4ed3c1109100d990f81..4f568cb9af3f90b62c52de1af32170ee4650d29d 100644 (file)
@@ -393,7 +393,7 @@ static int apm_open(struct inode * inode, struct file * filp)
        return as ? 0 : -ENOMEM;
 }
 
-static struct file_operations apm_bios_fops = {
+static const struct file_operations apm_bios_fops = {
        .owner          = THIS_MODULE,
        .read           = apm_read,
        .poll           = apm_poll,
index e3dd24bff5143206df8c4345fc1fce56fe492cda..836d4f0a876f5ca53b03f8314acea1a0f23f5ca3 100644 (file)
@@ -217,7 +217,7 @@ static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
 # define bfin_otp_ioctl NULL
 #endif
 
-static struct file_operations bfin_otp_fops = {
+static const struct file_operations bfin_otp_fops = {
        .owner          = THIS_MODULE,
        .unlocked_ioctl = bfin_otp_ioctl,
        .read           = bfin_otp_read,
index df5038bbcbc28647cc64eed72f0fee6fbc8c2568..4254457d391186429590769d05334d01c459bd75 100644 (file)
@@ -3354,7 +3354,7 @@ static int __init cy_detect_isa(void)
                        continue;
                }
 #ifdef MODULE
-               if (isparam && irq[i])
+               if (isparam && i < NR_CARDS && irq[i])
                        cy_isa_irq = irq[i];
                else
 #endif
index 52e06589821d8ed53edef8bf96e02e0a95a9d430..045c930e6320c89e9ac2f28fadee74e1c3607790 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/errno.h>       /* for -EBUSY */
 #include <linux/ioport.h>      /* for request_region */
 #include <linux/delay.h>       /* for loops_per_jiffy */
+#include <linux/sched.h>
 #include <linux/smp_lock.h>    /* cycle_kernel_lock() */
 #include <asm/io.h>            /* for inb_p, outb_p, inb, outb, etc. */
 #include <asm/uaccess.h>       /* for get_user, etc. */
index 41fc11dc921c70260e89551f111a8f73d97a3b10..65545de3dbf4ded375e55467fcaf5a8360000dfd 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/errno.h>
 #include <asm/system.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/ipmi.h>
index 09050797c76a26546ca5fa2d4ed3e165cc9455b9..ec5e3f8df648ba1e719836a9b8349246005ba685 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/errno.h>
 #include <asm/system.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
index 5942a9d674c0051885bd796fc005b39f14622657..452370af95def5a352dd4753107ce3fd4154fb93 100644 (file)
@@ -220,8 +220,7 @@ static inline int serial_paranoia_check(struct cyclades_port *info, char *name,
                return 1;
        }
 
-       if ((long)info < (long)(&cy_port[0])
-           || (long)(&cy_port[NR_PORTS]) < (long)info) {
+       if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) {
                printk("Warning: cyclades_port out of range for (%s) in %s\n",
                                name, routine);
                return 1;
@@ -520,15 +519,13 @@ static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
                panic("TxInt on debug port!!!");
        }
 #endif
-
-       info = &cy_port[channel];
-
        /* validate the port number (as configured and open) */
        if ((channel < 0) || (NR_PORTS <= channel)) {
                base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
                base_addr[CyTEOIR] = CyNOTRANS;
                return IRQ_HANDLED;
        }
+       info = &cy_port[channel];
        info->last_active = jiffies;
        if (info->tty == 0) {
                base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
index aafdbaebc16a8697df6f16efbaadbce255e05d86..feb55075819bab4f7d9f75ce11f7aa7232ba9dc1 100644 (file)
@@ -518,7 +518,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
 static int tty_ldisc_halt(struct tty_struct *tty)
 {
        clear_bit(TTY_LDISC, &tty->flags);
-       return cancel_delayed_work(&tty->buf.work);
+       return cancel_delayed_work_sync(&tty->buf.work);
 }
 
 /**
@@ -756,12 +756,9 @@ void tty_ldisc_hangup(struct tty_struct *tty)
         * N_TTY.
         */
        if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
-               /* Make sure the old ldisc is quiescent */
-               tty_ldisc_halt(tty);
-               flush_scheduled_work();
-
                /* Avoid racing set_ldisc or tty_ldisc_release */
                mutex_lock(&tty->ldisc_mutex);
+               tty_ldisc_halt(tty);
                if (tty->ldisc) {       /* Not yet closed */
                        /* Switch back to N_TTY */
                        tty_ldisc_reinit(tty);
index 29c651ab0d7891f1504cf5a222a11a6f269c261b..6b36ee56e6fe972db14dd1f4785e5cf173468acf 100644 (file)
@@ -981,8 +981,10 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        goto eperm;
 
                if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
-                                               sizeof(struct vt_setactivate)))
-                       return -EFAULT;
+                                       sizeof(struct vt_setactivate))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
                if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
                        ret = -ENXIO;
                else {
index f40ab699860f4645a693f76a239473812e767493..4846d50199f3d1c917d23d2a13aa1108d28cace9 100644 (file)
@@ -559,7 +559,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
        return status;
 }
 
-static struct file_operations hwicap_fops = {
+static const struct file_operations hwicap_fops = {
        .owner = THIS_MODULE,
        .write = hwicap_write,
        .read = hwicap_read,
index 4a1dfe1f4ba9c1704b3f1cc56dbc2931a21c32c4..210338ea222f38e408d093f2aceaf9e0c539e5bc 100644 (file)
@@ -78,18 +78,20 @@ void cn_queue_wrapper(struct work_struct *work)
        struct cn_callback_entry *cbq =
                container_of(work, struct cn_callback_entry, work);
        struct cn_callback_data *d = &cbq->data;
+       struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
+       struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
 
-       d->callback(d->callback_priv);
+       d->callback(msg, nsp);
 
-       d->destruct_data(d->ddata);
-       d->ddata = NULL;
+       kfree_skb(d->skb);
+       d->skb = NULL;
 
        kfree(d->free);
 }
 
 static struct cn_callback_entry *
 cn_queue_alloc_callback_entry(char *name, struct cb_id *id,
-                             void (*callback)(struct cn_msg *))
+                             void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
 {
        struct cn_callback_entry *cbq;
 
@@ -123,7 +125,7 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
 }
 
 int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id,
-                         void (*callback)(struct cn_msg *))
+                         void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
 {
        struct cn_callback_entry *cbq, *__cbq;
        int found = 0;
index 74f52af79563ea18558ecd862df9693ffbb22e5c..f06024668f99d2abfd73d560804cf172d9ea19a8 100644 (file)
@@ -129,21 +129,19 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
 /*
  * Callback helper - queues work and setup destructor for given data.
  */
-static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
+static int cn_call_callback(struct sk_buff *skb)
 {
        struct cn_callback_entry *__cbq, *__new_cbq;
        struct cn_dev *dev = &cdev;
+       struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
        int err = -ENODEV;
 
        spin_lock_bh(&dev->cbdev->queue_lock);
        list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
                if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
                        if (likely(!work_pending(&__cbq->work) &&
-                                       __cbq->data.ddata == NULL)) {
-                               __cbq->data.callback_priv = msg;
-
-                               __cbq->data.ddata = data;
-                               __cbq->data.destruct_data = destruct_data;
+                                       __cbq->data.skb == NULL)) {
+                               __cbq->data.skb = skb;
 
                                if (queue_cn_work(__cbq, &__cbq->work))
                                        err = 0;
@@ -156,10 +154,8 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
                                __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
                                if (__new_cbq) {
                                        d = &__new_cbq->data;
-                                       d->callback_priv = msg;
+                                       d->skb = skb;
                                        d->callback = __cbq->data.callback;
-                                       d->ddata = data;
-                                       d->destruct_data = destruct_data;
                                        d->free = __new_cbq;
 
                                        __new_cbq->pdev = __cbq->pdev;
@@ -191,7 +187,6 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
  */
 static void cn_rx_skb(struct sk_buff *__skb)
 {
-       struct cn_msg *msg;
        struct nlmsghdr *nlh;
        int err;
        struct sk_buff *skb;
@@ -208,8 +203,7 @@ static void cn_rx_skb(struct sk_buff *__skb)
                        return;
                }
 
-               msg = NLMSG_DATA(nlh);
-               err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
+               err = cn_call_callback(skb);
                if (err < 0)
                        kfree_skb(skb);
        }
@@ -270,7 +264,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
  * May sleep.
  */
 int cn_add_callback(struct cb_id *id, char *name,
-                   void (*callback)(struct cn_msg *))
+                   void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
 {
        int err;
        struct cn_dev *dev = &cdev;
@@ -352,7 +346,7 @@ static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
  *
  * Used for notification of a request's processing.
  */
-static void cn_callback(struct cn_msg *msg)
+static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
        struct cn_ctl_msg *ctl;
        struct cn_ctl_entry *ent;
index ced186d7e9a9d16552fcf3d73a95203303a8251a..5089331544ed5336e682fdec039be94068314102 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/mutex.h>
 #include <linux/poll.h>
 #include <linux/preempt.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/time.h>
 #include <linux/uaccess.h>
index bb11a429394ab865f7e07cfc289d8a32330bd320..662ed923d9eb0be22a49c0a1db2ae5c14e11d49d 100644 (file)
@@ -1487,7 +1487,7 @@ static int gpiolib_open(struct inode *inode, struct file *file)
        return single_open(file, gpiolib_show, NULL);
 }
 
-static struct file_operations gpiolib_operations = {
+static const struct file_operations gpiolib_operations = {
        .open           = gpiolib_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
index 0c6639ea03dd1748076dd8742035f1f154603cd9..ba05275e5104f7d30771254b82e3f35a48017bfa 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/major.h>
 #include <linux/hid.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/smp_lock.h>
 
 #include <linux/hidraw.h>
index ea955edde87e5127fc4c7f57d7d0c0b51ed3b1e4..2a7a85a6dc360e9615725fc7be5c25b0f845799c 100644 (file)
@@ -915,7 +915,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp,
        return ret;
 }
 
-static struct file_operations watchdog_fops = {
+static const struct file_operations watchdog_fops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .open = watchdog_open,
index 6c9a04136e0aefb9a1b4430146b1453ed9acbe3f..00d975eb5b83dcc86ddd8d5f5b6846c9d370f6e6 100644 (file)
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ltc4215);
-
 /* Here are names of the chip's registers (a.k.a. commands) */
 enum ltc4215_cmd {
        LTC4215_CONTROL                 = 0x00, /* rw */
@@ -246,9 +241,13 @@ static const struct attribute_group ltc4215_group = {
 static int ltc4215_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
+       struct i2c_adapter *adapter = client->adapter;
        struct ltc4215_data *data;
        int ret;
 
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data) {
                ret = -ENOMEM;
@@ -294,56 +293,20 @@ static int ltc4215_remove(struct i2c_client *client)
        return 0;
 }
 
-static int ltc4215_detect(struct i2c_client *client,
-                         int kind,
-                         struct i2c_board_info *info)
-{
-       struct i2c_adapter *adapter = client->adapter;
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return -ENODEV;
-
-       if (kind < 0) {         /* probed detection - check the chip type */
-               s32 v;          /* 8 bits from the chip, or -ERRNO */
-
-               /*
-                * Register 0x01 bit b7 is reserved, expect 0
-                * Register 0x03 bit b6 and b7 are reserved, expect 0
-                */
-               v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
-               if (v < 0 || (v & (1 << 7)) != 0)
-                       return -ENODEV;
-
-               v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
-               if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
-                               return -ENODEV;
-       }
-
-       strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
-       dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
-                       kind < 0 ? "probed" : "forced",
-                       client->addr);
-
-       return 0;
-}
-
 static const struct i2c_device_id ltc4215_id[] = {
-       { "ltc4215", ltc4215 },
+       { "ltc4215", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ltc4215_id);
 
 /* This is the driver that will be inserted */
 static struct i2c_driver ltc4215_driver = {
-       .class          = I2C_CLASS_HWMON,
        .driver = {
                .name   = "ltc4215",
        },
        .probe          = ltc4215_probe,
        .remove         = ltc4215_remove,
        .id_table       = ltc4215_id,
-       .detect         = ltc4215_detect,
-       .address_data   = &addr_data,
 };
 
 static int __init ltc4215_init(void)
index e389643336126897d9abd8adf08cfe3464425712..65c232a9d0c5a917b533e2aeac34c2c13aa4fba5 100644 (file)
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 
-/* Valid addresses are 0x20 - 0x3f
- *
- * For now, we do not probe, since some of these addresses
- * are known to be unfriendly to probing */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ltc4245);
-
 /* Here are names of the chip's registers (a.k.a. commands) */
 enum ltc4245_cmd {
        LTC4245_STATUS                  = 0x00, /* readonly */
@@ -369,9 +360,13 @@ static const struct attribute_group ltc4245_group = {
 static int ltc4245_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
+       struct i2c_adapter *adapter = client->adapter;
        struct ltc4245_data *data;
        int ret;
 
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data) {
                ret = -ENOMEM;
@@ -418,136 +413,20 @@ static int ltc4245_remove(struct i2c_client *client)
        return 0;
 }
 
-/* Check that some bits in a control register appear at all possible
- * locations without changing value
- *
- * @client: the i2c client to use
- * @reg: the register to read
- * @bits: the bits to check (0xff checks all bits,
- *                           0x03 checks only the last two bits)
- *
- * return -ERRNO if the register read failed
- * return -ENODEV if the register value doesn't stay constant at all
- * possible addresses
- *
- * return 0 for success
- */
-static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits)
-{
-       int i;
-       s32 v, voff1, voff2;
-
-       /* Read register and check for error */
-       v = i2c_smbus_read_byte_data(client, reg);
-       if (v < 0)
-               return v;
-
-       v &= bits;
-
-       for (i = 0x00; i < 0xff; i += 0x20) {
-
-               voff1 = i2c_smbus_read_byte_data(client, reg + i);
-               if (voff1 < 0)
-                       return voff1;
-
-               voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08);
-               if (voff2 < 0)
-                       return voff2;
-
-               voff1 &= bits;
-               voff2 &= bits;
-
-               if (v != voff1 || v != voff2)
-                       return -ENODEV;
-       }
-
-       return 0;
-}
-
-static int ltc4245_detect(struct i2c_client *client,
-                         int kind,
-                         struct i2c_board_info *info)
-{
-       struct i2c_adapter *adapter = client->adapter;
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return -ENODEV;
-
-       if (kind < 0) {         /* probed detection - check the chip type */
-               s32 v;          /* 8 bits from the chip, or -ERRNO */
-
-               /* Chip registers 0x00-0x07 are control registers
-                * Chip registers 0x10-0x1f are data registers
-                *
-                * Address bits b7-b5 are ignored. This makes the chip "repeat"
-                * in steps of 0x20. Any control registers should appear with
-                * the same values across all duplicated addresses.
-                *
-                * Register 0x02 bit b2 is reserved, expect 0
-                * Register 0x07 bits b7 to b4 are reserved, expect 0
-                *
-                * Registers 0x01, 0x02 are control registers and should not
-                * change on their own.
-                *
-                * Register 0x06 bits b6 and b7 are control bits, and should
-                * not change on their own.
-                *
-                * Register 0x07 bits b3 to b0 are control bits, and should
-                * not change on their own.
-                */
-
-               /* read register 0x02 reserved bit, expect 0 */
-               v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL);
-               if (v < 0 || (v & 0x04) != 0)
-                       return -ENODEV;
-
-               /* read register 0x07 reserved bits, expect 0 */
-               v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR);
-               if (v < 0 || (v & 0xf0) != 0)
-                       return -ENODEV;
-
-               /* check that the alert register appears at all locations */
-               if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff))
-                       return -ENODEV;
-
-               /* check that the control register appears at all locations */
-               if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff))
-                       return -ENODEV;
-
-               /* check that register 0x06 bits b6 and b7 stay constant */
-               if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0))
-                       return -ENODEV;
-
-               /* check that register 0x07 bits b3-b0 stay constant */
-               if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f))
-                       return -ENODEV;
-       }
-
-       strlcpy(info->type, "ltc4245", I2C_NAME_SIZE);
-       dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n",
-                       kind < 0 ? "probed" : "forced",
-                       client->addr);
-
-       return 0;
-}
-
 static const struct i2c_device_id ltc4245_id[] = {
-       { "ltc4245", ltc4245 },
+       { "ltc4245", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ltc4245_id);
 
 /* This is the driver that will be inserted */
 static struct i2c_driver ltc4245_driver = {
-       .class          = I2C_CLASS_HWMON,
        .driver = {
                .name   = "ltc4245",
        },
        .probe          = ltc4245_probe,
        .remove         = ltc4245_remove,
        .id_table       = ltc4245_id,
-       .detect         = ltc4245_detect,
-       .address_data   = &addr_data,
 };
 
 static int __init ltc4245_init(void)
index f7d6fe9c49baa3724c38463448acbcb5a4384cb4..8f0b90ef8c76fe9e76e1c2101d841004690963e4 100644 (file)
@@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
        error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
                                  amd756_driver.name);
        if (error)
-               return error;
+               return -ENODEV;
 
        if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
                dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
index a7c59908c457cbeb23937904dc6d6a76a05e060c..5b4ad86ca166f2bdcec9e63f8fa02947f2bfd83c 100644 (file)
@@ -376,8 +376,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
        smbus->size = pci_resource_len(dev, 0);
 
        error = acpi_check_resource_conflict(&dev->resource[0]);
-       if (error)
+       if (error) {
+               error = -ENODEV;
                goto out_kfree;
+       }
 
        if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
                error = -EBUSY;
index 9d2c5adf5d4fbbcf06c8baf68d98cb01c5b93706..55edcfe5b851abe5676d1d3c857eed93c233e458 100644 (file)
@@ -732,8 +732,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        }
 
        err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
-       if (err)
+       if (err) {
+               err = -ENODEV;
                goto exit;
+       }
 
        err = pci_request_region(dev, SMBBAR, i801_driver.name);
        if (err) {
index 9f6b8e0f8632af44c2eb4c49667277e0656bec7b..dba6eb053e2facc6f1393abe41ac5b296b9127aa 100644 (file)
@@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev,
                return -ENODEV;
        }
        if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
-               return -EBUSY;
+               return -ENODEV;
        if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
                dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
                        sch_smba);
index a782c7a08f9e1256d40430bf15d050d30791375b..d26a972aacaad8b0eff3f850b46fa5ed418d0440 100644 (file)
@@ -169,7 +169,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
        }
 
        if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
-               return -EBUSY;
+               return -ENODEV;
 
        if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
                dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
@@ -260,7 +260,7 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 
        piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
        if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
-               return -EBUSY;
+               return -ENODEV;
 
        if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
                dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
index 8295885b2fdb9417c18f19becc3a3ce045240d18..1649963b00dcfef12861868dfa5715547f9bfc7a 100644 (file)
@@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
 
        retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
        if (retval)
-               return retval;
+               return -ENODEV;
 
        /* Everything is happy, let's grab the memory and set things up. */
        if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
index 54d810a4d00f86aa3ff687294e235b47a0a4a7cf..e4b1543015af9cb5eeb44f40a676918c70fb83e8 100644 (file)
@@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
 found:
        error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
        if (error)
-               return error;
+               return -ENODEV;
 
        if (!request_region(vt596_smba, 8, vt596_driver.name)) {
                dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
index 51bd9669cb1f7697c0be4e1b4b0c38dc4ee05499..f504c9b00c1ba631cbe7f27b80ad0859ab9f3a08 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/cdev.h>
index 8c46f2257098cf2d7e01ba472c31a48dc5ffb77a..7de02969ed7d80bcf28b59abe9471253d9a9138f 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/mutex.h>
 #include <linux/kref.h>
 #include <linux/compat.h>
+#include <linux/sched.h>
 #include <linux/semaphore.h>
 
 #include <asm/uaccess.h>
index d3fff9e008a3e01f1f81795101738ae236b02dcb..aec0fbdfe7f016bba4126bbf89d64060783501b9 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/cdev.h>
index 1148140d08a1faf72967dc3068e41c71488054d8..dee6706038aad7ad1519f551bd4d71f02fa6f9c1 100644 (file)
@@ -13,6 +13,7 @@
 #define EVDEV_BUFFER_SIZE      64
 
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
index e828aab7daceada9eb8858fb19fa3fc755baa7ea..c6f88ebb40c766e21c17104cdbbe12563ed075a7 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/random.h>
 #include <linux/major.h>
 #include <linux/proc_fs.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/poll.h>
 #include <linux/device.h>
@@ -1273,6 +1274,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
                }                                               \
        } while (0)
 
+#ifdef CONFIG_PM
 static void input_dev_reset(struct input_dev *dev, bool activate)
 {
        if (!dev->event)
@@ -1287,7 +1289,6 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
        }
 }
 
-#ifdef CONFIG_PM
 static int input_dev_suspend(struct device *dev)
 {
        struct input_dev *input_dev = to_input_dev(dev);
index 901b2525993e54f77c219cac9b1d55e3431219e5..b1bd6dd322864d0bd04c2f9a48c9f80b3217dcce 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
index c5a49aba418f9232ff026dbce0a9d30db706bf1b..d3f57245420a008a412afa9b55dd4bd8f015ce8d 100644 (file)
@@ -30,6 +30,7 @@
  *             - first public version
  */
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
index 966b8868f7924f6f73c276411cded8f29b155714..a13d80f7da17481772cc4e00f260b2f564919e13 100644 (file)
@@ -13,6 +13,7 @@
 #define MOUSEDEV_MINORS                32
 #define MOUSEDEV_MIX           31
 
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/poll.h>
index 8b256a617c8a4524cec9f503ef7371ebbf30356b..3697c409bec66d5b9c2dbe0b31577f22fef2ef1c 100644 (file)
@@ -16,6 +16,7 @@
 #else
 #include <linux/fs.h>
 #endif
+#include <linux/sched.h>
 #include <linux/isdnif.h>
 #include <net/net_namespace.h>
 #include "isdn_divert.h"
index c36f521374562271c5c4dba4890303a99ffbc069..feb0fa45b664b7f30f843d8097fc47013be8adce 100644 (file)
@@ -415,7 +415,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 }
 
 static int data_sock_setsockopt(struct socket *sock, int level, int optname,
-       char __user *optval, int len)
+       char __user *optval, unsigned int len)
 {
        struct sock *sk = sock->sk;
        int err = 0, opt = 0;
index 708a8017c21d49e207139c9773927fd87c848f7a..adc561eb59d2ed022873bacf35501b9462e19bbc 100644 (file)
@@ -19,9 +19,6 @@
 #include <linux/workqueue.h>
 #include <linux/leds-pca9532.h>
 
-static const unsigned short normal_i2c[] = { /*0x60,*/ I2C_CLIENT_END};
-I2C_CLIENT_INSMOD_1(pca9532);
-
 #define PCA9532_REG_PSC(i) (0x2+(i)*2)
 #define PCA9532_REG_PWM(i) (0x3+(i)*2)
 #define PCA9532_REG_LS0  0x6
index b4d3f7ca554f0d8e81be09a02d824fb4f84cb978..bd1632388e4a37f0f12268e83d645b92e96632ff 100644 (file)
@@ -508,7 +508,7 @@ static int close(struct inode *inode, struct file *file)
  * uses: reading and writing a character device called /dev/lguest.  All the
  * work happens in the read(), write() and close() routines:
  */
-static struct file_operations lguest_fops = {
+static const struct file_operations lguest_fops = {
        .owner   = THIS_MODULE,
        .release = close,
        .write   = write,
index fde377c60cca753eafe9c358f7e562c6d538ad7b..556f0feaa4df33fe3733e0ccf3638bb6bfe1aa44 100644 (file)
@@ -124,6 +124,8 @@ read_reg(struct thermostat* th, int reg)
        return data;
 }
 
+static struct i2c_driver thermostat_driver;
+
 static int
 attach_thermostat(struct i2c_adapter *adapter)
 {
@@ -148,7 +150,7 @@ attach_thermostat(struct i2c_adapter *adapter)
         * Let i2c-core delete that device on driver removal.
         * This is safe because i2c-core holds the core_lock mutex for us.
         */
-       list_add_tail(&client->detected, &client->driver->clients);
+       list_add_tail(&client->detected, &thermostat_driver.clients);
        return 0;
 }
 
index a028598af2d32ae030596bff2e83145420271d65..ea32c7e5a9af116c49e885b1e015fe9742f24758 100644 (file)
@@ -286,6 +286,8 @@ struct fcu_fan_table        fcu_fans[] = {
        },
 };
 
+static struct i2c_driver therm_pm72_driver;
+
 /*
  * Utility function to create an i2c_client structure and
  * attach it to one of u3 adapters
@@ -318,7 +320,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
         * Let i2c-core delete that device on driver removal.
         * This is safe because i2c-core holds the core_lock mutex for us.
         */
-       list_add_tail(&clt->detected, &clt->driver->clients);
+       list_add_tail(&clt->detected, &therm_pm72_driver.clients);
        return clt;
 }
 
index 529886c7a8263ae4d4d01df89b7b513695d983c3..ed6426a107738b4dff5a1d639140a7f22b7c9b27 100644 (file)
@@ -115,6 +115,8 @@ static int wf_lm75_probe(struct i2c_client *client,
        return rc;
 }
 
+static struct i2c_driver wf_lm75_driver;
+
 static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
                                             u8 addr, int ds1775,
                                             const char *loc)
@@ -157,7 +159,7 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
         * Let i2c-core delete that device on driver removal.
         * This is safe because i2c-core holds the core_lock mutex for us.
         */
-       list_add_tail(&client->detected, &client->driver->clients);
+       list_add_tail(&client->detected, &wf_lm75_driver.clients);
        return client;
  fail:
        return NULL;
index e2a55ecda2b28aa2c80114dd7d6c7ec0cd519827..a67b349319e9c9be57f19faf3f309ff487e06448 100644 (file)
@@ -88,6 +88,8 @@ static int wf_max6690_probe(struct i2c_client *client,
        return rc;
 }
 
+static struct i2c_driver wf_max6690_driver;
+
 static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
                                            u8 addr, const char *loc)
 {
@@ -119,7 +121,7 @@ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
         * Let i2c-core delete that device on driver removal.
         * This is safe because i2c-core holds the core_lock mutex for us.
         */
-       list_add_tail(&client->detected, &client->driver->clients);
+       list_add_tail(&client->detected, &wf_max6690_driver.clients);
        return client;
 
  fail:
index 5da729e58f99294ec43cd23ec7bee680da7e70b7..e20330a28959bc539d0691337bf49438e2022efe 100644 (file)
@@ -194,6 +194,8 @@ static struct wf_sensor_ops wf_sat_ops = {
        .owner          = THIS_MODULE,
 };
 
+static struct i2c_driver wf_sat_driver;
+
 static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
 {
        struct i2c_board_info info;
@@ -222,7 +224,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
         * Let i2c-core delete that device on driver removal.
         * This is safe because i2c-core holds the core_lock mutex for us.
         */
-       list_add_tail(&client->detected, &client->driver->clients);
+       list_add_tail(&client->detected, &wf_sat_driver.clients);
 }
 
 static int wf_sat_probe(struct i2c_client *client,
index ba0edad2d048017bd08257f0c7b34eb9f86bf1ea..54abf9e303b7d66c4f41de1ef1ff17197572d292 100644 (file)
@@ -129,11 +129,13 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
  * This is the connector callback that delivers data
  * that was sent from userspace.
  */
-static void cn_ulog_callback(void *data)
+static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
-       struct cn_msg *msg = (struct cn_msg *)data;
        struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
 
+       if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+               return;
+
        spin_lock(&receiving_list_lock);
        if (msg->len == 0)
                fill_pkg(msg, NULL);
index 376f1ab48a245fcdce521bd55a7ceb109f7f8c9e..23e76fe0d35958d604657a559a5954095854bf23 100644 (file)
@@ -130,7 +130,7 @@ struct mapped_device {
        /*
         * A list of ios that arrived while we were suspended.
         */
-       atomic_t pending[2];
+       atomic_t pending;
        wait_queue_head_t wait;
        struct work_struct work;
        struct bio_list deferred;
@@ -453,14 +453,13 @@ static void start_io_acct(struct dm_io *io)
 {
        struct mapped_device *md = io->md;
        int cpu;
-       int rw = bio_data_dir(io->bio);
 
        io->start_time = jiffies;
 
        cpu = part_stat_lock();
        part_round_stats(cpu, &dm_disk(md)->part0);
        part_stat_unlock();
-       dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]);
+       dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
 }
 
 static void end_io_acct(struct dm_io *io)
@@ -480,9 +479,8 @@ static void end_io_acct(struct dm_io *io)
         * After this is decremented the bio must not be touched if it is
         * a barrier.
         */
-       dm_disk(md)->part0.in_flight[rw] = pending =
-               atomic_dec_return(&md->pending[rw]);
-       pending += atomic_read(&md->pending[rw^0x1]);
+       dm_disk(md)->part0.in_flight = pending =
+               atomic_dec_return(&md->pending);
 
        /* nudge anyone waiting on suspend queue */
        if (!pending)
@@ -1787,8 +1785,7 @@ static struct mapped_device *alloc_dev(int minor)
        if (!md->disk)
                goto bad_disk;
 
-       atomic_set(&md->pending[0], 0);
-       atomic_set(&md->pending[1], 0);
+       atomic_set(&md->pending, 0);
        init_waitqueue_head(&md->wait);
        INIT_WORK(&md->work, dm_wq_work);
        init_waitqueue_head(&md->eventq);
@@ -2091,8 +2088,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
                                break;
                        }
                        spin_unlock_irqrestore(q->queue_lock, flags);
-               } else if (!atomic_read(&md->pending[0]) &&
-                                       !atomic_read(&md->pending[1]))
+               } else if (!atomic_read(&md->pending))
                        break;
 
                if (interruptible == TASK_INTERRUPTIBLE &&
index 3750ff48cba1e75097c99daf4697931b2f9b0a3f..c37790ad92d0b501e470d4c0a6de0a1713fc592a 100644 (file)
@@ -20,6 +20,7 @@
  *
  */
 
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -1203,7 +1204,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
        return mask;
 }
 
-static struct file_operations dvb_dvr_fops = {
+static const struct file_operations dvb_dvr_fops = {
        .owner = THIS_MODULE,
        .read = dvb_dvr_read,
        .write = dvb_dvr_write,
index eef6d36166268f77883b2fb454eb6dcd698ca1fa..91c537bca8adaac314f85c7ffc531c05f5d00620 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
index eeb80d0ea3ff24585295aad880e0a77ecc9078fb..853e04b7cb361d45257f80dcafdcf121cd340c63 100644 (file)
@@ -215,7 +215,7 @@ static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
        return POLLIN;
 }
 
-static struct file_operations fdtv_ca_fops = {
+static const struct file_operations fdtv_ca_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = dvb_generic_ioctl,
        .open           = dvb_generic_open,
index 8b1440136c45b10710079bdbf2e80fba7f166978..482d0f3be5ffe7a26ed931a1c7f44042a384da9c 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/videodev2.h>   /* V4L2 API defs                */
 #include <linux/param.h>
 #include <linux/pnp.h>
+#include <linux/sched.h>
 #include <linux/io.h>          /* outb, outb_p                 */
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
index 43ab0adf3b610a8927299e833c6bb3ab5f3b73ad..2377313c041a8c33976db18f0c1ef7a698c94bd6 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/ctype.h>
index 5447da16a1705c49e9e72c57a58e203ceb4ce1eb..613481028272f114c754a4a652987fce90452cae 100644 (file)
@@ -57,8 +57,6 @@
  * The AB3100 is usually assigned address 0x48 (7-bit)
  * The chip is defined in the platform i2c_board_data section.
  */
-static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END };
-I2C_CLIENT_INSMOD_1(ab3100);
 
 u8 ab3100_get_chip_type(struct ab3100 *ab3100)
 {
@@ -966,7 +964,7 @@ static int __exit ab3100_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id ab3100_id[] = {
-       { "ab3100", ab3100 },
+       { "ab3100", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ab3100_id);
index 2afc08006e6d1db891f995445a351c59186165fd..fa294b6d600a9d6af6f8f27d8b853b5aea7d55e3 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/ucb1400.h>
 
 unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
index 3c0c58eed34778a22b6d052dbb665584e8b55147..5a6b2bce8ad5a7a3672c8333a91a8285202b9af2 100644 (file)
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 
-/* Do not scan - the MAX6875 access method will write to some EEPROM chips */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(max6875);
-
 /* The MAX6875 can only read/write 16 bytes at a time */
 #define SLICE_SIZE                     16
 #define SLICE_BITS                     4
@@ -146,31 +140,21 @@ static struct bin_attribute user_eeprom_attr = {
        .read = max6875_read,
 };
 
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int max6875_detect(struct i2c_client *client, int kind,
-                         struct i2c_board_info *info)
+static int max6875_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
 {
        struct i2c_adapter *adapter = client->adapter;
+       struct max6875_data *data;
+       int err;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
                                     | I2C_FUNC_SMBUS_READ_BYTE))
                return -ENODEV;
 
-       /* Only check even addresses */
+       /* Only bind to even addresses */
        if (client->addr & 1)
                return -ENODEV;
 
-       strlcpy(info->type, "max6875", I2C_NAME_SIZE);
-
-       return 0;
-}
-
-static int max6875_probe(struct i2c_client *client,
-                        const struct i2c_device_id *id)
-{
-       struct max6875_data *data;
-       int err;
-
        if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
                return -ENOMEM;
 
@@ -222,9 +206,6 @@ static struct i2c_driver max6875_driver = {
        .probe          = max6875_probe,
        .remove         = max6875_remove,
        .id_table       = max6875_id,
-
-       .detect         = max6875_detect,
-       .address_data   = &addr_data,
 };
 
 static int __init max6875_init(void)
index fa57b67593ae5b884c42a9ae7e7704084c905004..90a95ce8dc344953365cc1ec3d5eafc58e02a490 100644 (file)
@@ -271,7 +271,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait)
        return mask;
 }
 
-static struct file_operations phantom_file_ops = {
+static const struct file_operations phantom_file_ops = {
        .open = phantom_open,
        .release = phantom_release,
        .unlocked_ioctl = phantom_ioctl,
index 300e7ba391a0faffcb436ed4974a573e0a2b4618..41c8fe2a928c6a76967890a7467038e7df703c3c 100644 (file)
@@ -53,7 +53,6 @@ struct gru_stats_s gru_stats;
 /* Guaranteed user available resources on each node */
 static int max_user_cbrs, max_user_dsr_bytes;
 
-static struct file_operations gru_fops;
 static struct miscdevice gru_miscdev;
 
 
@@ -426,7 +425,7 @@ static void __exit gru_exit(void)
        gru_proc_exit();
 }
 
-static struct file_operations gru_fops = {
+static const struct file_operations gru_fops = {
        .owner          = THIS_MODULE,
        .unlocked_ioctl = gru_file_unlocked_ioctl,
        .mmap           = gru_file_mmap,
index 610dbd1fcc820a85cf4fcc667281063cb1b26983..96d10f40fb23e1ba6db97359c53c4e6a8415660f 100644 (file)
@@ -240,7 +240,7 @@ static int mmc_ext_csd_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations mmc_dbg_ext_csd_fops = {
+static const struct file_operations mmc_dbg_ext_csd_fops = {
        .open           = mmc_ext_csd_open,
        .read           = mmc_ext_csd_read,
        .release        = mmc_ext_csd_release,
index 6636354b48ceac476c3ecbb7a88054dd4047d8d2..e1035c8958086b92ee9e563028c573d161cd104d 100644 (file)
@@ -98,6 +98,22 @@ static const unsigned char speed_val[16] =
 static const unsigned int speed_unit[8] =
        { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
 
+/* FUNCE tuples with these types get passed to SDIO drivers */
+static const unsigned char funce_type_whitelist[] = {
+       4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */
+};
+
+static int cistpl_funce_whitelisted(unsigned char type)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) {
+               if (funce_type_whitelist[i] == type)
+                       return 1;
+       }
+       return 0;
+}
+
 static int cistpl_funce_common(struct mmc_card *card,
                               const unsigned char *buf, unsigned size)
 {
@@ -120,6 +136,10 @@ static int cistpl_funce_func(struct sdio_func *func,
        unsigned vsn;
        unsigned min_size;
 
+       /* let SDIO drivers take care of whitelisted FUNCE tuples */
+       if (cistpl_funce_whitelisted(buf[0]))
+               return -EILSEQ;
+
        vsn = func->card->cccr.sdio_vsn;
        min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
 
@@ -154,13 +174,12 @@ static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
        else
                ret = cistpl_funce_common(card, buf, size);
 
-       if (ret) {
+       if (ret && ret != -EILSEQ) {
                printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
                       "type %u\n", mmc_hostname(card->host), size, buf[0]);
-               return ret;
        }
 
-       return 0;
+       return ret;
 }
 
 typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
@@ -253,21 +272,12 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
                for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
                        if (cis_tpl_list[i].code == tpl_code)
                                break;
-               if (i >= ARRAY_SIZE(cis_tpl_list)) {
-                       /* this tuple is unknown to the core */
-                       this->next = NULL;
-                       this->code = tpl_code;
-                       this->size = tpl_link;
-                       *prev = this;
-                       prev = &this->next;
-                       printk(KERN_DEBUG
-                              "%s: queuing CIS tuple 0x%02x length %u\n",
-                              mmc_hostname(card->host), tpl_code, tpl_link);
-               } else {
+               if (i < ARRAY_SIZE(cis_tpl_list)) {
                        const struct cis_tpl *tpl = cis_tpl_list + i;
                        if (tpl_link < tpl->min_size) {
                                printk(KERN_ERR
-                                      "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
+                                      "%s: bad CIS tuple 0x%02x"
+                                      " (length = %u, expected >= %u)\n",
                                       mmc_hostname(card->host),
                                       tpl_code, tpl_link, tpl->min_size);
                                ret = -EINVAL;
@@ -275,7 +285,30 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
                                ret = tpl->parse(card, func,
                                                 this->data, tpl_link);
                        }
-                       kfree(this);
+                       /*
+                        * We don't need the tuple anymore if it was
+                        * successfully parsed by the SDIO core or if it is
+                        * not going to be parsed by SDIO drivers.
+                        */
+                       if (!ret || ret != -EILSEQ)
+                               kfree(this);
+               } else {
+                       /* unknown tuple */
+                       ret = -EILSEQ;
+               }
+
+               if (ret == -EILSEQ) {
+                       /* this tuple is unknown to the core or whitelisted */
+                       this->next = NULL;
+                       this->code = tpl_code;
+                       this->size = tpl_link;
+                       *prev = this;
+                       prev = &this->next;
+                       printk(KERN_DEBUG
+                              "%s: queuing CIS tuple 0x%02x length %u\n",
+                              mmc_hostname(card->host), tpl_code, tpl_link);
+                       /* keep on analyzing tuples */
+                       ret = 0;
                }
 
                ptr += tpl_link;
index 7cb057f3f883837e1fc05e459eef0f3b8219201f..432ae8358c86953a39b9584dce1ebdc085fd30f7 100644 (file)
@@ -276,6 +276,47 @@ config MMC_S3C
 
          If unsure, say N.
 
+config MMC_S3C_HW_SDIO_IRQ
+       bool "Hardware support for SDIO IRQ"
+       depends on MMC_S3C
+       help
+         Enable the hardware support for SDIO interrupts instead of using
+        the generic polling code.
+
+choice
+       prompt "Samsung S3C SD/MMC transfer code"
+       depends on MMC_S3C
+
+config MMC_S3C_PIO
+       bool "Use PIO transfers only"
+       help
+         Use PIO to transfer data between memory and the hardware.
+
+         PIO is slower than DMA as it requires CPU instructions to
+         move the data. This has been the traditional default for
+         the S3C MCI driver.
+
+config MMC_S3C_DMA
+       bool "Use DMA transfers only (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         Use DMA to transfer data between memory and the hardare.
+
+         Currently, the DMA support in this driver seems to not be
+         working properly and needs to be debugged before this
+         option is useful.
+
+config MMC_S3C_PIODMA
+       bool "Support for both PIO and DMA (EXPERIMENTAL)"
+       help
+         Compile both the PIO and DMA transfer routines into the
+         driver and let the platform select at run-time which one
+         is best.
+
+         See notes for the DMA option.
+
+endchoice
+
 config MMC_SDRICOH_CS
        tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)"
        depends on EXPERIMENTAL && PCI && PCMCIA
index 3d1e5329da12b9f84a141f544c0aaac8e0f8d92c..705a5894a6bbae304a76b37f649ee0be474b89c4 100644 (file)
@@ -678,7 +678,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
        writel(0, host->base + MMCIMASK1);
        writel(0xfff, host->base + MMCICLEAR);
 
-#ifdef CONFIG_GPIOLIB
        if (gpio_is_valid(plat->gpio_cd)) {
                ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
                if (ret == 0)
@@ -697,7 +696,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
                else if (ret != -ENOSYS)
                        goto err_gpio_wp;
        }
-#endif
 
        ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
        if (ret)
index 8c08cd7efa7f1a9073e6a80bba0dc8696632b2ce..99b74a3510203a2e258d83c9f9f4d9aa4f9db816 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/cpufreq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/io.h>
@@ -58,8 +60,6 @@ static const int dbgmap_debug = dbg_err | dbg_debug;
                dev_dbg(&host->pdev->dev, args);  \
        } while (0)
 
-#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-
 static struct s3c2410_dma_client s3cmci_dma_client = {
        .name           = "s3c-mci",
 };
@@ -164,6 +164,40 @@ static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
 
 #endif /* CONFIG_MMC_DEBUG */
 
+/**
+ * s3cmci_host_usedma - return whether the host is using dma or pio
+ * @host: The host state
+ *
+ * Return true if the host is using DMA to transfer data, else false
+ * to use PIO mode. Will return static data depending on the driver
+ * configuration.
+ */
+static inline bool s3cmci_host_usedma(struct s3cmci_host *host)
+{
+#ifdef CONFIG_MMC_S3C_PIO
+       return false;
+#elif defined(CONFIG_MMC_S3C_DMA)
+       return true;
+#else
+       return host->dodma;
+#endif
+}
+
+/**
+ * s3cmci_host_canpio - return true if host has pio code available
+ *
+ * Return true if the driver has been compiled with the PIO support code
+ * available.
+ */
+static inline bool s3cmci_host_canpio(void)
+{
+#ifdef CONFIG_MMC_S3C_PIO
+       return true;
+#else
+       return false;
+#endif
+}
+
 static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
 {
        u32 newmask;
@@ -190,7 +224,33 @@ static inline u32 disable_imask(struct s3cmci_host *host, u32 imask)
 
 static inline void clear_imask(struct s3cmci_host *host)
 {
-       writel(0, host->base + host->sdiimsk);
+       u32 mask = readl(host->base + host->sdiimsk);
+
+       /* preserve the SDIO IRQ mask state */
+       mask &= S3C2410_SDIIMSK_SDIOIRQ;
+       writel(mask, host->base + host->sdiimsk);
+}
+
+/**
+ * s3cmci_check_sdio_irq - test whether the SDIO IRQ is being signalled
+ * @host: The host to check.
+ *
+ * Test to see if the SDIO interrupt is being signalled in case the
+ * controller has failed to re-detect a card interrupt. Read GPE8 and
+ * see if it is low and if so, signal a SDIO interrupt.
+ *
+ * This is currently called if a request is finished (we assume that the
+ * bus is now idle) and when the SDIO IRQ is enabled in case the IRQ is
+ * already being indicated.
+*/
+static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
+{
+       if (host->sdio_irqen) {
+               if (gpio_get_value(S3C2410_GPE(8)) == 0) {
+                       printk(KERN_DEBUG "%s: signalling irq\n", __func__);
+                       mmc_signal_sdio_irq(host->mmc);
+               }
+       }
 }
 
 static inline int get_data_buffer(struct s3cmci_host *host,
@@ -238,6 +298,64 @@ static inline u32 fifo_free(struct s3cmci_host *host)
        return 63 - fifostat;
 }
 
+/**
+ * s3cmci_enable_irq - enable IRQ, after having disabled it.
+ * @host: The device state.
+ * @more: True if more IRQs are expected from transfer.
+ *
+ * Enable the main IRQ if needed after it has been disabled.
+ *
+ * The IRQ can be one of the following states:
+ *     - disabled during IDLE
+ *     - disabled whilst processing data
+ *     - enabled during transfer
+ *     - enabled whilst awaiting SDIO interrupt detection
+ */
+static void s3cmci_enable_irq(struct s3cmci_host *host, bool more)
+{
+       unsigned long flags;
+       bool enable = false;
+
+       local_irq_save(flags);
+
+       host->irq_enabled = more;
+       host->irq_disabled = false;
+
+       enable = more | host->sdio_irqen;
+
+       if (host->irq_state != enable) {
+               host->irq_state = enable;
+
+               if (enable)
+                       enable_irq(host->irq);
+               else
+                       disable_irq(host->irq);
+       }
+
+       local_irq_restore(flags);
+}
+
+/**
+ *
+ */
+static void s3cmci_disable_irq(struct s3cmci_host *host, bool transfer)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       //printk(KERN_DEBUG "%s: transfer %d\n", __func__, transfer);
+
+       host->irq_disabled = transfer;
+
+       if (transfer && host->irq_state) {
+               host->irq_state = false;
+               disable_irq(host->irq);
+       }
+
+       local_irq_restore(flags);
+}
+
 static void do_pio_read(struct s3cmci_host *host)
 {
        int res;
@@ -374,8 +492,7 @@ static void pio_tasklet(unsigned long data)
 {
        struct s3cmci_host *host = (struct s3cmci_host *) data;
 
-
-       disable_irq(host->irq);
+       s3cmci_disable_irq(host, true);
 
        if (host->pio_active == XFER_WRITE)
                do_pio_write(host);
@@ -395,9 +512,10 @@ static void pio_tasklet(unsigned long data)
                                host->mrq->data->error = -EINVAL;
                }
 
+               s3cmci_enable_irq(host, false);
                finalize_request(host);
        } else
-               enable_irq(host->irq);
+               s3cmci_enable_irq(host, true);
 }
 
 /*
@@ -432,17 +550,27 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
        struct s3cmci_host *host = dev_id;
        struct mmc_command *cmd;
        u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
-       u32 mci_cclear, mci_dclear;
+       u32 mci_cclear = 0, mci_dclear;
        unsigned long iflags;
 
+       mci_dsta = readl(host->base + S3C2410_SDIDSTA);
+       mci_imsk = readl(host->base + host->sdiimsk);
+
+       if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
+               if (mci_imsk & S3C2410_SDIIMSK_SDIOIRQ) {
+                       mci_dclear = S3C2410_SDIDSTA_SDIOIRQDETECT;
+                       writel(mci_dclear, host->base + S3C2410_SDIDSTA);
+
+                       mmc_signal_sdio_irq(host->mmc);
+                       return IRQ_HANDLED;
+               }
+       }
+
        spin_lock_irqsave(&host->complete_lock, iflags);
 
        mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
-       mci_dsta = readl(host->base + S3C2410_SDIDSTA);
        mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
        mci_fsta = readl(host->base + S3C2410_SDIFSTA);
-       mci_imsk = readl(host->base + host->sdiimsk);
-       mci_cclear = 0;
        mci_dclear = 0;
 
        if ((host->complete_what == COMPLETION_NONE) ||
@@ -466,7 +594,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
                goto irq_out;
        }
 
-       if (!host->dodma) {
+       if (!s3cmci_host_usedma(host)) {
                if ((host->pio_active == XFER_WRITE) &&
                    (mci_fsta & S3C2410_SDIFSTA_TFDET)) {
 
@@ -673,6 +801,7 @@ static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,
        dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n",
                size, mci_dsta, mci_dcnt);
 
+       host->dma_complete = 1;
        host->complete_what = COMPLETION_FINALIZE;
 
 out:
@@ -683,9 +812,9 @@ out:
 fail_request:
        host->mrq->data->error = -EINVAL;
        host->complete_what = COMPLETION_FINALIZE;
-       writel(0, host->base + host->sdiimsk);
-       goto out;
+       clear_imask(host);
 
+       goto out;
 }
 
 static void finalize_request(struct s3cmci_host *host)
@@ -702,8 +831,9 @@ static void finalize_request(struct s3cmci_host *host)
 
        if (cmd->data && (cmd->error == 0) &&
            (cmd->data->error == 0)) {
-               if (host->dodma && (!host->dma_complete)) {
-                       dbg(host, dbg_dma, "DMA Missing!\n");
+               if (s3cmci_host_usedma(host) && (!host->dma_complete)) {
+                       dbg(host, dbg_dma, "DMA Missing (%d)!\n",
+                           host->dma_complete);
                        return;
                }
        }
@@ -728,7 +858,7 @@ static void finalize_request(struct s3cmci_host *host)
        writel(0, host->base + S3C2410_SDICMDARG);
        writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
        writel(0, host->base + S3C2410_SDICMDCON);
-       writel(0, host->base + host->sdiimsk);
+       clear_imask(host);
 
        if (cmd->data && cmd->error)
                cmd->data->error = cmd->error;
@@ -754,7 +884,7 @@ static void finalize_request(struct s3cmci_host *host)
        /* If we had an error while transfering data we flush the
         * DMA channel and the fifo to clear out any garbage. */
        if (mrq->data->error != 0) {
-               if (host->dodma)
+               if (s3cmci_host_usedma(host))
                        s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
 
                if (host->is2440) {
@@ -776,6 +906,8 @@ static void finalize_request(struct s3cmci_host *host)
 request_done:
        host->complete_what = COMPLETION_NONE;
        host->mrq = NULL;
+
+       s3cmci_check_sdio_irq(host);
        mmc_request_done(host->mmc, mrq);
 }
 
@@ -872,7 +1004,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
 
        dcon  = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
 
-       if (host->dodma)
+       if (s3cmci_host_usedma(host))
                dcon |= S3C2410_SDIDCON_DMAEN;
 
        if (host->bus_width == MMC_BUS_WIDTH_4)
@@ -950,7 +1082,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
 static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
 {
        int dma_len, i;
-       int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
+       int rw = data->flags & MMC_DATA_WRITE;
 
        BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
@@ -958,7 +1090,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
        s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
 
        dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
-                            (rw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+                            rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
        if (dma_len == 0)
                return -ENOMEM;
@@ -969,11 +1101,11 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
        for (i = 0; i < dma_len; i++) {
                int res;
 
-               dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i,
-                       sg_dma_address(&data->sg[i]),
-                       sg_dma_len(&data->sg[i]));
+               dbg(host, dbg_dma, "enqueue %i: %08x@%u\n", i,
+                   sg_dma_address(&data->sg[i]),
+                   sg_dma_len(&data->sg[i]));
 
-               res = s3c2410_dma_enqueue(host->dma, (void *) host,
+               res = s3c2410_dma_enqueue(host->dma, host,
                                          sg_dma_address(&data->sg[i]),
                                          sg_dma_len(&data->sg[i]));
 
@@ -1018,7 +1150,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
                        return;
                }
 
-               if (host->dodma)
+               if (s3cmci_host_usedma(host))
                        res = s3cmci_prepare_dma(host, cmd->data);
                else
                        res = s3cmci_prepare_pio(host, cmd->data);
@@ -1037,7 +1169,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
        s3cmci_send_command(host, cmd);
 
        /* Enable Interrupt */
-       enable_irq(host->irq);
+       s3cmci_enable_irq(host, true);
 }
 
 static int s3cmci_card_present(struct mmc_host *mmc)
@@ -1049,7 +1181,7 @@ static int s3cmci_card_present(struct mmc_host *mmc)
        if (pdata->gpio_detect == 0)
                return -ENOSYS;
 
-       ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1;
+       ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
        return ret ^ pdata->detect_invert;
 }
 
@@ -1104,12 +1236,12 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        switch (ios->power_mode) {
        case MMC_POWER_ON:
        case MMC_POWER_UP:
-               s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
-               s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
-               s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
-               s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
-               s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
-               s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+               s3c2410_gpio_cfgpin(S3C2410_GPE(5), S3C2410_GPE5_SDCLK);
+               s3c2410_gpio_cfgpin(S3C2410_GPE(6), S3C2410_GPE6_SDCMD);
+               s3c2410_gpio_cfgpin(S3C2410_GPE(7), S3C2410_GPE7_SDDAT0);
+               s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
+               s3c2410_gpio_cfgpin(S3C2410_GPE(9), S3C2410_GPE9_SDDAT2);
+               s3c2410_gpio_cfgpin(S3C2410_GPE(10), S3C2410_GPE10_SDDAT3);
 
                if (host->pdata->set_power)
                        host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1121,8 +1253,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        case MMC_POWER_OFF:
        default:
-               s3c2410_gpio_setpin(S3C2410_GPE5, 0);
-               s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPIO_OUTPUT);
+               gpio_direction_output(S3C2410_GPE(5), 0);
 
                if (host->is2440)
                        mci_con |= S3C2440_SDICON_SDRESET;
@@ -1168,7 +1299,7 @@ static int s3cmci_get_ro(struct mmc_host *mmc)
        struct s3c24xx_mci_pdata *pdata = host->pdata;
        int ret;
 
-       if (pdata->gpio_wprotect == 0)
+       if (pdata->no_wprotect)
                return 0;
 
        ret = s3c2410_gpio_getpin(pdata->gpio_wprotect);
@@ -1179,11 +1310,52 @@ static int s3cmci_get_ro(struct mmc_host *mmc)
        return ret;
 }
 
+static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+       struct s3cmci_host *host = mmc_priv(mmc);
+       unsigned long flags;
+       u32 con;
+
+       local_irq_save(flags);
+
+       con = readl(host->base + S3C2410_SDICON);
+       host->sdio_irqen = enable;
+
+       if (enable == host->sdio_irqen)
+               goto same_state;
+
+       if (enable) {
+               con |= S3C2410_SDICON_SDIOIRQ;
+               enable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
+
+               if (!host->irq_state && !host->irq_disabled) {
+                       host->irq_state = true;
+                       enable_irq(host->irq);
+               }
+       } else {
+               disable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
+               con &= ~S3C2410_SDICON_SDIOIRQ;
+
+               if (!host->irq_enabled && host->irq_state) {
+                       disable_irq_nosync(host->irq);
+                       host->irq_state = false;
+               }
+       }
+
+       writel(con, host->base + S3C2410_SDICON);
+
+ same_state:
+       local_irq_restore(flags);
+
+       s3cmci_check_sdio_irq(host);
+}
+
 static struct mmc_host_ops s3cmci_ops = {
        .request        = s3cmci_request,
        .set_ios        = s3cmci_set_ios,
        .get_ro         = s3cmci_get_ro,
        .get_cd         = s3cmci_card_present,
+       .enable_sdio_irq = s3cmci_enable_sdio_irq,
 };
 
 static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
@@ -1246,11 +1418,140 @@ static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
 }
 #endif
 
-static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
+
+#ifdef CONFIG_DEBUG_FS
+
+static int s3cmci_state_show(struct seq_file *seq, void *v)
+{
+       struct s3cmci_host *host = seq->private;
+
+       seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
+       seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
+       seq_printf(seq, "Prescale = %d\n", host->prescaler);
+       seq_printf(seq, "is2440 = %d\n", host->is2440);
+       seq_printf(seq, "IRQ = %d\n", host->irq);
+       seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
+       seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
+       seq_printf(seq, "IRQ state = %d\n", host->irq_state);
+       seq_printf(seq, "CD IRQ = %d\n", host->irq_cd);
+       seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host));
+       seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk);
+       seq_printf(seq, "SDIDATA at %d\n", host->sdidata);
+
+       return 0;
+}
+
+static int s3cmci_state_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, s3cmci_state_show, inode->i_private);
+}
+
+static const struct file_operations s3cmci_fops_state = {
+       .owner          = THIS_MODULE,
+       .open           = s3cmci_state_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+#define DBG_REG(_r) { .addr = S3C2410_SDI##_r, .name = #_r }
+
+struct s3cmci_reg {
+       unsigned short  addr;
+       unsigned char   *name;
+} debug_regs[] = {
+       DBG_REG(CON),
+       DBG_REG(PRE),
+       DBG_REG(CMDARG),
+       DBG_REG(CMDCON),
+       DBG_REG(CMDSTAT),
+       DBG_REG(RSP0),
+       DBG_REG(RSP1),
+       DBG_REG(RSP2),
+       DBG_REG(RSP3),
+       DBG_REG(TIMER),
+       DBG_REG(BSIZE),
+       DBG_REG(DCON),
+       DBG_REG(DCNT),
+       DBG_REG(DSTA),
+       DBG_REG(FSTA),
+       {}
+};
+
+static int s3cmci_regs_show(struct seq_file *seq, void *v)
+{
+       struct s3cmci_host *host = seq->private;
+       struct s3cmci_reg *rptr = debug_regs;
+
+       for (; rptr->name; rptr++)
+               seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name,
+                          readl(host->base + rptr->addr));
+
+       seq_printf(seq, "SDIIMSK\t=0x%08x\n", readl(host->base + host->sdiimsk));
+
+       return 0;
+}
+
+static int s3cmci_regs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, s3cmci_regs_show, inode->i_private);
+}
+
+static const struct file_operations s3cmci_fops_regs = {
+       .owner          = THIS_MODULE,
+       .open           = s3cmci_regs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void s3cmci_debugfs_attach(struct s3cmci_host *host)
+{
+       struct device *dev = &host->pdev->dev;
+
+       host->debug_root = debugfs_create_dir(dev_name(dev), NULL);
+       if (IS_ERR(host->debug_root)) {
+               dev_err(dev, "failed to create debugfs root\n");
+               return;
+       }
+
+       host->debug_state = debugfs_create_file("state", 0444,
+                                               host->debug_root, host,
+                                               &s3cmci_fops_state);
+
+       if (IS_ERR(host->debug_state))
+               dev_err(dev, "failed to create debug state file\n");
+
+       host->debug_regs = debugfs_create_file("regs", 0444,
+                                              host->debug_root, host,
+                                              &s3cmci_fops_regs);
+
+       if (IS_ERR(host->debug_regs))
+               dev_err(dev, "failed to create debug regs file\n");
+}
+
+static void s3cmci_debugfs_remove(struct s3cmci_host *host)
+{
+       debugfs_remove(host->debug_regs);
+       debugfs_remove(host->debug_state);
+       debugfs_remove(host->debug_root);
+}
+
+#else
+static inline void s3cmci_debugfs_attach(struct s3cmci_host *host) { }
+static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __devinit s3cmci_probe(struct platform_device *pdev)
 {
        struct s3cmci_host *host;
        struct mmc_host *mmc;
        int ret;
+       int is2440;
+       int i;
+
+       is2440 = platform_get_device_id(pdev)->driver_data;
 
        mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
        if (!mmc) {
@@ -1258,6 +1559,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
                goto probe_out;
        }
 
+       for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
+               ret = gpio_request(i, dev_name(&pdev->dev));
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get gpio %d\n", i);
+
+                       for (i--; i >= S3C2410_GPE(5); i--)
+                               gpio_free(i);
+
+                       goto probe_free_host;
+               }
+       }
+
        host = mmc_priv(mmc);
        host->mmc       = mmc;
        host->pdev      = pdev;
@@ -1282,11 +1595,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
                host->clk_div   = 2;
        }
 
-       host->dodma             = 0;
        host->complete_what     = COMPLETION_NONE;
        host->pio_active        = XFER_NONE;
 
-       host->dma               = S3CMCI_DMA;
+#ifdef CONFIG_MMC_S3C_PIODMA
+       host->dodma             = host->pdata->dma;
+#endif
 
        host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!host->mem) {
@@ -1294,19 +1608,19 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
                        "failed to get io memory region resouce.\n");
 
                ret = -ENOENT;
-               goto probe_free_host;
+               goto probe_free_gpio;
        }
 
        host->mem = request_mem_region(host->mem->start,
-                                      RESSIZE(host->mem), pdev->name);
+                                      resource_size(host->mem), pdev->name);
 
        if (!host->mem) {
                dev_err(&pdev->dev, "failed to request io memory region.\n");
                ret = -ENOENT;
-               goto probe_free_host;
+               goto probe_free_gpio;
        }
 
-       host->base = ioremap(host->mem->start, RESSIZE(host->mem));
+       host->base = ioremap(host->mem->start, resource_size(host->mem));
        if (!host->base) {
                dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
                ret = -EINVAL;
@@ -1331,31 +1645,60 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
         * ensure we don't lock the system with un-serviceable requests. */
 
        disable_irq(host->irq);
+       host->irq_state = false;
 
-       host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
-
-       if (host->irq_cd >= 0) {
-               if (request_irq(host->irq_cd, s3cmci_irq_cd,
-                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                               DRIVER_NAME, host)) {
-                       dev_err(&pdev->dev, "can't get card detect irq.\n");
-                       ret = -ENOENT;
+       if (!host->pdata->no_detect) {
+               ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get detect gpio\n");
                        goto probe_free_irq;
                }
-       } else {
-               dev_warn(&pdev->dev, "host detect has no irq available\n");
-               s3c2410_gpio_cfgpin(host->pdata->gpio_detect,
-                                   S3C2410_GPIO_INPUT);
+
+               host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
+
+               if (host->irq_cd >= 0) {
+                       if (request_irq(host->irq_cd, s3cmci_irq_cd,
+                                       IRQF_TRIGGER_RISING |
+                                       IRQF_TRIGGER_FALLING,
+                                       DRIVER_NAME, host)) {
+                               dev_err(&pdev->dev,
+                                       "can't get card detect irq.\n");
+                               ret = -ENOENT;
+                               goto probe_free_gpio_cd;
+                       }
+               } else {
+                       dev_warn(&pdev->dev,
+                                "host detect has no irq available\n");
+                       gpio_direction_input(host->pdata->gpio_detect);
+               }
+       } else
+               host->irq_cd = -1;
+
+       if (!host->pdata->no_wprotect) {
+               ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get writeprotect\n");
+                       goto probe_free_irq_cd;
+               }
+
+               gpio_direction_input(host->pdata->gpio_wprotect);
        }
 
-       if (host->pdata->gpio_wprotect)
-               s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
-                                   S3C2410_GPIO_INPUT);
+       /* depending on the dma state, get a dma channel to use. */
 
-       if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) {
-               dev_err(&pdev->dev, "unable to get DMA channel.\n");
-               ret = -EBUSY;
-               goto probe_free_irq_cd;
+       if (s3cmci_host_usedma(host)) {
+               host->dma = s3c2410_dma_request(DMACH_SDI, &s3cmci_dma_client,
+                                               host);
+               if (host->dma < 0) {
+                       dev_err(&pdev->dev, "cannot get DMA channel.\n");
+                       if (!s3cmci_host_canpio()) {
+                               ret = -EBUSY;
+                               goto probe_free_gpio_wp;
+                       } else {
+                               dev_warn(&pdev->dev, "falling back to PIO.\n");
+                               host->dodma = 0;
+                       }
+               }
        }
 
        host->clk = clk_get(&pdev->dev, "sdi");
@@ -1363,7 +1706,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
                dev_err(&pdev->dev, "failed to find clock source.\n");
                ret = PTR_ERR(host->clk);
                host->clk = NULL;
-               goto probe_free_host;
+               goto probe_free_dma;
        }
 
        ret = clk_enable(host->clk);
@@ -1376,7 +1719,11 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
 
        mmc->ops        = &s3cmci_ops;
        mmc->ocr_avail  = MMC_VDD_32_33 | MMC_VDD_33_34;
+#ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
+       mmc->caps       = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+#else
        mmc->caps       = MMC_CAP_4_BIT_DATA;
+#endif
        mmc->f_min      = host->clk_rate / (host->clk_div * 256);
        mmc->f_max      = host->clk_rate / host->clk_div;
 
@@ -1408,8 +1755,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
                goto free_cpufreq;
        }
 
+       s3cmci_debugfs_attach(host);
+
        platform_set_drvdata(pdev, mmc);
-       dev_info(&pdev->dev, "initialisation done.\n");
+       dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),
+                s3cmci_host_usedma(host) ? "dma" : "pio",
+                mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
 
        return 0;
 
@@ -1422,6 +1773,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
  clk_free:
        clk_put(host->clk);
 
+ probe_free_dma:
+       if (s3cmci_host_usedma(host))
+               s3c2410_dma_free(host->dma, &s3cmci_dma_client);
+
+ probe_free_gpio_wp:
+       if (!host->pdata->no_wprotect)
+               gpio_free(host->pdata->gpio_wprotect);
+
+ probe_free_gpio_cd:
+       if (!host->pdata->no_detect)
+               gpio_free(host->pdata->gpio_detect);
+
  probe_free_irq_cd:
        if (host->irq_cd >= 0)
                free_irq(host->irq_cd, host);
@@ -1433,10 +1796,15 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
        iounmap(host->base);
 
  probe_free_mem_region:
-       release_mem_region(host->mem->start, RESSIZE(host->mem));
+       release_mem_region(host->mem->start, resource_size(host->mem));
+
+ probe_free_gpio:
+       for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+               gpio_free(i);
 
  probe_free_host:
        mmc_free_host(mmc);
+
  probe_out:
        return ret;
 }
@@ -1449,6 +1817,7 @@ static void s3cmci_shutdown(struct platform_device *pdev)
        if (host->irq_cd >= 0)
                free_irq(host->irq_cd, host);
 
+       s3cmci_debugfs_remove(host);
        s3cmci_cpufreq_deregister(host);
        mmc_remove_host(mmc);
        clk_disable(host->clk);
@@ -1458,104 +1827,102 @@ static int __devexit s3cmci_remove(struct platform_device *pdev)
 {
        struct mmc_host         *mmc  = platform_get_drvdata(pdev);
        struct s3cmci_host      *host = mmc_priv(mmc);
+       struct s3c24xx_mci_pdata *pd = host->pdata;
+       int i;
 
        s3cmci_shutdown(pdev);
 
        clk_put(host->clk);
 
        tasklet_disable(&host->pio_tasklet);
-       s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client);
+
+       if (s3cmci_host_usedma(host))
+               s3c2410_dma_free(host->dma, &s3cmci_dma_client);
 
        free_irq(host->irq, host);
 
+       if (!pd->no_wprotect)
+               gpio_free(pd->gpio_wprotect);
+
+       if (!pd->no_detect)
+               gpio_free(pd->gpio_detect);
+
+       for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+               gpio_free(i);
+
+
        iounmap(host->base);
-       release_mem_region(host->mem->start, RESSIZE(host->mem));
+       release_mem_region(host->mem->start, resource_size(host->mem));
 
        mmc_free_host(mmc);
        return 0;
 }
 
-static int __devinit s3cmci_2410_probe(struct platform_device *dev)
-{
-       return s3cmci_probe(dev, 0);
-}
+static struct platform_device_id s3cmci_driver_ids[] = {
+       {
+               .name   = "s3c2410-sdi",
+               .driver_data    = 0,
+       }, {
+               .name   = "s3c2412-sdi",
+               .driver_data    = 1,
+       }, {
+               .name   = "s3c2440-sdi",
+               .driver_data    = 1,
+       },
+       { }
+};
 
-static int __devinit s3cmci_2412_probe(struct platform_device *dev)
-{
-       return s3cmci_probe(dev, 1);
-}
+MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
 
-static int __devinit s3cmci_2440_probe(struct platform_device *dev)
-{
-       return s3cmci_probe(dev, 1);
-}
 
 #ifdef CONFIG_PM
 
-static int s3cmci_suspend(struct platform_device *dev, pm_message_t state)
+static int s3cmci_suspend(struct device *dev)
 {
-       struct mmc_host *mmc = platform_get_drvdata(dev);
+       struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
+       struct pm_message event = { PM_EVENT_SUSPEND };
 
-       return  mmc_suspend_host(mmc, state);
+       return mmc_suspend_host(mmc, event);
 }
 
-static int s3cmci_resume(struct platform_device *dev)
+static int s3cmci_resume(struct device *dev)
 {
-       struct mmc_host *mmc = platform_get_drvdata(dev);
+       struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
 
        return mmc_resume_host(mmc);
 }
 
-#else /* CONFIG_PM */
-#define s3cmci_suspend NULL
-#define s3cmci_resume NULL
-#endif /* CONFIG_PM */
-
-
-static struct platform_driver s3cmci_2410_driver = {
-       .driver.name    = "s3c2410-sdi",
-       .driver.owner   = THIS_MODULE,
-       .probe          = s3cmci_2410_probe,
-       .remove         = __devexit_p(s3cmci_remove),
-       .shutdown       = s3cmci_shutdown,
+static struct dev_pm_ops s3cmci_pm = {
        .suspend        = s3cmci_suspend,
        .resume         = s3cmci_resume,
 };
 
-static struct platform_driver s3cmci_2412_driver = {
-       .driver.name    = "s3c2412-sdi",
-       .driver.owner   = THIS_MODULE,
-       .probe          = s3cmci_2412_probe,
-       .remove         = __devexit_p(s3cmci_remove),
-       .shutdown       = s3cmci_shutdown,
-       .suspend        = s3cmci_suspend,
-       .resume         = s3cmci_resume,
-};
+#define s3cmci_pm_ops &s3cmci_pm
+#else /* CONFIG_PM */
+#define s3cmci_pm_ops NULL
+#endif /* CONFIG_PM */
 
-static struct platform_driver s3cmci_2440_driver = {
-       .driver.name    = "s3c2440-sdi",
-       .driver.owner   = THIS_MODULE,
-       .probe          = s3cmci_2440_probe,
+
+static struct platform_driver s3cmci_driver = {
+       .driver = {
+               .name   = "s3c-sdi",
+               .owner  = THIS_MODULE,
+               .pm     = s3cmci_pm_ops,
+       },
+       .id_table       = s3cmci_driver_ids,
+       .probe          = s3cmci_probe,
        .remove         = __devexit_p(s3cmci_remove),
        .shutdown       = s3cmci_shutdown,
-       .suspend        = s3cmci_suspend,
-       .resume         = s3cmci_resume,
 };
 
-
 static int __init s3cmci_init(void)
 {
-       platform_driver_register(&s3cmci_2410_driver);
-       platform_driver_register(&s3cmci_2412_driver);
-       platform_driver_register(&s3cmci_2440_driver);
-       return 0;
+       return platform_driver_register(&s3cmci_driver);
 }
 
 static void __exit s3cmci_exit(void)
 {
-       platform_driver_unregister(&s3cmci_2410_driver);
-       platform_driver_unregister(&s3cmci_2412_driver);
-       platform_driver_unregister(&s3cmci_2440_driver);
+       platform_driver_unregister(&s3cmci_driver);
 }
 
 module_init(s3cmci_init);
@@ -1564,6 +1931,3 @@ module_exit(s3cmci_exit);
 MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");
-MODULE_ALIAS("platform:s3c2410-sdi");
-MODULE_ALIAS("platform:s3c2412-sdi");
-MODULE_ALIAS("platform:s3c2440-sdi");
index ca1ba3d58cfd545a9c730f56135fb99506391e94..c76b53dbeb6179a3545bbb26b7aa87d50302477e 100644 (file)
@@ -8,9 +8,6 @@
  * published by the Free Software Foundation.
  */
 
-/* FIXME: DMA Resource management ?! */
-#define S3CMCI_DMA 0
-
 enum s3cmci_waitfor {
        COMPLETION_NONE,
        COMPLETION_FINALIZE,
@@ -42,6 +39,11 @@ struct s3cmci_host {
        int                     dodma;
        int                     dmatogo;
 
+       bool                    irq_disabled;
+       bool                    irq_enabled;
+       bool                    irq_state;
+       int                     sdio_irqen;
+
        struct mmc_request      *mrq;
        int                     cmd_is_stop;
 
@@ -68,6 +70,12 @@ struct s3cmci_host {
        unsigned int            ccnt, dcnt;
        struct tasklet_struct   pio_tasklet;
 
+#ifdef CONFIG_DEBUG_FS
+       struct dentry           *debug_root;
+       struct dentry           *debug_state;
+       struct dentry           *debug_regs;
+#endif
+
 #ifdef CONFIG_CPU_FREQ
        struct notifier_block   freq_transition;
 #endif
index 0acbf4f5be50d31e31ccbce8d5e51db854e57f22..8ca17a3e96eaa0e85251ecf861d23673b9df3927 100644 (file)
@@ -32,14 +32,6 @@ struct mtd_blkcore_priv {
        spinlock_t queue_lock;
 };
 
-static int blktrans_discard_request(struct request_queue *q,
-                                   struct request *req)
-{
-       req->cmd_type = REQ_TYPE_LINUX_BLOCK;
-       req->cmd[0] = REQ_LB_OP_DISCARD;
-       return 0;
-}
-
 static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                               struct mtd_blktrans_dev *dev,
                               struct request *req)
@@ -52,10 +44,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 
        buf = req->buffer;
 
-       if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
-           req->cmd[0] == REQ_LB_OP_DISCARD)
-               return tr->discard(dev, block, nsect);
-
        if (!blk_fs_request(req))
                return -EIO;
 
@@ -63,6 +51,9 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
            get_capacity(req->rq_disk))
                return -EIO;
 
+       if (blk_discard_rq(req))
+               return tr->discard(dev, block, nsect);
+
        switch(rq_data_dir(req)) {
        case READ:
                for (; nsect > 0; nsect--, block++, buf += tr->blksize)
@@ -380,8 +371,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        tr->blkcore_priv->rq->queuedata = tr;
        blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize);
        if (tr->discard)
-               blk_queue_set_discard(tr->blkcore_priv->rq,
-                                     blktrans_discard_request);
+               queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+                                       tr->blkcore_priv->rq);
 
        tr->blkshift = ffs(tr->blksize) - 1;
 
index b9eeadf01b749cb9ae223ee6f63ba63e685db98e..975e25b19ebe8a19502366c0c2763b3f6298058b 100644 (file)
@@ -805,52 +805,54 @@ static void poll_vortex(struct net_device *dev)
 
 #ifdef CONFIG_PM
 
-static int vortex_suspend(struct pci_dev *pdev, pm_message_t state)
+static int vortex_suspend(struct device *dev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct net_device *ndev = pci_get_drvdata(pdev);
+
+       if (!ndev || !netif_running(ndev))
+               return 0;
+
+       netif_device_detach(ndev);
+       vortex_down(ndev, 1);
 
-       if (dev && netdev_priv(dev)) {
-               if (netif_running(dev)) {
-                       netif_device_detach(dev);
-                       vortex_down(dev, 1);
-                       disable_irq(dev->irq);
-               }
-               pci_save_state(pdev);
-               pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
-               pci_disable_device(pdev);
-               pci_set_power_state(pdev, pci_choose_state(pdev, state));
-       }
        return 0;
 }
 
-static int vortex_resume(struct pci_dev *pdev)
+static int vortex_resume(struct device *dev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct vortex_private *vp = netdev_priv(dev);
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct net_device *ndev = pci_get_drvdata(pdev);
        int err;
 
-       if (dev && vp) {
-               pci_set_power_state(pdev, PCI_D0);
-               pci_restore_state(pdev);
-               err = pci_enable_device(pdev);
-               if (err) {
-                       pr_warning("%s: Could not enable device\n",
-                               dev->name);
-                       return err;
-               }
-               pci_set_master(pdev);
-               if (netif_running(dev)) {
-                       err = vortex_up(dev);
-                       if (err)
-                               return err;
-                       enable_irq(dev->irq);
-                       netif_device_attach(dev);
-               }
-       }
+       if (!ndev || !netif_running(ndev))
+               return 0;
+
+       err = vortex_up(ndev);
+       if (err)
+               return err;
+
+       netif_device_attach(ndev);
+
        return 0;
 }
 
-#endif /* CONFIG_PM */
+static struct dev_pm_ops vortex_pm_ops = {
+       .suspend = vortex_suspend,
+       .resume = vortex_resume,
+       .freeze = vortex_suspend,
+       .thaw = vortex_resume,
+       .poweroff = vortex_suspend,
+       .restore = vortex_resume,
+};
+
+#define VORTEX_PM_OPS (&vortex_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define VORTEX_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
 
 #ifdef CONFIG_EISA
 static struct eisa_device_id vortex_eisa_ids[] = {
@@ -3199,10 +3201,7 @@ static struct pci_driver vortex_driver = {
        .probe          = vortex_init_one,
        .remove         = __devexit_p(vortex_remove_one),
        .id_table       = vortex_pci_tbl,
-#ifdef CONFIG_PM
-       .suspend        = vortex_suspend,
-       .resume         = vortex_resume,
-#endif
+       .driver.pm      = VORTEX_PM_OPS,
 };
 
 
index 2bea67c134f022456a15fdad71fcd3f089ca52d2..712776089b4600349c7e6cdd6148e63d819b53fa 100644 (file)
@@ -1738,6 +1738,13 @@ config KS8851
        help
          SPI driver for Micrel KS8851 SPI attached network chip.
 
+config KS8851_MLL
+       tristate "Micrel KS8851 MLL"
+       depends on HAS_IOMEM
+       help
+         This platform driver is for Micrel KS8851 Address/data bus
+         multiplexed network chip.
+
 config VIA_RHINE
        tristate "VIA Rhine support"
        depends on NET_PCI && PCI
index ae8cd30f13d6548690acdf90b114e1190f6ab465..d866b8cf65d19b184574dbb3ba3463899e31ba4a 100644 (file)
@@ -89,6 +89,7 @@ obj-$(CONFIG_SKY2) += sky2.o
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_KS8842)   += ks8842.o
 obj-$(CONFIG_KS8851)   += ks8851.o
+obj-$(CONFIG_KS8851_MLL)       += ks8851_mll.o
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
index 09d270913c5041f866537f9e7c4ae6d3a3d976c8..ba29dc319b34860b651696b929b8af908b0b8428 100644 (file)
@@ -90,7 +90,7 @@ static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
                if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
                        break;
                udelay(1);
-       } while (limit-- >= 0);
+       } while (limit-- > 0);
 
        return (limit < 0) ? 1 : 0;
 }
index 684c6fe24c8d538daa5145c803ac3c66e717fec2..a80da0e14a52b31c22706e641290ef2da1b7c455 100644 (file)
@@ -258,6 +258,7 @@ struct be_adapter {
        bool link_up;
        u32 port_num;
        bool promiscuous;
+       u32 cap;
 };
 
 extern const struct ethtool_ops be_ethtool_ops;
index 3dd76c4170bfc000657f4b65713b662d20c8de04..79d35d122c08c8caa066cb54d8f5f91b11de141d 100644 (file)
@@ -1068,7 +1068,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
 }
 
 /* Uses mbox */
-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
+int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_query_fw_cfg *req;
@@ -1088,6 +1088,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
        if (!status) {
                struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
                *port_num = le32_to_cpu(resp->phys_port);
+               *cap = le32_to_cpu(resp->function_cap);
        }
 
        spin_unlock(&adapter->mbox_lock);
index 93e432f3d926f784ecf586375ceb1c0c54c76183..8b4c2cb9ad624faff6d8fa13cbff44dbd7143655 100644 (file)
@@ -760,7 +760,8 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter,
                        u32 tx_fc, u32 rx_fc);
 extern int be_cmd_get_flow_control(struct be_adapter *adapter,
                        u32 *tx_fc, u32 *rx_fc);
-extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
+extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
+                       u32 *port_num, u32 *cap);
 extern int be_cmd_reset_function(struct be_adapter *adapter);
 extern int be_process_mcc(struct be_adapter *adapter);
 extern int be_cmd_write_flashrom(struct be_adapter *adapter,
index 409cf05959034737273f6b2cb8371a2347102059..2f9b50156e0c4febe663341bb853f9a4e9a83636 100644 (file)
@@ -747,9 +747,16 @@ static void be_rx_compl_process(struct be_adapter *adapter,
                        struct be_eth_rx_compl *rxcp)
 {
        struct sk_buff *skb;
-       u32 vtp, vid;
+       u32 vlanf, vid;
+       u8 vtm;
 
-       vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+       vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+       vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+
+       /* vlanf could be wrongly set in some cards.
+        * ignore if vtm is not set */
+       if ((adapter->cap == 0x400) && !vtm)
+               vlanf = 0;
 
        skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
        if (!skb) {
@@ -772,7 +779,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
        skb->protocol = eth_type_trans(skb, adapter->netdev);
        skb->dev = adapter->netdev;
 
-       if (vtp) {
+       if (vlanf) {
                if (!adapter->vlan_grp || adapter->num_vlans == 0) {
                        kfree_skb(skb);
                        return;
@@ -797,11 +804,18 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
        struct be_eq_obj *eq_obj =  &adapter->rx_eq;
        u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
        u16 i, rxq_idx = 0, vid, j;
+       u8 vtm;
 
        num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
        pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
        vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
        rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+       vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+
+       /* vlanf could be wrongly set in some cards.
+        * ignore if vtm is not set */
+       if ((adapter->cap == 0x400) && !vtm)
+               vlanf = 0;
 
        skb = napi_get_frags(&eq_obj->napi);
        if (!skb) {
@@ -2045,7 +2059,8 @@ static int be_hw_up(struct be_adapter *adapter)
        if (status)
                return status;
 
-       status = be_cmd_query_fw_cfg(adapter, &adapter->port_num);
+       status = be_cmd_query_fw_cfg(adapter,
+                               &adapter->port_num, &adapter->cap);
        return status;
 }
 
index 6044e12ff9fce99f433f514e5eb182bccc5097ee..ff449de6f3c00ab0eb394640cc56b07ce7e968dc 100644 (file)
@@ -1182,6 +1182,7 @@ static ssize_t bonding_store_primary(struct device *d,
                                       ": %s: Setting %s as primary slave.\n",
                                       bond->dev->name, slave->dev->name);
                                bond->primary_slave = slave;
+                               strcpy(bond->params.primary, slave->dev->name);
                                bond_select_active_slave(bond);
                                goto out;
                        }
index 211c8e9182fc51566fffac1fff201da34bc8ee05..46c87ec7960c83c03d10772a4793629c3cd8904d 100644 (file)
@@ -2733,7 +2733,8 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
                        cnic_ulp_init(dev);
                else if (event == NETDEV_UNREGISTER)
                        cnic_ulp_exit(dev);
-               else if (event == NETDEV_UP) {
+
+               if (event == NETDEV_UP) {
                        if (cnic_register_netdev(dev) != 0) {
                                cnic_put(dev);
                                goto done;
index a49235739eef9444d1596df5dfb5248a4aba8a1e..d8b09efdcb5261ec62c28c7b965e63be482d317f 100644 (file)
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION    "2.0.0"
-#define CNIC_MODULE_RELDATE    "May 21, 2009"
+#define CNIC_MODULE_VERSION    "2.0.1"
+#define CNIC_MODULE_RELDATE    "Oct 01, 2009"
 
 #define CNIC_ULP_RDMA          0
 #define CNIC_ULP_ISCSI         1
index 16c193a6c95c1e21e8fdc15a69874cad1e4fd910..0687c6aa4e46e406c0dd67d33169b6574be75f7f 100644 (file)
@@ -4982,12 +4982,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                goto err_pci_reg;
 
        /* AER (Advanced Error Reporting) hooks */
-       err = pci_enable_pcie_error_reporting(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
-                       "0x%x\n", err);
-               /* non-fatal, continue */
-       }
+       pci_enable_pcie_error_reporting(pdev);
 
        pci_set_master(pdev);
        /* PCI config space info */
@@ -5263,7 +5258,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       int err;
 
        /*
         * flush_scheduled work may reschedule our watchdog task, so
@@ -5299,10 +5293,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
        free_netdev(netdev);
 
        /* AER disable */
-       err = pci_disable_pcie_error_reporting(pdev);
-       if (err)
-               dev_err(&pdev->dev,
-                       "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+       pci_disable_pcie_error_reporting(pdev);
 
        pci_disable_device(pdev);
 }
index 33b55f729742efbfd0c370b762463fb8be46ff92..db4b7f1603f662992d551ef6f2baca986baac697 100644 (file)
@@ -258,7 +258,7 @@ static void ax_bump(struct mkiss *ax)
                        }
                        if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
                                printk(KERN_INFO
-                                      "mkiss: %s: Switchting to crc-smack\n",
+                                      "mkiss: %s: Switching to crc-smack\n",
                                       ax->dev->name);
                                ax->crcmode = CRC_MODE_SMACK;
                        }
@@ -272,7 +272,7 @@ static void ax_bump(struct mkiss *ax)
                        }
                        if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
                                printk(KERN_INFO
-                                      "mkiss: %s: Switchting to crc-flexnet\n",
+                                      "mkiss: %s: Switching to crc-flexnet\n",
                                       ax->dev->name);
                                ax->crcmode = CRC_MODE_FLEX;
                        }
index 5d6c1530a8c0458e02ae42305e3accf893f9cdd1..714c3a4a44eff5a1d43b538a6c6cf380bfea445c 100644 (file)
@@ -1246,12 +1246,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        if (err)
                goto err_pci_reg;
 
-       err = pci_enable_pcie_error_reporting(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
-                       "0x%x\n", err);
-               /* non-fatal, continue */
-       }
+       pci_enable_pcie_error_reporting(pdev);
 
        pci_set_master(pdev);
        pci_save_state(pdev);
@@ -1628,7 +1623,6 @@ static void __devexit igb_remove(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       int err;
 
        /* flush_scheduled work may reschedule our watchdog task, so
         * explicitly disable watchdog tasks from being rescheduled  */
@@ -1682,10 +1676,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
 
        free_netdev(netdev);
 
-       err = pci_disable_pcie_error_reporting(pdev);
-       if (err)
-               dev_err(&pdev->dev,
-                       "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+       pci_disable_pcie_error_reporting(pdev);
 
        pci_disable_device(pdev);
 }
index e36e951cbc65ba93bc6acc295a5109ff17beda7a..aa7286bc4364a79bf4fffd9b4b762948621779a6 100644 (file)
@@ -495,7 +495,7 @@ static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
                           cnx->remote_lp);
        } else {
                memcpy(&cnx->cap_ack_event, event,
-                      sizeof(&cnx->cap_ack_event));
+                      sizeof(cnx->cap_ack_event));
                cnx->state |= VETH_STATE_GOTCAPACK;
                veth_kick_statemachine(cnx);
        }
index 56b12f3192f1d5b18d72b77bb03aab9807708b5f..e2d5343f127553d7ad7c5d4b032bd087f66db990 100644 (file)
@@ -425,7 +425,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
 #endif /* CONFIG_DCB */
        default:
                hw_dbg(hw, "Flow control param set incorrectly\n");
-               ret_val = -IXGBE_ERR_CONFIG;
+               ret_val = IXGBE_ERR_CONFIG;
                goto out;
                break;
        }
index 6621e172df3d79533e391777bb2cb0e78050e75a..40ff120a9ad4374e5755f4fa3b3d7010238b8917 100644 (file)
@@ -1355,9 +1355,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 /**
  *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
  *  @hw: pointer to hardware structure
- *  @addr_list: the list of new addresses
- *  @addr_count: number of addresses
- *  @next: iterator function to walk the address list
+ *  @uc_list: the list of new addresses
  *
  *  The given list replaces any existing list.  Clears the secondary addrs from
  *  receive address registers.  Uses unused receive address registers for the
@@ -1663,7 +1661,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
 #endif /* CONFIG_DCB */
        default:
                hw_dbg(hw, "Flow control param set incorrectly\n");
-               ret_val = -IXGBE_ERR_CONFIG;
+               ret_val = IXGBE_ERR_CONFIG;
                goto out;
                break;
        }
@@ -1734,75 +1732,140 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
        s32 ret_val = 0;
        ixgbe_link_speed speed;
        u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
+       u32 links2, anlp1_reg, autoc_reg, links;
        bool link_up;
 
        /*
         * AN should have completed when the cable was plugged in.
         * Look for reasons to bail out.  Bail out if:
         * - FC autoneg is disabled, or if
-        * - we don't have multispeed fiber, or if
-        * - we're not running at 1G, or if
-        * - link is not up, or if
-        * - link is up but AN did not complete, or if
-        * - link is up and AN completed but timed out
+        * - link is not up.
         *
-        * Since we're being called from an LSC, link is already know to be up.
+        * Since we're being called from an LSC, link is already known to be up.
         * So use link_up_wait_to_complete=false.
         */
        hw->mac.ops.check_link(hw, &speed, &link_up, false);
-       linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
-
-       if (hw->fc.disable_fc_autoneg ||
-           !hw->phy.multispeed_fiber ||
-           (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
-           !link_up ||
-           ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
-           ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+
+       if (hw->fc.disable_fc_autoneg || (!link_up)) {
                hw->fc.fc_was_autonegged = false;
                hw->fc.current_mode = hw->fc.requested_mode;
-               hw_dbg(hw, "Autoneg FC was skipped.\n");
                goto out;
        }
 
+       /*
+        * On backplane, bail out if
+        * - backplane autoneg was not completed, or if
+        * - link partner is not AN enabled
+        */
+       if (hw->phy.media_type == ixgbe_media_type_backplane) {
+               links = IXGBE_READ_REG(hw, IXGBE_LINKS);
+               links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
+               if (((links & IXGBE_LINKS_KX_AN_COMP) == 0) ||
+                   ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0)) {
+                       hw->fc.fc_was_autonegged = false;
+                       hw->fc.current_mode = hw->fc.requested_mode;
+                       goto out;
+               }
+       }
+
+       /*
+        * On multispeed fiber at 1g, bail out if
+        * - link is up but AN did not complete, or if
+        * - link is up and AN completed but timed out
+        */
+       if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) {
+               linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+               if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
+                   ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+                       hw->fc.fc_was_autonegged = false;
+                       hw->fc.current_mode = hw->fc.requested_mode;
+                       goto out;
+               }
+       }
+
        /*
         * Read the AN advertisement and LP ability registers and resolve
         * local flow control settings accordingly
         */
-       pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
-       pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
-       if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
-               (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+       if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
+           (hw->phy.media_type != ixgbe_media_type_backplane)) {
+               pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+               pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
+               if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+                   (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+                       /*
+                        * Now we need to check if the user selected Rx ONLY
+                        * of pause frames.  In this case, we had to advertise
+                        * FULL flow control because we could not advertise RX
+                        * ONLY. Hence, we must now check to see if we need to
+                        * turn OFF the TRANSMISSION of PAUSE frames.
+                        */
+                       if (hw->fc.requested_mode == ixgbe_fc_full) {
+                               hw->fc.current_mode = ixgbe_fc_full;
+                               hw_dbg(hw, "Flow Control = FULL.\n");
+                       } else {
+                               hw->fc.current_mode = ixgbe_fc_rx_pause;
+                               hw_dbg(hw, "Flow Control=RX PAUSE only\n");
+                       }
+               } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+                          (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+                          (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+                          (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+                       hw->fc.current_mode = ixgbe_fc_tx_pause;
+                       hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+               } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+                          (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+                          !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+                          (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+                       hw->fc.current_mode = ixgbe_fc_rx_pause;
+                       hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+               } else {
+                       hw->fc.current_mode = ixgbe_fc_none;
+                       hw_dbg(hw, "Flow Control = NONE.\n");
+               }
+       }
+
+       if (hw->phy.media_type == ixgbe_media_type_backplane) {
                /*
-                * Now we need to check if the user selected Rx ONLY
-                * of pause frames.  In this case, we had to advertise
-                * FULL flow control because we could not advertise RX
-                * ONLY. Hence, we must now check to see if we need to
-                * turn OFF the TRANSMISSION of PAUSE frames.
+                * Read the 10g AN autoc and LP ability registers and resolve
+                * local flow control settings accordingly
                 */
-               if (hw->fc.requested_mode == ixgbe_fc_full) {
-                       hw->fc.current_mode = ixgbe_fc_full;
-                       hw_dbg(hw, "Flow Control = FULL.\n");
-               } else {
+               autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+               anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+
+               if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
+                   (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) {
+                       /*
+                        * Now we need to check if the user selected Rx ONLY
+                        * of pause frames.  In this case, we had to advertise
+                        * FULL flow control because we could not advertise RX
+                        * ONLY. Hence, we must now check to see if we need to
+                        * turn OFF the TRANSMISSION of PAUSE frames.
+                        */
+                       if (hw->fc.requested_mode == ixgbe_fc_full) {
+                               hw->fc.current_mode = ixgbe_fc_full;
+                               hw_dbg(hw, "Flow Control = FULL.\n");
+                       } else {
+                               hw->fc.current_mode = ixgbe_fc_rx_pause;
+                               hw_dbg(hw, "Flow Control=RX PAUSE only\n");
+                       }
+               } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
+                          (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
+                          (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
+                          (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
+                       hw->fc.current_mode = ixgbe_fc_tx_pause;
+                       hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+               } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
+                          (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
+                          !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
+                          (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
                        hw->fc.current_mode = ixgbe_fc_rx_pause;
                        hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+               } else {
+                       hw->fc.current_mode = ixgbe_fc_none;
+                       hw_dbg(hw, "Flow Control = NONE.\n");
                }
-       } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
-                  (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
-                  (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
-                  (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
-               hw->fc.current_mode = ixgbe_fc_tx_pause;
-               hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
-       } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
-                  (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
-                  !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
-                  (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
-               hw->fc.current_mode = ixgbe_fc_rx_pause;
-               hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
-       } else {
-               hw->fc.current_mode = ixgbe_fc_none;
-               hw_dbg(hw, "Flow Control = NONE.\n");
        }
-
        /* Record that current_mode is the result of a successful autoneg */
        hw->fc.fc_was_autonegged = true;
 
@@ -1919,7 +1982,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
 #endif /* CONFIG_DCB */
        default:
                hw_dbg(hw, "Flow control param set incorrectly\n");
-               ret_val = -IXGBE_ERR_CONFIG;
+               ret_val = IXGBE_ERR_CONFIG;
                goto out;
                break;
        }
@@ -1927,9 +1990,6 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
        IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
        reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
 
-       /* Enable and restart autoneg to inform the link partner */
-       reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
-
        /* Disable AN timeout */
        if (hw->fc.strict_ieee)
                reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
@@ -1937,6 +1997,70 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
        IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
        hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
 
+       /*
+        * Set up the 10G flow control advertisement registers so the HW
+        * can do fc autoneg once the cable is plugged in.  If we end up
+        * using 1g instead, this is harmless.
+        */
+       reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+       /*
+        * The possible values of fc.requested_mode are:
+        * 0: Flow control is completely disabled
+        * 1: Rx flow control is enabled (we can receive pause frames,
+        *    but not send pause frames).
+        * 2: Tx flow control is enabled (we can send pause frames but
+        *    we do not support receiving pause frames).
+        * 3: Both Rx and Tx flow control (symmetric) are enabled.
+        * other: Invalid.
+        */
+       switch (hw->fc.requested_mode) {
+       case ixgbe_fc_none:
+               /* Flow control completely disabled by software override. */
+               reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
+               break;
+       case ixgbe_fc_rx_pause:
+               /*
+                * Rx Flow control is enabled and Tx Flow control is
+                * disabled by software override. Since there really
+                * isn't a way to advertise that we are capable of RX
+                * Pause ONLY, we will advertise that we support both
+                * symmetric and asymmetric Rx PAUSE.  Later, we will
+                * disable the adapter's ability to send PAUSE frames.
+                */
+               reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
+               break;
+       case ixgbe_fc_tx_pause:
+               /*
+                * Tx Flow control is enabled, and Rx Flow control is
+                * disabled by software override.
+                */
+               reg |= (IXGBE_AUTOC_ASM_PAUSE);
+               reg &= ~(IXGBE_AUTOC_SYM_PAUSE);
+               break;
+       case ixgbe_fc_full:
+               /* Flow control (both Rx and Tx) is enabled by SW override. */
+               reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
+               break;
+#ifdef CONFIG_DCB
+       case ixgbe_fc_pfc:
+               goto out;
+               break;
+#endif /* CONFIG_DCB */
+       default:
+               hw_dbg(hw, "Flow control param set incorrectly\n");
+               ret_val = IXGBE_ERR_CONFIG;
+               goto out;
+               break;
+       }
+       /*
+        * AUTOC restart handles negotiation of 1G and 10G. There is
+        * no need to set the PCS1GCTL register.
+        */
+       reg |= IXGBE_AUTOC_AN_RESTART;
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg);
+       hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
+
 out:
        return ret_val;
 }
@@ -2000,7 +2124,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
 
        while (timeout) {
                if (ixgbe_get_eeprom_semaphore(hw))
-                       return -IXGBE_ERR_SWFW_SYNC;
+                       return IXGBE_ERR_SWFW_SYNC;
 
                gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
                if (!(gssr & (fwmask | swmask)))
@@ -2017,7 +2141,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
 
        if (!timeout) {
                hw_dbg(hw, "Driver can't access resource, GSSR timeout.\n");
-               return -IXGBE_ERR_SWFW_SYNC;
+               return IXGBE_ERR_SWFW_SYNC;
        }
 
        gssr |= swmask;
index 53b0a6680254fdbd816692f0a88e1616f312a7aa..fa314cb005a4dcf15ce8884c0da5e9987f1e2604 100644 (file)
@@ -53,6 +53,10 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
        {"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)},
        {"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)},
+       {"rx_pkts_nic", IXGBE_STAT(stats.gprc)},
+       {"tx_pkts_nic", IXGBE_STAT(stats.gptc)},
+       {"rx_bytes_nic", IXGBE_STAT(stats.gorc)},
+       {"tx_bytes_nic", IXGBE_STAT(stats.gotc)},
        {"lsc_int", IXGBE_STAT(lsc_int)},
        {"tx_busy", IXGBE_STAT(tx_busy)},
        {"non_eop_descs", IXGBE_STAT(non_eop_descs)},
index c407bd9de0dd87644556efcb5b717a835c4657d6..28fbb9d281f915c505c980b246bf1571de7fe3fd 100644 (file)
@@ -49,7 +49,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "2.0.37-k2"
+#define DRV_VERSION "2.0.44-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
 
@@ -1885,12 +1885,29 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
                IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
                adapter->tx_ring[i].head = IXGBE_TDH(j);
                adapter->tx_ring[i].tail = IXGBE_TDT(j);
-               /* Disable Tx Head Writeback RO bit, since this hoses
+               /*
+                * Disable Tx Head Writeback RO bit, since this hoses
                 * bookkeeping if things aren't delivered in order.
                 */
-               txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
+               switch (hw->mac.type) {
+               case ixgbe_mac_82598EB:
+                       txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
+                       break;
+               case ixgbe_mac_82599EB:
+               default:
+                       txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
+                       break;
+               }
                txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
-               IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
+               switch (hw->mac.type) {
+               case ixgbe_mac_82598EB:
+                       IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
+                       break;
+               case ixgbe_mac_82599EB:
+               default:
+                       IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
+                       break;
+               }
        }
        if (hw->mac.type == ixgbe_mac_82599EB) {
                /* We enable 8 traffic classes, DCB only */
@@ -4432,10 +4449,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 
        /* 82598 hardware only has a 32 bit counter in the high register */
        if (hw->mac.type == ixgbe_mac_82599EB) {
+               u64 tmp;
                adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
-               IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
+               tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */
+               adapter->stats.gorc += (tmp << 32);
                adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
-               IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
+               tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */
+               adapter->stats.gotc += (tmp << 32);
                adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
                IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
                adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
@@ -5071,7 +5091,6 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
        /* Right now, we support IPv4 only */
        struct ixgbe_atr_input atr_input;
        struct tcphdr *th;
-       struct udphdr *uh;
        struct iphdr *iph = ip_hdr(skb);
        struct ethhdr *eth = (struct ethhdr *)skb->data;
        u16 vlan_id, src_port, dst_port, flex_bytes;
@@ -5085,12 +5104,6 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
                dst_port = th->dest;
                l4type |= IXGBE_ATR_L4TYPE_TCP;
                /* l4type IPv4 type is 0, no need to assign */
-       } else if(iph->protocol == IPPROTO_UDP) {
-               uh = udp_hdr(skb);
-               src_port = uh->source;
-               dst_port = uh->dest;
-               l4type |= IXGBE_ATR_L4TYPE_UDP;
-               /* l4type IPv4 type is 0, no need to assign */
        } else {
                /* Unsupported L4 header, just bail here */
                return;
@@ -5494,12 +5507,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                goto err_pci_reg;
        }
 
-       err = pci_enable_pcie_error_reporting(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
-                                   "0x%x\n", err);
-               /* non-fatal, continue */
-       }
+       pci_enable_pcie_error_reporting(pdev);
 
        pci_set_master(pdev);
        pci_save_state(pdev);
@@ -5808,7 +5816,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       int err;
 
        set_bit(__IXGBE_DOWN, &adapter->state);
        /* clear the module not found bit to make sure the worker won't
@@ -5859,10 +5866,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 
        free_netdev(netdev);
 
-       err = pci_disable_pcie_error_reporting(pdev);
-       if (err)
-               dev_err(&pdev->dev,
-                       "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+       pci_disable_pcie_error_reporting(pdev);
 
        pci_disable_device(pdev);
 }
index 8761d7899f7d0704440d4bb3766bc671e4043750..7c93e923bf2e1fd2346969eb9625b4867d6407a9 100644 (file)
 #define IXGBE_AUTOC_KX4_SUPP    0x80000000
 #define IXGBE_AUTOC_KX_SUPP     0x40000000
 #define IXGBE_AUTOC_PAUSE       0x30000000
+#define IXGBE_AUTOC_ASM_PAUSE   0x20000000
+#define IXGBE_AUTOC_SYM_PAUSE   0x10000000
 #define IXGBE_AUTOC_RF          0x08000000
 #define IXGBE_AUTOC_PD_TMR      0x06000000
 #define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
 #define IXGBE_LINK_UP_TIME      90 /* 9.0 Seconds */
 #define IXGBE_AUTO_NEG_TIME     45 /* 4.5 Seconds */
 
+#define IXGBE_LINKS2_AN_SUPPORTED   0x00000040
+
 /* PCS1GLSTA Bit Masks */
 #define IXGBE_PCS1GLSTA_LINK_OK         1
 #define IXGBE_PCS1GLSTA_SYNK_OK         0x10
 #define IXGBE_PCS1GLCTL_AN_ENABLE       0x10000
 #define IXGBE_PCS1GLCTL_AN_RESTART      0x20000
 
+/* ANLP1 Bit Masks */
+#define IXGBE_ANLP1_PAUSE               0x0C00
+#define IXGBE_ANLP1_SYM_PAUSE           0x0400
+#define IXGBE_ANLP1_ASM_PAUSE           0x0800
+
 /* SW Semaphore Register bitmasks */
 #define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
 #define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
new file mode 100644 (file)
index 0000000..0be14d7
--- /dev/null
@@ -0,0 +1,1697 @@
+/**
+ * drivers/net/ks8851_mll.c
+ * Copyright (c) 2009 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/**
+ * Supports:
+ * KS8851 16bit MLL chip from Micrel Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/cache.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#define        DRV_NAME        "ks8851_mll"
+
+static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
+#define MAX_RECV_FRAMES                        32
+#define MAX_BUF_SIZE                   2048
+#define TX_BUF_SIZE                    2000
+#define RX_BUF_SIZE                    2000
+
+#define KS_CCR                         0x08
+#define CCR_EEPROM                     (1 << 9)
+#define CCR_SPI                                (1 << 8)
+#define CCR_8BIT                       (1 << 7)
+#define CCR_16BIT                      (1 << 6)
+#define CCR_32BIT                      (1 << 5)
+#define CCR_SHARED                     (1 << 4)
+#define CCR_32PIN                      (1 << 0)
+
+/* MAC address registers */
+#define KS_MARL                                0x10
+#define KS_MARM                                0x12
+#define KS_MARH                                0x14
+
+#define KS_OBCR                                0x20
+#define OBCR_ODS_16MA                  (1 << 6)
+
+#define KS_EEPCR                       0x22
+#define EEPCR_EESA                     (1 << 4)
+#define EEPCR_EESB                     (1 << 3)
+#define EEPCR_EEDO                     (1 << 2)
+#define EEPCR_EESCK                    (1 << 1)
+#define EEPCR_EECS                     (1 << 0)
+
+#define KS_MBIR                                0x24
+#define MBIR_TXMBF                     (1 << 12)
+#define MBIR_TXMBFA                    (1 << 11)
+#define MBIR_RXMBF                     (1 << 4)
+#define MBIR_RXMBFA                    (1 << 3)
+
+#define KS_GRR                         0x26
+#define GRR_QMU                                (1 << 1)
+#define GRR_GSR                                (1 << 0)
+
+#define KS_WFCR                                0x2A
+#define WFCR_MPRXE                     (1 << 7)
+#define WFCR_WF3E                      (1 << 3)
+#define WFCR_WF2E                      (1 << 2)
+#define WFCR_WF1E                      (1 << 1)
+#define WFCR_WF0E                      (1 << 0)
+
+#define KS_WF0CRC0                     0x30
+#define KS_WF0CRC1                     0x32
+#define KS_WF0BM0                      0x34
+#define KS_WF0BM1                      0x36
+#define KS_WF0BM2                      0x38
+#define KS_WF0BM3                      0x3A
+
+#define KS_WF1CRC0                     0x40
+#define KS_WF1CRC1                     0x42
+#define KS_WF1BM0                      0x44
+#define KS_WF1BM1                      0x46
+#define KS_WF1BM2                      0x48
+#define KS_WF1BM3                      0x4A
+
+#define KS_WF2CRC0                     0x50
+#define KS_WF2CRC1                     0x52
+#define KS_WF2BM0                      0x54
+#define KS_WF2BM1                      0x56
+#define KS_WF2BM2                      0x58
+#define KS_WF2BM3                      0x5A
+
+#define KS_WF3CRC0                     0x60
+#define KS_WF3CRC1                     0x62
+#define KS_WF3BM0                      0x64
+#define KS_WF3BM1                      0x66
+#define KS_WF3BM2                      0x68
+#define KS_WF3BM3                      0x6A
+
+#define KS_TXCR                                0x70
+#define TXCR_TCGICMP                   (1 << 8)
+#define TXCR_TCGUDP                    (1 << 7)
+#define TXCR_TCGTCP                    (1 << 6)
+#define TXCR_TCGIP                     (1 << 5)
+#define TXCR_FTXQ                      (1 << 4)
+#define TXCR_TXFCE                     (1 << 3)
+#define TXCR_TXPE                      (1 << 2)
+#define TXCR_TXCRC                     (1 << 1)
+#define TXCR_TXE                       (1 << 0)
+
+#define KS_TXSR                                0x72
+#define TXSR_TXLC                      (1 << 13)
+#define TXSR_TXMC                      (1 << 12)
+#define TXSR_TXFID_MASK                        (0x3f << 0)
+#define TXSR_TXFID_SHIFT               (0)
+#define TXSR_TXFID_GET(_v)             (((_v) >> 0) & 0x3f)
+
+
+#define KS_RXCR1                       0x74
+#define RXCR1_FRXQ                     (1 << 15)
+#define RXCR1_RXUDPFCC                 (1 << 14)
+#define RXCR1_RXTCPFCC                 (1 << 13)
+#define RXCR1_RXIPFCC                  (1 << 12)
+#define RXCR1_RXPAFMA                  (1 << 11)
+#define RXCR1_RXFCE                    (1 << 10)
+#define RXCR1_RXEFE                    (1 << 9)
+#define RXCR1_RXMAFMA                  (1 << 8)
+#define RXCR1_RXBE                     (1 << 7)
+#define RXCR1_RXME                     (1 << 6)
+#define RXCR1_RXUE                     (1 << 5)
+#define RXCR1_RXAE                     (1 << 4)
+#define RXCR1_RXINVF                   (1 << 1)
+#define RXCR1_RXE                      (1 << 0)
+#define RXCR1_FILTER_MASK              (RXCR1_RXINVF | RXCR1_RXAE | \
+                                        RXCR1_RXMAFMA | RXCR1_RXPAFMA)
+
+#define KS_RXCR2                       0x76
+#define RXCR2_SRDBL_MASK               (0x7 << 5)
+#define RXCR2_SRDBL_SHIFT              (5)
+#define RXCR2_SRDBL_4B                 (0x0 << 5)
+#define RXCR2_SRDBL_8B                 (0x1 << 5)
+#define RXCR2_SRDBL_16B                        (0x2 << 5)
+#define RXCR2_SRDBL_32B                        (0x3 << 5)
+/* #define RXCR2_SRDBL_FRAME           (0x4 << 5) */
+#define RXCR2_IUFFP                    (1 << 4)
+#define RXCR2_RXIUFCEZ                 (1 << 3)
+#define RXCR2_UDPLFE                   (1 << 2)
+#define RXCR2_RXICMPFCC                        (1 << 1)
+#define RXCR2_RXSAF                    (1 << 0)
+
+#define KS_TXMIR                       0x78
+
+#define KS_RXFHSR                      0x7C
+#define RXFSHR_RXFV                    (1 << 15)
+#define RXFSHR_RXICMPFCS               (1 << 13)
+#define RXFSHR_RXIPFCS                 (1 << 12)
+#define RXFSHR_RXTCPFCS                        (1 << 11)
+#define RXFSHR_RXUDPFCS                        (1 << 10)
+#define RXFSHR_RXBF                    (1 << 7)
+#define RXFSHR_RXMF                    (1 << 6)
+#define RXFSHR_RXUF                    (1 << 5)
+#define RXFSHR_RXMR                    (1 << 4)
+#define RXFSHR_RXFT                    (1 << 3)
+#define RXFSHR_RXFTL                   (1 << 2)
+#define RXFSHR_RXRF                    (1 << 1)
+#define RXFSHR_RXCE                    (1 << 0)
+#define        RXFSHR_ERR                      (RXFSHR_RXCE | RXFSHR_RXRF |\
+                                       RXFSHR_RXFTL | RXFSHR_RXMR |\
+                                       RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\
+                                       RXFSHR_RXTCPFCS)
+#define KS_RXFHBCR                     0x7E
+#define RXFHBCR_CNT_MASK               0x0FFF
+
+#define KS_TXQCR                       0x80
+#define TXQCR_AETFE                    (1 << 2)
+#define TXQCR_TXQMAM                   (1 << 1)
+#define TXQCR_METFE                    (1 << 0)
+
+#define KS_RXQCR                       0x82
+#define RXQCR_RXDTTS                   (1 << 12)
+#define RXQCR_RXDBCTS                  (1 << 11)
+#define RXQCR_RXFCTS                   (1 << 10)
+#define RXQCR_RXIPHTOE                 (1 << 9)
+#define RXQCR_RXDTTE                   (1 << 7)
+#define RXQCR_RXDBCTE                  (1 << 6)
+#define RXQCR_RXFCTE                   (1 << 5)
+#define RXQCR_ADRFE                    (1 << 4)
+#define RXQCR_SDA                      (1 << 3)
+#define RXQCR_RRXEF                    (1 << 0)
+#define RXQCR_CMD_CNTL                 (RXQCR_RXFCTE|RXQCR_ADRFE)
+
+#define KS_TXFDPR                      0x84
+#define TXFDPR_TXFPAI                  (1 << 14)
+#define TXFDPR_TXFP_MASK               (0x7ff << 0)
+#define TXFDPR_TXFP_SHIFT              (0)
+
+#define KS_RXFDPR                      0x86
+#define RXFDPR_RXFPAI                  (1 << 14)
+
+#define KS_RXDTTR                      0x8C
+#define KS_RXDBCTR                     0x8E
+
+#define KS_IER                         0x90
+#define KS_ISR                         0x92
+#define IRQ_LCI                                (1 << 15)
+#define IRQ_TXI                                (1 << 14)
+#define IRQ_RXI                                (1 << 13)
+#define IRQ_RXOI                       (1 << 11)
+#define IRQ_TXPSI                      (1 << 9)
+#define IRQ_RXPSI                      (1 << 8)
+#define IRQ_TXSAI                      (1 << 6)
+#define IRQ_RXWFDI                     (1 << 5)
+#define IRQ_RXMPDI                     (1 << 4)
+#define IRQ_LDI                                (1 << 3)
+#define IRQ_EDI                                (1 << 2)
+#define IRQ_SPIBEI                     (1 << 1)
+#define IRQ_DEDI                       (1 << 0)
+
+#define KS_RXFCTR                      0x9C
+#define RXFCTR_THRESHOLD_MASK          0x00FF
+
+#define KS_RXFC                                0x9D
+#define RXFCTR_RXFC_MASK               (0xff << 8)
+#define RXFCTR_RXFC_SHIFT              (8)
+#define RXFCTR_RXFC_GET(_v)            (((_v) >> 8) & 0xff)
+#define RXFCTR_RXFCT_MASK              (0xff << 0)
+#define RXFCTR_RXFCT_SHIFT             (0)
+
+#define KS_TXNTFSR                     0x9E
+
+#define KS_MAHTR0                      0xA0
+#define KS_MAHTR1                      0xA2
+#define KS_MAHTR2                      0xA4
+#define KS_MAHTR3                      0xA6
+
+#define KS_FCLWR                       0xB0
+#define KS_FCHWR                       0xB2
+#define KS_FCOWR                       0xB4
+
+#define KS_CIDER                       0xC0
+#define CIDER_ID                       0x8870
+#define CIDER_REV_MASK                 (0x7 << 1)
+#define CIDER_REV_SHIFT                        (1)
+#define CIDER_REV_GET(_v)              (((_v) >> 1) & 0x7)
+
+#define KS_CGCR                                0xC6
+#define KS_IACR                                0xC8
+#define IACR_RDEN                      (1 << 12)
+#define IACR_TSEL_MASK                 (0x3 << 10)
+#define IACR_TSEL_SHIFT                        (10)
+#define IACR_TSEL_MIB                  (0x3 << 10)
+#define IACR_ADDR_MASK                 (0x1f << 0)
+#define IACR_ADDR_SHIFT                        (0)
+
+#define KS_IADLR                       0xD0
+#define KS_IAHDR                       0xD2
+
+#define KS_PMECR                       0xD4
+#define PMECR_PME_DELAY                        (1 << 14)
+#define PMECR_PME_POL                  (1 << 12)
+#define PMECR_WOL_WAKEUP               (1 << 11)
+#define PMECR_WOL_MAGICPKT             (1 << 10)
+#define PMECR_WOL_LINKUP               (1 << 9)
+#define PMECR_WOL_ENERGY               (1 << 8)
+#define PMECR_AUTO_WAKE_EN             (1 << 7)
+#define PMECR_WAKEUP_NORMAL            (1 << 6)
+#define PMECR_WKEVT_MASK               (0xf << 2)
+#define PMECR_WKEVT_SHIFT              (2)
+#define PMECR_WKEVT_GET(_v)            (((_v) >> 2) & 0xf)
+#define PMECR_WKEVT_ENERGY             (0x1 << 2)
+#define PMECR_WKEVT_LINK               (0x2 << 2)
+#define PMECR_WKEVT_MAGICPKT           (0x4 << 2)
+#define PMECR_WKEVT_FRAME              (0x8 << 2)
+#define PMECR_PM_MASK                  (0x3 << 0)
+#define PMECR_PM_SHIFT                 (0)
+#define PMECR_PM_NORMAL                        (0x0 << 0)
+#define PMECR_PM_ENERGY                        (0x1 << 0)
+#define PMECR_PM_SOFTDOWN              (0x2 << 0)
+#define PMECR_PM_POWERSAVE             (0x3 << 0)
+
+/* Standard MII PHY data */
+#define KS_P1MBCR                      0xE4
+#define P1MBCR_FORCE_FDX               (1 << 8)
+
+#define KS_P1MBSR                      0xE6
+#define P1MBSR_AN_COMPLETE             (1 << 5)
+#define P1MBSR_AN_CAPABLE              (1 << 3)
+#define P1MBSR_LINK_UP                 (1 << 2)
+
+#define KS_PHY1ILR                     0xE8
+#define KS_PHY1IHR                     0xEA
+#define KS_P1ANAR                      0xEC
+#define KS_P1ANLPR                     0xEE
+
+#define KS_P1SCLMD                     0xF4
+#define P1SCLMD_LEDOFF                 (1 << 15)
+#define P1SCLMD_TXIDS                  (1 << 14)
+#define P1SCLMD_RESTARTAN              (1 << 13)
+#define P1SCLMD_DISAUTOMDIX            (1 << 10)
+#define P1SCLMD_FORCEMDIX              (1 << 9)
+#define P1SCLMD_AUTONEGEN              (1 << 7)
+#define P1SCLMD_FORCE100               (1 << 6)
+#define P1SCLMD_FORCEFDX               (1 << 5)
+#define P1SCLMD_ADV_FLOW               (1 << 4)
+#define P1SCLMD_ADV_100BT_FDX          (1 << 3)
+#define P1SCLMD_ADV_100BT_HDX          (1 << 2)
+#define P1SCLMD_ADV_10BT_FDX           (1 << 1)
+#define P1SCLMD_ADV_10BT_HDX           (1 << 0)
+
+#define KS_P1CR                                0xF6
+#define P1CR_HP_MDIX                   (1 << 15)
+#define P1CR_REV_POL                   (1 << 13)
+#define P1CR_OP_100M                   (1 << 10)
+#define P1CR_OP_FDX                    (1 << 9)
+#define P1CR_OP_MDI                    (1 << 7)
+#define P1CR_AN_DONE                   (1 << 6)
+#define P1CR_LINK_GOOD                 (1 << 5)
+#define P1CR_PNTR_FLOW                 (1 << 4)
+#define P1CR_PNTR_100BT_FDX            (1 << 3)
+#define P1CR_PNTR_100BT_HDX            (1 << 2)
+#define P1CR_PNTR_10BT_FDX             (1 << 1)
+#define P1CR_PNTR_10BT_HDX             (1 << 0)
+
+/* TX Frame control */
+
+#define TXFR_TXIC                      (1 << 15)
+#define TXFR_TXFID_MASK                        (0x3f << 0)
+#define TXFR_TXFID_SHIFT               (0)
+
+#define KS_P1SR                                0xF8
+#define P1SR_HP_MDIX                   (1 << 15)
+#define P1SR_REV_POL                   (1 << 13)
+#define P1SR_OP_100M                   (1 << 10)
+#define P1SR_OP_FDX                    (1 << 9)
+#define P1SR_OP_MDI                    (1 << 7)
+#define P1SR_AN_DONE                   (1 << 6)
+#define P1SR_LINK_GOOD                 (1 << 5)
+#define P1SR_PNTR_FLOW                 (1 << 4)
+#define P1SR_PNTR_100BT_FDX            (1 << 3)
+#define P1SR_PNTR_100BT_HDX            (1 << 2)
+#define P1SR_PNTR_10BT_FDX             (1 << 1)
+#define P1SR_PNTR_10BT_HDX             (1 << 0)
+
+#define        ENUM_BUS_NONE                   0
+#define        ENUM_BUS_8BIT                   1
+#define        ENUM_BUS_16BIT                  2
+#define        ENUM_BUS_32BIT                  3
+
+#define MAX_MCAST_LST                  32
+#define HW_MCAST_SIZE                  8
+#define MAC_ADDR_LEN                   6
+
+/**
+ * union ks_tx_hdr - tx header data
+ * @txb: The header as bytes
+ * @txw: The header as 16bit, little-endian words
+ *
+ * A dual representation of the tx header data to allow
+ * access to individual bytes, and to allow 16bit accesses
+ * with 16bit alignment.
+ */
+union ks_tx_hdr {
+       u8      txb[4];
+       __le16  txw[2];
+};
+
+/**
+ * struct ks_net - KS8851 driver private data
+ * @net_device         : The network device we're bound to
+ * @hw_addr    : start address of data register.
+ * @hw_addr_cmd        : start address of command register.
+ * @txh        : temporaly buffer to save status/length.
+ * @lock       : Lock to ensure that the device is not accessed when busy.
+ * @pdev       : Pointer to platform device.
+ * @mii                : The MII state information for the mii calls.
+ * @frame_head_info    : frame header information for multi-pkt rx.
+ * @statelock  : Lock on this structure for tx list.
+ * @msg_enable : The message flags controlling driver output (see ethtool).
+ * @frame_cnt          : number of frames received.
+ * @bus_width          : i/o bus width.
+ * @irq        : irq number assigned to this device.
+ * @rc_rxqcr   : Cached copy of KS_RXQCR.
+ * @rc_txcr    : Cached copy of KS_TXCR.
+ * @rc_ier     : Cached copy of KS_IER.
+ * @sharedbus          : Multipex(addr and data bus) mode indicator.
+ * @cmd_reg_cache      : command register cached.
+ * @cmd_reg_cache_int  : command register cached. Used in the irq handler.
+ * @promiscuous        : promiscuous mode indicator.
+ * @all_mcast          : mutlicast indicator.
+ * @mcast_lst_size     : size of multicast list.
+ * @mcast_lst          : multicast list.
+ * @mcast_bits         : multicast enabed.
+ * @mac_addr                   : MAC address assigned to this device.
+ * @fid                : frame id.
+ * @extra_byte         : number of extra byte prepended rx pkt.
+ * @enabled                    : indicator this device works.
+ *
+ * The @lock ensures that the chip is protected when certain operations are
+ * in progress. When the read or write packet transfer is in progress, most
+ * of the chip registers are not accessible until the transfer is finished and
+ * the DMA has been de-asserted.
+ *
+ * The @statelock is used to protect information in the structure which may
+ * need to be accessed via several sources, such as the network driver layer
+ * or one of the work queues.
+ *
+ */
+
+/* Receive multiplex framer header info */
+struct type_frame_head {
+       u16     sts;         /* Frame status */
+       u16     len;         /* Byte count */
+};
+
+struct ks_net {
+       struct net_device       *netdev;
+       void __iomem            *hw_addr;
+       void __iomem            *hw_addr_cmd;
+       union ks_tx_hdr         txh ____cacheline_aligned;
+       struct mutex            lock; /* spinlock to be interrupt safe */
+       struct platform_device *pdev;
+       struct mii_if_info      mii;
+       struct type_frame_head  *frame_head_info;
+       spinlock_t              statelock;
+       u32                     msg_enable;
+       u32                     frame_cnt;
+       int                     bus_width;
+       int                     irq;
+
+       u16                     rc_rxqcr;
+       u16                     rc_txcr;
+       u16                     rc_ier;
+       u16                     sharedbus;
+       u16                     cmd_reg_cache;
+       u16                     cmd_reg_cache_int;
+       u16                     promiscuous;
+       u16                     all_mcast;
+       u16                     mcast_lst_size;
+       u8                      mcast_lst[MAX_MCAST_LST][MAC_ADDR_LEN];
+       u8                      mcast_bits[HW_MCAST_SIZE];
+       u8                      mac_addr[6];
+       u8                      fid;
+       u8                      extra_byte;
+       u8                      enabled;
+};
+
+static int msg_enable;
+
+#define ks_info(_ks, _msg...) dev_info(&(_ks)->pdev->dev, _msg)
+#define ks_warn(_ks, _msg...) dev_warn(&(_ks)->pdev->dev, _msg)
+#define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->pdev->dev, _msg)
+#define ks_err(_ks, _msg...) dev_err(&(_ks)->pdev->dev, _msg)
+
+#define BE3             0x8000      /* Byte Enable 3 */
+#define BE2             0x4000      /* Byte Enable 2 */
+#define BE1             0x2000      /* Byte Enable 1 */
+#define BE0             0x1000      /* Byte Enable 0 */
+
+/**
+ * register read/write calls.
+ *
+ * All these calls issue transactions to access the chip's registers. They
+ * all require that the necessary lock is held to prevent accesses when the
+ * chip is busy transfering packet data (RX/TX FIFO accesses).
+ */
+
+/**
+ * ks_rdreg8 - read 8 bit register from device
+ * @ks   : The chip information
+ * @offset: The register address
+ *
+ * Read a 8bit register from the chip, returning the result
+ */
+static u8 ks_rdreg8(struct ks_net *ks, int offset)
+{
+       u16 data;
+       u8 shift_bit = offset & 0x03;
+       u8 shift_data = (offset & 1) << 3;
+       ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit);
+       iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+       data  = ioread16(ks->hw_addr);
+       return (u8)(data >> shift_data);
+}
+
+/**
+ * ks_rdreg16 - read 16 bit register from device
+ * @ks   : The chip information
+ * @offset: The register address
+ *
+ * Read a 16bit register from the chip, returning the result
+ */
+
+static u16 ks_rdreg16(struct ks_net *ks, int offset)
+{
+       ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
+       iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+       return ioread16(ks->hw_addr);
+}
+
+/**
+ * ks_wrreg8 - write 8bit register value to chip
+ * @ks: The chip information
+ * @offset: The register address
+ * @value: The value to write
+ *
+ */
+static void ks_wrreg8(struct ks_net *ks, int offset, u8 value)
+{
+       u8  shift_bit = (offset & 0x03);
+       u16 value_write = (u16)(value << ((offset & 1) << 3));
+       ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit);
+       iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+       iowrite16(value_write, ks->hw_addr);
+}
+
+/**
+ * ks_wrreg16 - write 16bit register value to chip
+ * @ks: The chip information
+ * @offset: The register address
+ * @value: The value to write
+ *
+ */
+
+static void ks_wrreg16(struct ks_net *ks, int offset, u16 value)
+{
+       ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
+       iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+       iowrite16(value, ks->hw_addr);
+}
+
+/**
+ * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode enabled.
+ * @ks: The chip state
+ * @wptr: buffer address to save data
+ * @len: length in byte to read
+ *
+ */
+static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len)
+{
+       len >>= 1;
+       while (len--)
+               *wptr++ = (u16)ioread16(ks->hw_addr);
+}
+
+/**
+ * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled.
+ * @ks: The chip information
+ * @wptr: buffer address
+ * @len: length in byte to write
+ *
+ */
+static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
+{
+       len >>= 1;
+       while (len--)
+               iowrite16(*wptr++, ks->hw_addr);
+}
+
+/**
+ * ks_tx_fifo_space - return the available hardware buffer size.
+ * @ks: The chip information
+ *
+ */
+static inline u16 ks_tx_fifo_space(struct ks_net *ks)
+{
+       return ks_rdreg16(ks, KS_TXMIR) & 0x1fff;
+}
+
+/**
+ * ks_save_cmd_reg - save the command register from the cache.
+ * @ks: The chip information
+ *
+ */
+static inline void ks_save_cmd_reg(struct ks_net *ks)
+{
+       /*ks8851 MLL has a bug to read back the command register.
+       * So rely on software to save the content of command register.
+       */
+       ks->cmd_reg_cache_int = ks->cmd_reg_cache;
+}
+
+/**
+ * ks_restore_cmd_reg - restore the command register from the cache and
+ *     write to hardware register.
+ * @ks: The chip information
+ *
+ */
+static inline void ks_restore_cmd_reg(struct ks_net *ks)
+{
+       ks->cmd_reg_cache = ks->cmd_reg_cache_int;
+       iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+}
+
+/**
+ * ks_set_powermode - set power mode of the device
+ * @ks: The chip information
+ * @pwrmode: The power mode value to write to KS_PMECR.
+ *
+ * Change the power mode of the chip.
+ */
+static void ks_set_powermode(struct ks_net *ks, unsigned pwrmode)
+{
+       unsigned pmecr;
+
+       if (netif_msg_hw(ks))
+               ks_dbg(ks, "setting power mode %d\n", pwrmode);
+
+       ks_rdreg16(ks, KS_GRR);
+       pmecr = ks_rdreg16(ks, KS_PMECR);
+       pmecr &= ~PMECR_PM_MASK;
+       pmecr |= pwrmode;
+
+       ks_wrreg16(ks, KS_PMECR, pmecr);
+}
+
+/**
+ * ks_read_config - read chip configuration of bus width.
+ * @ks: The chip information
+ *
+ */
+static void ks_read_config(struct ks_net *ks)
+{
+       u16 reg_data = 0;
+
+       /* Regardless of bus width, 8 bit read should always work.*/
+       reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF;
+       reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8;
+
+       /* addr/data bus are multiplexed */
+       ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;
+
+       /* There are garbage data when reading data from QMU,
+       depending on bus-width.
+       */
+
+       if (reg_data & CCR_8BIT) {
+               ks->bus_width = ENUM_BUS_8BIT;
+               ks->extra_byte = 1;
+       } else if (reg_data & CCR_16BIT) {
+               ks->bus_width = ENUM_BUS_16BIT;
+               ks->extra_byte = 2;
+       } else {
+               ks->bus_width = ENUM_BUS_32BIT;
+               ks->extra_byte = 4;
+       }
+}
+
+/**
+ * ks_soft_reset - issue one of the soft reset to the device
+ * @ks: The device state.
+ * @op: The bit(s) to set in the GRR
+ *
+ * Issue the relevant soft-reset command to the device's GRR register
+ * specified by @op.
+ *
+ * Note, the delays are in there as a caution to ensure that the reset
+ * has time to take effect and then complete. Since the datasheet does
+ * not currently specify the exact sequence, we have chosen something
+ * that seems to work with our device.
+ */
+static void ks_soft_reset(struct ks_net *ks, unsigned op)
+{
+       /* Disable interrupt first */
+       ks_wrreg16(ks, KS_IER, 0x0000);
+       ks_wrreg16(ks, KS_GRR, op);
+       mdelay(10);     /* wait a short time to effect reset */
+       ks_wrreg16(ks, KS_GRR, 0);
+       mdelay(1);      /* wait for condition to clear */
+}
+
+
+/**
+ * ks_read_qmu - read 1 pkt data from the QMU.
+ * @ks: The chip information
+ * @buf: buffer address to save 1 pkt
+ * @len: Pkt length
+ * Here is the sequence to read 1 pkt:
+ *     1. set sudo DMA mode
+ *     2. read prepend data
+ *     3. read pkt data
+ *     4. reset sudo DMA Mode
+ */
+static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len)
+{
+       u32 r =  ks->extra_byte & 0x1 ;
+       u32 w = ks->extra_byte - r;
+
+       /* 1. set sudo DMA mode */
+       ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
+       ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+
+       /* 2. read prepend data */
+       /**
+        * read 4 + extra bytes and discard them.
+        * extra bytes for dummy, 2 for status, 2 for len
+        */
+
+       /* use likely(r) for 8 bit access for performance */
+       if (unlikely(r))
+               ioread8(ks->hw_addr);
+       ks_inblk(ks, buf, w + 2 + 2);
+
+       /* 3. read pkt data */
+       ks_inblk(ks, buf, ALIGN(len, 4));
+
+       /* 4. reset sudo DMA Mode */
+       ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
+}
+
+/**
+ * ks_rcv - read multiple pkts data from the QMU.
+ * @ks: The chip information
+ * @netdev: The network device being opened.
+ *
+ * Read all of header information before reading pkt content.
+ * It is not allowed only port of pkts in QMU after issuing
+ * interrupt ack.
+ */
+static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
+{
+       u32     i;
+       struct type_frame_head *frame_hdr = ks->frame_head_info;
+       struct sk_buff *skb;
+
+       ks->frame_cnt = ks_rdreg16(ks, KS_RXFCTR) >> 8;
+
+       /* read all header information */
+       for (i = 0; i < ks->frame_cnt; i++) {
+               /* Checking Received packet status */
+               frame_hdr->sts = ks_rdreg16(ks, KS_RXFHSR);
+               /* Get packet len from hardware */
+               frame_hdr->len = ks_rdreg16(ks, KS_RXFHBCR);
+               frame_hdr++;
+       }
+
+       frame_hdr = ks->frame_head_info;
+       while (ks->frame_cnt--) {
+               skb = dev_alloc_skb(frame_hdr->len + 16);
+               if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) &&
+                       (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
+                       skb_reserve(skb, 2);
+                       /* read data block including CRC 4 bytes */
+                       ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
+                       skb_put(skb, frame_hdr->len);
+                       skb->dev = netdev;
+                       skb->protocol = eth_type_trans(skb, netdev);
+                       netif_rx(skb);
+               } else {
+                       printk(KERN_ERR "%s: err:skb alloc\n", __func__);
+                       ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
+                       if (skb)
+                               dev_kfree_skb_irq(skb);
+               }
+               frame_hdr++;
+       }
+}
+
+/**
+ * ks_update_link_status - link status update.
+ * @netdev: The network device being opened.
+ * @ks: The chip information
+ *
+ */
+
+static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks)
+{
+       /* check the status of the link */
+       u32 link_up_status;
+       if (ks_rdreg16(ks, KS_P1SR) & P1SR_LINK_GOOD) {
+               netif_carrier_on(netdev);
+               link_up_status = true;
+       } else {
+               netif_carrier_off(netdev);
+               link_up_status = false;
+       }
+       if (netif_msg_link(ks))
+               ks_dbg(ks, "%s: %s\n",
+                       __func__, link_up_status ? "UP" : "DOWN");
+}
+
+/**
+ * ks_irq - device interrupt handler
+ * @irq: Interrupt number passed from the IRQ hnalder.
+ * @pw: The private word passed to register_irq(), our struct ks_net.
+ *
+ * This is the handler invoked to find out what happened
+ *
+ * Read the interrupt status, work out what needs to be done and then clear
+ * any of the interrupts that are not needed.
+ */
+
+static irqreturn_t ks_irq(int irq, void *pw)
+{
+       struct ks_net *ks = pw;
+       struct net_device *netdev = ks->netdev;
+       u16 status;
+
+       /*this should be the first in IRQ handler */
+       ks_save_cmd_reg(ks);
+
+       status = ks_rdreg16(ks, KS_ISR);
+       if (unlikely(!status)) {
+               ks_restore_cmd_reg(ks);
+               return IRQ_NONE;
+       }
+
+       ks_wrreg16(ks, KS_ISR, status);
+
+       if (likely(status & IRQ_RXI))
+               ks_rcv(ks, netdev);
+
+       if (unlikely(status & IRQ_LCI))
+               ks_update_link_status(netdev, ks);
+
+       if (unlikely(status & IRQ_TXI))
+               netif_wake_queue(netdev);
+
+       if (unlikely(status & IRQ_LDI)) {
+
+               u16 pmecr = ks_rdreg16(ks, KS_PMECR);
+               pmecr &= ~PMECR_WKEVT_MASK;
+               ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
+       }
+
+       /* this should be the last in IRQ handler*/
+       ks_restore_cmd_reg(ks);
+       return IRQ_HANDLED;
+}
+
+
+/**
+ * ks_net_open - open network device
+ * @netdev: The network device being opened.
+ *
+ * Called when the network device is marked active, such as a user executing
+ * 'ifconfig up' on the device.
+ */
+static int ks_net_open(struct net_device *netdev)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       int err;
+
+#define        KS_INT_FLAGS    (IRQF_DISABLED|IRQF_TRIGGER_LOW)
+       /* lock the card, even if we may not actually do anything
+        * else at the moment.
+        */
+
+       if (netif_msg_ifup(ks))
+               ks_dbg(ks, "%s - entry\n", __func__);
+
+       /* reset the HW */
+       err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
+
+       if (err) {
+               printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
+                       ks->irq, err);
+               return err;
+       }
+
+       if (netif_msg_ifup(ks))
+               ks_dbg(ks, "network device %s up\n", netdev->name);
+
+       return 0;
+}
+
+/**
+ * ks_net_stop - close network device
+ * @netdev: The device being closed.
+ *
+ * Called to close down a network device which has been active. Cancell any
+ * work, shutdown the RX and TX process and then place the chip into a low
+ * power state whilst it is not being used.
+ */
+static int ks_net_stop(struct net_device *netdev)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+
+       if (netif_msg_ifdown(ks))
+               ks_info(ks, "%s: shutting down\n", netdev->name);
+
+       netif_stop_queue(netdev);
+
+       kfree(ks->frame_head_info);
+
+       mutex_lock(&ks->lock);
+
+       /* turn off the IRQs and ack any outstanding */
+       ks_wrreg16(ks, KS_IER, 0x0000);
+       ks_wrreg16(ks, KS_ISR, 0xffff);
+
+       /* shutdown RX process */
+       ks_wrreg16(ks, KS_RXCR1, 0x0000);
+
+       /* shutdown TX process */
+       ks_wrreg16(ks, KS_TXCR, 0x0000);
+
+       /* set powermode to soft power down to save power */
+       ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
+       free_irq(ks->irq, netdev);
+       mutex_unlock(&ks->lock);
+       return 0;
+}
+
+
+/**
+ * ks_write_qmu - write 1 pkt data to the QMU.
+ * @ks: The chip information
+ * @pdata: buffer address to save 1 pkt
+ * @len: Pkt length in byte
+ * Here is the sequence to write 1 pkt:
+ *     1. set sudo DMA mode
+ *     2. write status/length
+ *     3. write pkt data
+ *     4. reset sudo DMA Mode
+ *     5. reset sudo DMA mode
+ *     6. Wait until pkt is out
+ */
+static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
+{
+       unsigned fid = ks->fid;
+
+       fid = ks->fid;
+       ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;
+
+       /* reduce the tx interrupt occurrances. */
+       if (!fid)
+               fid |= TXFR_TXIC;       /* irq on completion */
+
+       /* start header at txb[0] to align txw entries */
+       ks->txh.txw[0] = cpu_to_le16(fid);
+       ks->txh.txw[1] = cpu_to_le16(len);
+
+       /* 1. set sudo-DMA mode */
+       ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+       /* 2. write status/lenth info */
+       ks_outblk(ks, ks->txh.txw, 4);
+       /* 3. write pkt data */
+       ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4));
+       /* 4. reset sudo-DMA mode */
+       ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
+       /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
+       ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
+       /* 6. wait until TXQCR_METFE is auto-cleared */
+       while (ks_rdreg16(ks, KS_TXQCR) & TXQCR_METFE)
+               ;
+}
+
+static void ks_disable_int(struct ks_net *ks)
+{
+       ks_wrreg16(ks, KS_IER, 0x0000);
+}  /* ks_disable_int */
+
+static void ks_enable_int(struct ks_net *ks)
+{
+       ks_wrreg16(ks, KS_IER, ks->rc_ier);
+}  /* ks_enable_int */
+
+/**
+ * ks_start_xmit - transmit packet
+ * @skb                : The buffer to transmit
+ * @netdev     : The device used to transmit the packet.
+ *
+ * Called by the network layer to transmit the @skb.
+ * spin_lock_irqsave is required because tx and rx should be mutual exclusive.
+ * So while tx is in-progress, prevent IRQ interrupt from happenning.
+ */
+static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+       int retv = NETDEV_TX_OK;
+       struct ks_net *ks = netdev_priv(netdev);
+
+       disable_irq(netdev->irq);
+       ks_disable_int(ks);
+       spin_lock(&ks->statelock);
+
+       /* Extra space are required:
+       *  4 byte for alignment, 4 for status/length, 4 for CRC
+       */
+
+       if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) {
+               ks_write_qmu(ks, skb->data, skb->len);
+               dev_kfree_skb(skb);
+       } else
+               retv = NETDEV_TX_BUSY;
+       spin_unlock(&ks->statelock);
+       ks_enable_int(ks);
+       enable_irq(netdev->irq);
+       return retv;
+}
+
+/**
+ * ks_start_rx - ready to serve pkts
+ * @ks         : The chip information
+ *
+ */
+static void ks_start_rx(struct ks_net *ks)
+{
+       u16 cntl;
+
+       /* Enables QMU Receive (RXCR1). */
+       cntl = ks_rdreg16(ks, KS_RXCR1);
+       cntl |= RXCR1_RXE ;
+       ks_wrreg16(ks, KS_RXCR1, cntl);
+}  /* ks_start_rx */
+
+/**
+ * ks_stop_rx - stop to serve pkts
+ * @ks         : The chip information
+ *
+ */
+static void ks_stop_rx(struct ks_net *ks)
+{
+       u16 cntl;
+
+       /* Disables QMU Receive (RXCR1). */
+       cntl = ks_rdreg16(ks, KS_RXCR1);
+       cntl &= ~RXCR1_RXE ;
+       ks_wrreg16(ks, KS_RXCR1, cntl);
+
+}  /* ks_stop_rx */
+
+static unsigned long const ethernet_polynomial = 0x04c11db7U;
+
+static unsigned long ether_gen_crc(int length, u8 *data)
+{
+       long crc = -1;
+       while (--length >= 0) {
+               u8 current_octet = *data++;
+               int bit;
+
+               for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+                       crc = (crc << 1) ^
+                               ((crc < 0) ^ (current_octet & 1) ?
+                       ethernet_polynomial : 0);
+               }
+       }
+       return (unsigned long)crc;
+}  /* ether_gen_crc */
+
+/**
+* ks_set_grpaddr - set multicast information
+* @ks : The chip information
+*/
+
+static void ks_set_grpaddr(struct ks_net *ks)
+{
+       u8      i;
+       u32     index, position, value;
+
+       memset(ks->mcast_bits, 0, sizeof(u8) * HW_MCAST_SIZE);
+
+       for (i = 0; i < ks->mcast_lst_size; i++) {
+               position = (ether_gen_crc(6, ks->mcast_lst[i]) >> 26) & 0x3f;
+               index = position >> 3;
+               value = 1 << (position & 7);
+               ks->mcast_bits[index] |= (u8)value;
+       }
+
+       for (i  = 0; i < HW_MCAST_SIZE; i++) {
+               if (i & 1) {
+                       ks_wrreg16(ks, (u16)((KS_MAHTR0 + i) & ~1),
+                               (ks->mcast_bits[i] << 8) |
+                               ks->mcast_bits[i - 1]);
+               }
+       }
+}  /* ks_set_grpaddr */
+
+/*
+* ks_clear_mcast - clear multicast information
+*
+* @ks : The chip information
+* This routine removes all mcast addresses set in the hardware.
+*/
+
+static void ks_clear_mcast(struct ks_net *ks)
+{
+       u16     i, mcast_size;
+       for (i = 0; i < HW_MCAST_SIZE; i++)
+               ks->mcast_bits[i] = 0;
+
+       mcast_size = HW_MCAST_SIZE >> 2;
+       for (i = 0; i < mcast_size; i++)
+               ks_wrreg16(ks, KS_MAHTR0 + (2*i), 0);
+}
+
+static void ks_set_promis(struct ks_net *ks, u16 promiscuous_mode)
+{
+       u16             cntl;
+       ks->promiscuous = promiscuous_mode;
+       ks_stop_rx(ks);  /* Stop receiving for reconfiguration */
+       cntl = ks_rdreg16(ks, KS_RXCR1);
+
+       cntl &= ~RXCR1_FILTER_MASK;
+       if (promiscuous_mode)
+               /* Enable Promiscuous mode */
+               cntl |= RXCR1_RXAE | RXCR1_RXINVF;
+       else
+               /* Disable Promiscuous mode (default normal mode) */
+               cntl |= RXCR1_RXPAFMA;
+
+       ks_wrreg16(ks, KS_RXCR1, cntl);
+
+       if (ks->enabled)
+               ks_start_rx(ks);
+
+}  /* ks_set_promis */
+
+static void ks_set_mcast(struct ks_net *ks, u16 mcast)
+{
+       u16     cntl;
+
+       ks->all_mcast = mcast;
+       ks_stop_rx(ks);  /* Stop receiving for reconfiguration */
+       cntl = ks_rdreg16(ks, KS_RXCR1);
+       cntl &= ~RXCR1_FILTER_MASK;
+       if (mcast)
+               /* Enable "Perfect with Multicast address passed mode" */
+               cntl |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA);
+       else
+               /**
+                * Disable "Perfect with Multicast address passed
+                * mode" (normal mode).
+                */
+               cntl |= RXCR1_RXPAFMA;
+
+       ks_wrreg16(ks, KS_RXCR1, cntl);
+
+       if (ks->enabled)
+               ks_start_rx(ks);
+}  /* ks_set_mcast */
+
+static void ks_set_rx_mode(struct net_device *netdev)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       struct dev_mc_list *ptr;
+
+       /* Turn on/off promiscuous mode. */
+       if ((netdev->flags & IFF_PROMISC) == IFF_PROMISC)
+               ks_set_promis(ks,
+                       (u16)((netdev->flags & IFF_PROMISC) == IFF_PROMISC));
+       /* Turn on/off all mcast mode. */
+       else if ((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI)
+               ks_set_mcast(ks,
+                       (u16)((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI));
+       else
+               ks_set_promis(ks, false);
+
+       if ((netdev->flags & IFF_MULTICAST) && netdev->mc_count) {
+               if (netdev->mc_count <= MAX_MCAST_LST) {
+                       int i = 0;
+                       for (ptr = netdev->mc_list; ptr; ptr = ptr->next) {
+                               if (!(*ptr->dmi_addr & 1))
+                                       continue;
+                               if (i >= MAX_MCAST_LST)
+                                       break;
+                               memcpy(ks->mcast_lst[i++], ptr->dmi_addr,
+                               MAC_ADDR_LEN);
+                       }
+                       ks->mcast_lst_size = (u8)i;
+                       ks_set_grpaddr(ks);
+               } else {
+                       /**
+                        * List too big to support so
+                        * turn on all mcast mode.
+                        */
+                       ks->mcast_lst_size = MAX_MCAST_LST;
+                       ks_set_mcast(ks, true);
+               }
+       } else {
+               ks->mcast_lst_size = 0;
+               ks_clear_mcast(ks);
+       }
+} /* ks_set_rx_mode */
+
+static void ks_set_mac(struct ks_net *ks, u8 *data)
+{
+       u16 *pw = (u16 *)data;
+       u16 w, u;
+
+       ks_stop_rx(ks);  /* Stop receiving for reconfiguration */
+
+       u = *pw++;
+       w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
+       ks_wrreg16(ks, KS_MARH, w);
+
+       u = *pw++;
+       w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
+       ks_wrreg16(ks, KS_MARM, w);
+
+       u = *pw;
+       w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
+       ks_wrreg16(ks, KS_MARL, w);
+
+       memcpy(ks->mac_addr, data, 6);
+
+       if (ks->enabled)
+               ks_start_rx(ks);
+}
+
+static int ks_set_mac_address(struct net_device *netdev, void *paddr)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       struct sockaddr *addr = paddr;
+       u8 *da;
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+       da = (u8 *)netdev->dev_addr;
+
+       ks_set_mac(ks, da);
+       return 0;
+}
+
+static int ks_net_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL);
+}
+
+static const struct net_device_ops ks_netdev_ops = {
+       .ndo_open               = ks_net_open,
+       .ndo_stop               = ks_net_stop,
+       .ndo_do_ioctl           = ks_net_ioctl,
+       .ndo_start_xmit         = ks_start_xmit,
+       .ndo_set_mac_address    = ks_set_mac_address,
+       .ndo_set_rx_mode        = ks_set_rx_mode,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
+/* ethtool support */
+
+static void ks_get_drvinfo(struct net_device *netdev,
+                              struct ethtool_drvinfo *di)
+{
+       strlcpy(di->driver, DRV_NAME, sizeof(di->driver));
+       strlcpy(di->version, "1.00", sizeof(di->version));
+       strlcpy(di->bus_info, dev_name(netdev->dev.parent),
+               sizeof(di->bus_info));
+}
+
+static u32 ks_get_msglevel(struct net_device *netdev)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       return ks->msg_enable;
+}
+
+static void ks_set_msglevel(struct net_device *netdev, u32 to)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       ks->msg_enable = to;
+}
+
+static int ks_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       return mii_ethtool_gset(&ks->mii, cmd);
+}
+
+static int ks_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       return mii_ethtool_sset(&ks->mii, cmd);
+}
+
+static u32 ks_get_link(struct net_device *netdev)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       return mii_link_ok(&ks->mii);
+}
+
+static int ks_nway_reset(struct net_device *netdev)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       return mii_nway_restart(&ks->mii);
+}
+
+static const struct ethtool_ops ks_ethtool_ops = {
+       .get_drvinfo    = ks_get_drvinfo,
+       .get_msglevel   = ks_get_msglevel,
+       .set_msglevel   = ks_set_msglevel,
+       .get_settings   = ks_get_settings,
+       .set_settings   = ks_set_settings,
+       .get_link       = ks_get_link,
+       .nway_reset     = ks_nway_reset,
+};
+
+/* MII interface controls */
+
+/**
+ * ks_phy_reg - convert MII register into a KS8851 register
+ * @reg: MII register number.
+ *
+ * Return the KS8851 register number for the corresponding MII PHY register
+ * if possible. Return zero if the MII register has no direct mapping to the
+ * KS8851 register set.
+ */
+static int ks_phy_reg(int reg)
+{
+       switch (reg) {
+       case MII_BMCR:
+               return KS_P1MBCR;
+       case MII_BMSR:
+               return KS_P1MBSR;
+       case MII_PHYSID1:
+               return KS_PHY1ILR;
+       case MII_PHYSID2:
+               return KS_PHY1IHR;
+       case MII_ADVERTISE:
+               return KS_P1ANAR;
+       case MII_LPA:
+               return KS_P1ANLPR;
+       }
+
+       return 0x0;
+}
+
+/**
+ * ks_phy_read - MII interface PHY register read.
+ * @netdev: The network device the PHY is on.
+ * @phy_addr: Address of PHY (ignored as we only have one)
+ * @reg: The register to read.
+ *
+ * This call reads data from the PHY register specified in @reg. Since the
+ * device does not support all the MII registers, the non-existant values
+ * are always returned as zero.
+ *
+ * We return zero for unsupported registers as the MII code does not check
+ * the value returned for any error status, and simply returns it to the
+ * caller. The mii-tool that the driver was tested with takes any -ve error
+ * as real PHY capabilities, thus displaying incorrect data to the user.
+ */
+static int ks_phy_read(struct net_device *netdev, int phy_addr, int reg)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       int ksreg;
+       int result;
+
+       ksreg = ks_phy_reg(reg);
+       if (!ksreg)
+               return 0x0;     /* no error return allowed, so use zero */
+
+       mutex_lock(&ks->lock);
+       result = ks_rdreg16(ks, ksreg);
+       mutex_unlock(&ks->lock);
+
+       return result;
+}
+
+static void ks_phy_write(struct net_device *netdev,
+                            int phy, int reg, int value)
+{
+       struct ks_net *ks = netdev_priv(netdev);
+       int ksreg;
+
+       ksreg = ks_phy_reg(reg);
+       if (ksreg) {
+               mutex_lock(&ks->lock);
+               ks_wrreg16(ks, ksreg, value);
+               mutex_unlock(&ks->lock);
+       }
+}
+
+/**
+ * ks_read_selftest - read the selftest memory info.
+ * @ks: The device state
+ *
+ * Read and check the TX/RX memory selftest information.
+ */
+static int ks_read_selftest(struct ks_net *ks)
+{
+       unsigned both_done = MBIR_TXMBF | MBIR_RXMBF;
+       int ret = 0;
+       unsigned rd;
+
+       rd = ks_rdreg16(ks, KS_MBIR);
+
+       if ((rd & both_done) != both_done) {
+               ks_warn(ks, "Memory selftest not finished\n");
+               return 0;
+       }
+
+       if (rd & MBIR_TXMBFA) {
+               ks_err(ks, "TX memory selftest fails\n");
+               ret |= 1;
+       }
+
+       if (rd & MBIR_RXMBFA) {
+               ks_err(ks, "RX memory selftest fails\n");
+               ret |= 2;
+       }
+
+       ks_info(ks, "the selftest passes\n");
+       return ret;
+}
+
+static void ks_disable(struct ks_net *ks)
+{
+       u16     w;
+
+       w = ks_rdreg16(ks, KS_TXCR);
+
+       /* Disables QMU Transmit (TXCR). */
+       w  &= ~TXCR_TXE;
+       ks_wrreg16(ks, KS_TXCR, w);
+
+       /* Disables QMU Receive (RXCR1). */
+       w = ks_rdreg16(ks, KS_RXCR1);
+       w &= ~RXCR1_RXE ;
+       ks_wrreg16(ks, KS_RXCR1, w);
+
+       ks->enabled = false;
+
+}  /* ks_disable */
+
+static void ks_setup(struct ks_net *ks)
+{
+       u16     w;
+
+       /**
+        * Configure QMU Transmit
+        */
+
+       /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */
+       ks_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI);
+
+       /* Setup Receive Frame Data Pointer Auto-Increment */
+       ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
+
+       /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */
+       ks_wrreg16(ks, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK);
+
+       /* Setup RxQ Command Control (RXQCR) */
+       ks->rc_rxqcr = RXQCR_CMD_CNTL;
+       ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
+
+       /**
+        * set the force mode to half duplex, default is full duplex
+        *  because if the auto-negotiation fails, most switch uses
+        *  half-duplex.
+        */
+
+       w = ks_rdreg16(ks, KS_P1MBCR);
+       w &= ~P1MBCR_FORCE_FDX;
+       ks_wrreg16(ks, KS_P1MBCR, w);
+
+       w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
+       ks_wrreg16(ks, KS_TXCR, w);
+
+       w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
+
+       if (ks->promiscuous)         /* bPromiscuous */
+               w |= (RXCR1_RXAE | RXCR1_RXINVF);
+       else if (ks->all_mcast) /* Multicast address passed mode */
+               w |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA);
+       else                                   /* Normal mode */
+               w |= RXCR1_RXPAFMA;
+
+       ks_wrreg16(ks, KS_RXCR1, w);
+}  /*ks_setup */
+
+
+static void ks_setup_int(struct ks_net *ks)
+{
+       ks->rc_ier = 0x00;
+       /* Clear the interrupts status of the hardware. */
+       ks_wrreg16(ks, KS_ISR, 0xffff);
+
+       /* Enables the interrupts of the hardware. */
+       ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
+}  /* ks_setup_int */
+
+void ks_enable(struct ks_net *ks)
+{
+       u16 w;
+
+       w = ks_rdreg16(ks, KS_TXCR);
+       /* Enables QMU Transmit (TXCR). */
+       ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
+
+       /*
+        * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
+        * Enable
+        */
+
+       w = ks_rdreg16(ks, KS_RXQCR);
+       ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
+
+       /* Enables QMU Receive (RXCR1). */
+       w = ks_rdreg16(ks, KS_RXCR1);
+       ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
+       ks->enabled = true;
+}  /* ks_enable */
+
+static int ks_hw_init(struct ks_net *ks)
+{
+#define        MHEADER_SIZE    (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
+       ks->promiscuous = 0;
+       ks->all_mcast = 0;
+       ks->mcast_lst_size = 0;
+
+       ks->frame_head_info = (struct type_frame_head *) \
+               kmalloc(MHEADER_SIZE, GFP_KERNEL);
+       if (!ks->frame_head_info) {
+               printk(KERN_ERR "Error: Fail to allocate frame memory\n");
+               return false;
+       }
+
+       ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS);
+       return true;
+}
+
+
+static int __devinit ks8851_probe(struct platform_device *pdev)
+{
+       int err = -ENOMEM;
+       struct resource *io_d, *io_c;
+       struct net_device *netdev;
+       struct ks_net *ks;
+       u16 id, data;
+
+       io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
+       if (!request_mem_region(io_d->start, resource_size(io_d), DRV_NAME))
+               goto err_mem_region;
+
+       if (!request_mem_region(io_c->start, resource_size(io_c), DRV_NAME))
+               goto err_mem_region1;
+
+       netdev = alloc_etherdev(sizeof(struct ks_net));
+       if (!netdev)
+               goto err_alloc_etherdev;
+
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+
+       ks = netdev_priv(netdev);
+       ks->netdev = netdev;
+       ks->hw_addr = ioremap(io_d->start, resource_size(io_d));
+
+       if (!ks->hw_addr)
+               goto err_ioremap;
+
+       ks->hw_addr_cmd = ioremap(io_c->start, resource_size(io_c));
+       if (!ks->hw_addr_cmd)
+               goto err_ioremap1;
+
+       ks->irq = platform_get_irq(pdev, 0);
+
+       if (ks->irq < 0) {
+               err = ks->irq;
+               goto err_get_irq;
+       }
+
+       ks->pdev = pdev;
+
+       mutex_init(&ks->lock);
+       spin_lock_init(&ks->statelock);
+
+       netdev->netdev_ops = &ks_netdev_ops;
+       netdev->ethtool_ops = &ks_ethtool_ops;
+
+       /* setup mii state */
+       ks->mii.dev             = netdev;
+       ks->mii.phy_id          = 1,
+       ks->mii.phy_id_mask     = 1;
+       ks->mii.reg_num_mask    = 0xf;
+       ks->mii.mdio_read       = ks_phy_read;
+       ks->mii.mdio_write      = ks_phy_write;
+
+       ks_info(ks, "message enable is %d\n", msg_enable);
+       /* set the default message enable */
+       ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV |
+                                                    NETIF_MSG_PROBE |
+                                                    NETIF_MSG_LINK));
+       ks_read_config(ks);
+
+       /* simple check for a valid chip being connected to the bus */
+       if ((ks_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
+               ks_err(ks, "failed to read device ID\n");
+               err = -ENODEV;
+               goto err_register;
+       }
+
+       if (ks_read_selftest(ks)) {
+               ks_err(ks, "failed to read device ID\n");
+               err = -ENODEV;
+               goto err_register;
+       }
+
+       err = register_netdev(netdev);
+       if (err)
+               goto err_register;
+
+       platform_set_drvdata(pdev, netdev);
+
+       ks_soft_reset(ks, GRR_GSR);
+       ks_hw_init(ks);
+       ks_disable(ks);
+       ks_setup(ks);
+       ks_setup_int(ks);
+       ks_enable_int(ks);
+       ks_enable(ks);
+       memcpy(netdev->dev_addr, ks->mac_addr, 6);
+
+       data = ks_rdreg16(ks, KS_OBCR);
+       ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);
+
+       /**
+        * If you want to use the default MAC addr,
+        * comment out the 2 functions below.
+        */
+
+       random_ether_addr(netdev->dev_addr);
+       ks_set_mac(ks, netdev->dev_addr);
+
+       id = ks_rdreg16(ks, KS_CIDER);
+
+       printk(KERN_INFO DRV_NAME
+               " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
+               (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
+       return 0;
+
+err_register:
+err_get_irq:
+       iounmap(ks->hw_addr_cmd);
+err_ioremap1:
+       iounmap(ks->hw_addr);
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       release_mem_region(io_c->start, resource_size(io_c));
+err_mem_region1:
+       release_mem_region(io_d->start, resource_size(io_d));
+err_mem_region:
+       return err;
+}
+
+static int __devexit ks8851_remove(struct platform_device *pdev)
+{
+       struct net_device *netdev = platform_get_drvdata(pdev);
+       struct ks_net *ks = netdev_priv(netdev);
+       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       unregister_netdev(netdev);
+       iounmap(ks->hw_addr);
+       free_netdev(netdev);
+       release_mem_region(iomem->start, resource_size(iomem));
+       platform_set_drvdata(pdev, NULL);
+       return 0;
+
+}
+
+static struct platform_driver ks8851_platform_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+       },
+       .probe = ks8851_probe,
+       .remove = __devexit_p(ks8851_remove),
+};
+
+static int __init ks8851_init(void)
+{
+       return platform_driver_register(&ks8851_platform_driver);
+}
+
+static void __exit ks8851_exit(void)
+{
+       platform_driver_unregister(&ks8851_platform_driver);
+}
+
+module_init(ks8851_init);
+module_exit(ks8851_exit);
+
+MODULE_DESCRIPTION("KS8851 MLL Network driver");
+MODULE_AUTHOR("David Choi <david.choi@micrel.com>");
+MODULE_LICENSE("GPL");
+module_param_named(message, msg_enable, int, 0);
+MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)");
+
index 92ceb689b4d49c854a669cda872cff1da7822d18..2af81735386b86066c30d7ebbf9d99da59e2236e 100644 (file)
@@ -828,7 +828,7 @@ static int __exit meth_remove(struct platform_device *pdev)
 
 static struct platform_driver meth_driver = {
        .probe  = meth_probe,
-       .remove = __devexit_p(meth_remove),
+       .remove = __exit_p(meth_remove),
        .driver = {
                .name   = "meth",
                .owner  = THIS_MODULE,
index cc394d073755413c1bae92367c727f172b6d11e3..5910df60c93eee6a16705ef350546aef6593107a 100644 (file)
@@ -2179,7 +2179,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
  * session or the special tunnel type.
  */
 static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
-                              char __user *optval, int optlen)
+                              char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct pppol2tp_session *session = sk->sk_user_data;
index a9845a2f243f03b68d297539fb6a7dd7b645c0f5..30d5585beeee4771e45a0b316d93629169f25bcc 100644 (file)
@@ -1381,15 +1381,15 @@ struct intr_context {
 
 /* adapter flags definitions. */
 enum {
-       QL_ADAPTER_UP = (1 << 0),       /* Adapter has been brought up. */
-       QL_LEGACY_ENABLED = (1 << 3),
-       QL_MSI_ENABLED = (1 << 3),
-       QL_MSIX_ENABLED = (1 << 4),
-       QL_DMA64 = (1 << 5),
-       QL_PROMISCUOUS = (1 << 6),
-       QL_ALLMULTI = (1 << 7),
-       QL_PORT_CFG = (1 << 8),
-       QL_CAM_RT_SET = (1 << 9),
+       QL_ADAPTER_UP = 0,      /* Adapter has been brought up. */
+       QL_LEGACY_ENABLED = 1,
+       QL_MSI_ENABLED = 2,
+       QL_MSIX_ENABLED = 3,
+       QL_DMA64 = 4,
+       QL_PROMISCUOUS = 5,
+       QL_ALLMULTI = 6,
+       QL_PORT_CFG = 7,
+       QL_CAM_RT_SET = 8,
 };
 
 /* link_status bit definitions */
index 7783c5db81dcf12174e2dc95217336987c6ff10e..3d0efea32111bd15ce5f66a0eaec7ce20ae56408 100644 (file)
@@ -3142,14 +3142,14 @@ static int ql_route_initialize(struct ql_adapter *qdev)
 {
        int status = 0;
 
-       status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+       /* Clear all the entries in the routing table. */
+       status = ql_clear_routing_entries(qdev);
        if (status)
                return status;
 
-       /* Clear all the entries in the routing table. */
-       status = ql_clear_routing_entries(qdev);
+       status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
        if (status)
-               goto exit;
+               return status;
 
        status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1);
        if (status) {
@@ -3380,12 +3380,10 @@ static int ql_adapter_down(struct ql_adapter *qdev)
 
        ql_free_rx_buffers(qdev);
 
-       spin_lock(&qdev->hw_lock);
        status = ql_adapter_reset(qdev);
        if (status)
                QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n",
                        qdev->func);
-       spin_unlock(&qdev->hw_lock);
        return status;
 }
 
@@ -3705,7 +3703,7 @@ static void ql_asic_reset_work(struct work_struct *work)
        struct ql_adapter *qdev =
            container_of(work, struct ql_adapter, asic_reset_work.work);
        int status;
-
+       rtnl_lock();
        status = ql_adapter_down(qdev);
        if (status)
                goto error;
@@ -3713,12 +3711,12 @@ static void ql_asic_reset_work(struct work_struct *work)
        status = ql_adapter_up(qdev);
        if (status)
                goto error;
-
+       rtnl_unlock();
        return;
 error:
        QPRINTK(qdev, IFUP, ALERT,
                "Driver up/down cycle failed, closing device\n");
-       rtnl_lock();
+
        set_bit(QL_ADAPTER_UP, &qdev->flags);
        dev_close(qdev->ndev);
        rtnl_unlock();
@@ -3834,11 +3832,14 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
                return err;
        }
 
+       qdev->ndev = ndev;
+       qdev->pdev = pdev;
+       pci_set_drvdata(pdev, ndev);
        pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
        if (pos <= 0) {
                dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
                        "aborting.\n");
-               goto err_out;
+               return pos;
        } else {
                pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
                val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
@@ -3851,7 +3852,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
        err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
                dev_err(&pdev->dev, "PCI region request failed.\n");
-               goto err_out;
+               return err;
        }
 
        pci_set_master(pdev);
@@ -3869,7 +3870,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
                goto err_out;
        }
 
-       pci_set_drvdata(pdev, ndev);
        qdev->reg_base =
            ioremap_nocache(pci_resource_start(pdev, 1),
                            pci_resource_len(pdev, 1));
@@ -3889,8 +3889,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
                goto err_out;
        }
 
-       qdev->ndev = ndev;
-       qdev->pdev = pdev;
        err = ql_get_board_info(qdev);
        if (err) {
                dev_err(&pdev->dev, "Register access failed.\n");
index ecf3279fbef516857cca35a56cd0562805e92d52..f4dfd1f679a9d925081a364cd500727734326b6e 100644 (file)
@@ -826,7 +826,7 @@ static int __exit sgiseeq_remove(struct platform_device *pdev)
 
 static struct platform_driver sgiseeq_driver = {
        .probe  = sgiseeq_probe,
-       .remove = __devexit_p(sgiseeq_remove),
+       .remove = __exit_p(sgiseeq_remove),
        .driver = {
                .name   = "sgiseeq",
                .owner  = THIS_MODULE,
index 55bad408196604d454b4e4f8e241cb2b98365e83..01f6811f13249af0aabf7114f32d1f413fdee775 100644 (file)
@@ -3935,11 +3935,14 @@ static int __devinit skge_probe(struct pci_dev *pdev,
 #endif
 
        err = -ENOMEM;
-       hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+       /* space for skge@pci:0000:04:00.0 */
+       hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:" )
+                    + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
        if (!hw) {
                dev_err(&pdev->dev, "cannot allocate hardware struct\n");
                goto err_out_free_regions;
        }
+       sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
 
        hw->pdev = pdev;
        spin_lock_init(&hw->hw_lock);
@@ -3974,7 +3977,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
                goto err_out_free_netdev;
        }
 
-       err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, dev->name, hw);
+       err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, hw->irq_name, hw);
        if (err) {
                dev_err(&pdev->dev, "%s: cannot assign irq %d\n",
                       dev->name, pdev->irq);
@@ -3982,14 +3985,17 @@ static int __devinit skge_probe(struct pci_dev *pdev,
        }
        skge_show_addr(dev);
 
-       if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) {
-               if (register_netdev(dev1) == 0)
+       if (hw->ports > 1) {
+               dev1 = skge_devinit(hw, 1, using_dac);
+               if (dev1 && register_netdev(dev1) == 0)
                        skge_show_addr(dev1);
                else {
                        /* Failure to register second port need not be fatal */
                        dev_warn(&pdev->dev, "register of second port failed\n");
                        hw->dev[1] = NULL;
-                       free_netdev(dev1);
+                       hw->ports = 1;
+                       if (dev1)
+                               free_netdev(dev1);
                }
        }
        pci_set_drvdata(pdev, hw);
index 17caccbb768577f44ea259f672b53cfe7a73407d..831de1b6e96e49284973b2eb013ef490f3e0eb3c 100644 (file)
@@ -2423,6 +2423,8 @@ struct skge_hw {
        u16                  phy_addr;
        spinlock_t           phy_lock;
        struct tasklet_struct phy_task;
+
+       char                 irq_name[0]; /* skge@pci:000:04:00.0 */
 };
 
 enum pause_control {
index ef1165718dd77328da13bf06308d59baae82bc59..2ab5c39f33cabfa4c40a3e2a5fe71e67d7b5778c 100644 (file)
@@ -4487,13 +4487,16 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
 
        err = -ENOMEM;
-       hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+
+       hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
+                    + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
        if (!hw) {
                dev_err(&pdev->dev, "cannot allocate hardware struct\n");
                goto err_out_free_regions;
        }
 
        hw->pdev = pdev;
+       sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
 
        hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
        if (!hw->regs) {
@@ -4539,7 +4542,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 
        err = request_irq(pdev->irq, sky2_intr,
                          (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
-                         dev->name, hw);
+                         hw->irq_name, hw);
        if (err) {
                dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
                goto err_out_unregister;
index e0f23a101043c6ee977a52bb961678261226815d..ed54129698b4098306bcba5424bc285342e0a88c 100644 (file)
@@ -2085,6 +2085,8 @@ struct sky2_hw {
        struct timer_list    watchdog_timer;
        struct work_struct   restart_work;
        wait_queue_head_t    msi_wait;
+
+       char                 irq_name[0];
 };
 
 static inline int sky2_is_copper(const struct sky2_hw *hw)
index 82b45d8797b4eb6b2e6b8ad5ba6f08ed2a23709c..524691cd98969885bfc1f849f01be0ccc7a6e950 100644 (file)
@@ -2412,7 +2412,6 @@ struct ring_info {
 
 struct tx_ring_info {
        struct sk_buff                  *skb;
-       u32                             prev_vlan_tag;
 };
 
 struct tg3_config_info {
index d445845f2779ce1b57d6560fac856d4f9fe07888..8d009760277cede76fead3a54edf2c7669a7acbc 100644 (file)
@@ -948,7 +948,7 @@ free:
        return err;
 }
 
-static void virtnet_remove(struct virtio_device *vdev)
+static void __devexit virtnet_remove(struct virtio_device *vdev)
 {
        struct virtnet_info *vi = vdev->priv;
        struct sk_buff *skb;
index 49ea9c92b7e6ea29e733ad2bac893660a074243a..d7a764a2fc1abc3e809af4ae277925e20b331ca6 100644 (file)
@@ -31,13 +31,12 @@ config STRIP
        ---help---
          Say Y if you have a Metricom radio and intend to use Starmode Radio
          IP. STRIP is a radio protocol developed for the MosquitoNet project
-         (on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet
-         traffic using Metricom radios.  Metricom radios are small, battery
-         powered, 100kbit/sec packet radio transceivers, about the size and
-         weight of a cellular telephone. (You may also have heard them called
-         "Metricom modems" but we avoid the term "modem" because it misleads
-         many people into thinking that you can plug a Metricom modem into a
-         phone line and use it as a modem.)
+         to send Internet traffic using Metricom radios.  Metricom radios are
+         small, battery powered, 100kbit/sec packet radio transceivers, about
+         the size and weight of a cellular telephone. (You may also have heard
+         them called "Metricom modems" but we avoid the term "modem" because
+         it misleads many people into thinking that you can plug a Metricom
+         modem into a phone line and use it as a modem.)
 
          You can use STRIP on any Linux machine with a serial port, although
          it is obviously most useful for people with laptop computers. If you
index b3e5cf3735b00ddfc69e99f38d500c5a5e1e86fb..dbd488da18b1ffd8d3ce4ecdc61350b6fa1d046e 100644 (file)
@@ -1141,7 +1141,8 @@ static int ar9170_set_freq_cal_data(struct ar9170 *ar,
        u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
        u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
        int chain, idx, i;
-       u8 f;
+       u32 phy_data = 0;
+       u8 f, tmp;
 
        switch (channel->band) {
        case IEEE80211_BAND_2GHZ:
@@ -1208,9 +1209,6 @@ static int ar9170_set_freq_cal_data(struct ar9170 *ar,
                }
 
                for (i = 0; i < 76; i++) {
-                       u32 phy_data;
-                       u8 tmp;
-
                        if (i < 25) {
                                tmp = ar9170_interpolate_val(i, &pwrs[0][0],
                                                             &vpds[0][0]);
index e96091b314995ec0ebd2f66bfc860a61ca255ac9..9c1397996e0a57753e97f372bce2ad1296abcbb9 100644 (file)
@@ -340,10 +340,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
                        q->mmio_base + B43_PIO_TXDATA,
                        sizeof(u16));
        if (data_len & 1) {
+               u8 tail[2] = { 0, };
+
                /* Write the last byte. */
                ctl &= ~B43_PIO_TXCTL_WRITEHI;
                b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-               b43_piotx_write16(q, B43_PIO_TXDATA, data[data_len - 1]);
+               tail[0] = data[data_len - 1];
+               ssb_block_write(dev->dev, tail, 2,
+                               q->mmio_base + B43_PIO_TXDATA,
+                               sizeof(u16));
        }
 
        return ctl;
@@ -386,26 +391,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
                        q->mmio_base + B43_PIO8_TXDATA,
                        sizeof(u32));
        if (data_len & 3) {
-               u32 value = 0;
+               u8 tail[4] = { 0, };
 
                /* Write the last few bytes. */
                ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
                         B43_PIO8_TXCTL_24_31);
-               data = &(data[data_len - 1]);
                switch (data_len & 3) {
                case 3:
-                       ctl |= B43_PIO8_TXCTL_16_23;
-                       value |= (u32)(*data) << 16;
-                       data--;
+                       ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
+                       tail[0] = data[data_len - 3];
+                       tail[1] = data[data_len - 2];
+                       tail[2] = data[data_len - 1];
+                       break;
                case 2:
                        ctl |= B43_PIO8_TXCTL_8_15;
-                       value |= (u32)(*data) << 8;
-                       data--;
+                       tail[0] = data[data_len - 2];
+                       tail[1] = data[data_len - 1];
+                       break;
                case 1:
-                       value |= (u32)(*data);
+                       tail[0] = data[data_len - 1];
+                       break;
                }
                b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-               b43_piotx_write32(q, B43_PIO8_TXDATA, value);
+               ssb_block_write(dev->dev, tail, 4,
+                               q->mmio_base + B43_PIO8_TXDATA,
+                               sizeof(u32));
        }
 
        return ctl;
@@ -693,21 +703,25 @@ data_ready:
                               q->mmio_base + B43_PIO8_RXDATA,
                               sizeof(u32));
                if (len & 3) {
-                       u32 value;
-                       char *data;
+                       u8 tail[4] = { 0, };
 
                        /* Read the last few bytes. */
-                       value = b43_piorx_read32(q, B43_PIO8_RXDATA);
-                       data = &(skb->data[len + padding - 1]);
+                       ssb_block_read(dev->dev, tail, 4,
+                                      q->mmio_base + B43_PIO8_RXDATA,
+                                      sizeof(u32));
                        switch (len & 3) {
                        case 3:
-                               *data = (value >> 16);
-                               data--;
+                               skb->data[len + padding - 3] = tail[0];
+                               skb->data[len + padding - 2] = tail[1];
+                               skb->data[len + padding - 1] = tail[2];
+                               break;
                        case 2:
-                               *data = (value >> 8);
-                               data--;
+                               skb->data[len + padding - 2] = tail[0];
+                               skb->data[len + padding - 1] = tail[1];
+                               break;
                        case 1:
-                               *data = value;
+                               skb->data[len + padding - 1] = tail[0];
+                               break;
                        }
                }
        } else {
@@ -715,11 +729,13 @@ data_ready:
                               q->mmio_base + B43_PIO_RXDATA,
                               sizeof(u16));
                if (len & 1) {
-                       u16 value;
+                       u8 tail[2] = { 0, };
 
                        /* Read the last byte. */
-                       value = b43_piorx_read16(q, B43_PIO_RXDATA);
-                       skb->data[len + padding - 1] = value;
+                       ssb_block_read(dev->dev, tail, 2,
+                                      q->mmio_base + B43_PIO_RXDATA,
+                                      sizeof(u16));
+                       skb->data[len + padding - 1] = tail[0];
                }
        }
 
index 896f532182f06e27ba9ac1669ddd41364883d9a0..38cfd79e05902ceeff7f27731d5f39fe37503943 100644 (file)
@@ -631,6 +631,9 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
                data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
                if (WARN_ON(!data->beacon_int))
                        data->beacon_int = 1;
+               if (data->started)
+                       mod_timer(&data->beacon_timer,
+                                 jiffies + data->beacon_int);
        }
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT) {
index 1cbd9b4a3efc9c560784280e7c76f6160be00161..b8f5ee33445e15d877c662ad315e6598af01b794 100644 (file)
@@ -2381,6 +2381,7 @@ static struct usb_device_id rt73usb_device_table[] = {
        /* Huawei-3Com */
        { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Hercules */
+       { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Linksys */
index f424146a2bc946c6b8a9eb0683e4e7f8afd3c56f..ac8aa09ba0da56b33f12e3a9ba0168ef73e54779 100644 (file)
@@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = {
        .socket_suspend         = assabet_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_assabet_init(struct device *dev)
+int pcmcia_assabet_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index 4c41e86ccff9c9180999b22aa815d1f4f4f73dcb..0c76d337815bca429b2ef094e19c01f1bd39e8a8 100644 (file)
@@ -123,7 +123,7 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
        .socket_suspend         = sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_neponset_init(struct sa1111_dev *sadev)
+int pcmcia_neponset_init(struct sa1111_dev *sadev)
 {
        int ret = -ENODEV;
 
index afdbdaaf80cb354de22e024f1c99677d81bc0665..a2a742c8ff7e30dab430ef7ece4abc1c2a930dd3 100644 (file)
@@ -1211,15 +1211,6 @@ static int sony_nc_add(struct acpi_device *device)
                }
        }
 
-       /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1
-        * should be respected as we already checked for the device presence above */
-       if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) {
-               dprintk("Invoking _INI\n");
-               if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI,
-                                               NULL, NULL)))
-                       dprintk("_INI Method failed\n");
-       }
-
        if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
                                         &handle))) {
                if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
@@ -1399,27 +1390,20 @@ struct sonypi_eventtypes {
        struct sonypi_event     *events;
 };
 
-struct device_ctrl {
+struct sony_pic_dev {
+       struct acpi_device              *acpi_dev;
+       struct sony_pic_irq             *cur_irq;
+       struct sony_pic_ioport          *cur_ioport;
+       struct list_head                interrupts;
+       struct list_head                ioports;
+       struct mutex                    lock;
+       struct sonypi_eventtypes        *event_types;
+       int                             (*handle_irq)(const u8, const u8);
        int                             model;
-       int                             (*handle_irq)(const u8, const u8);
        u16                             evport_offset;
-       u8                              has_camera;
-       u8                              has_bluetooth;
-       u8                              has_wwan;
-       struct sonypi_eventtypes        *event_types;
-};
-
-struct sony_pic_dev {
-       struct device_ctrl      *control;
-       struct acpi_device      *acpi_dev;
-       struct sony_pic_irq     *cur_irq;
-       struct sony_pic_ioport  *cur_ioport;
-       struct list_head        interrupts;
-       struct list_head        ioports;
-       struct mutex            lock;
-       u8                      camera_power;
-       u8                      bluetooth_power;
-       u8                      wwan_power;
+       u8                              camera_power;
+       u8                              bluetooth_power;
+       u8                              wwan_power;
 };
 
 static struct sony_pic_dev spic_dev = {
@@ -1427,6 +1411,8 @@ static struct sony_pic_dev spic_dev = {
        .ioports        = LIST_HEAD_INIT(spic_dev.ioports),
 };
 
+static int spic_drv_registered;
+
 /* Event masks */
 #define SONYPI_JOGGER_MASK                     0x00000001
 #define SONYPI_CAPTURE_MASK                    0x00000002
@@ -1724,27 +1710,6 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev)
        return 1;
 }
 
-static struct device_ctrl spic_types[] = {
-       {
-               .model = SONYPI_DEVICE_TYPE1,
-               .handle_irq = NULL,
-               .evport_offset = SONYPI_TYPE1_OFFSET,
-               .event_types = type1_events,
-       },
-       {
-               .model = SONYPI_DEVICE_TYPE2,
-               .handle_irq = NULL,
-               .evport_offset = SONYPI_TYPE2_OFFSET,
-               .event_types = type2_events,
-       },
-       {
-               .model = SONYPI_DEVICE_TYPE3,
-               .handle_irq = type3_handle_irq,
-               .evport_offset = SONYPI_TYPE3_OFFSET,
-               .event_types = type3_events,
-       },
-};
-
 static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
 {
        struct pci_dev *pcidev;
@@ -1752,48 +1717,63 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
        if (pcidev) {
-               dev->control = &spic_types[0];
+               dev->model = SONYPI_DEVICE_TYPE1;
+               dev->evport_offset = SONYPI_TYPE1_OFFSET;
+               dev->event_types = type1_events;
                goto out;
        }
 
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_ICH6_1, NULL);
        if (pcidev) {
-               dev->control = &spic_types[2];
+               dev->model = SONYPI_DEVICE_TYPE2;
+               dev->evport_offset = SONYPI_TYPE2_OFFSET;
+               dev->event_types = type2_events;
                goto out;
        }
 
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
        if (pcidev) {
-               dev->control = &spic_types[2];
+               dev->model = SONYPI_DEVICE_TYPE3;
+               dev->handle_irq = type3_handle_irq;
+               dev->evport_offset = SONYPI_TYPE3_OFFSET;
+               dev->event_types = type3_events;
                goto out;
        }
 
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
        if (pcidev) {
-               dev->control = &spic_types[2];
+               dev->model = SONYPI_DEVICE_TYPE3;
+               dev->handle_irq = type3_handle_irq;
+               dev->evport_offset = SONYPI_TYPE3_OFFSET;
+               dev->event_types = type3_events;
                goto out;
        }
 
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
        if (pcidev) {
-               dev->control = &spic_types[2];
+               dev->model = SONYPI_DEVICE_TYPE3;
+               dev->handle_irq = type3_handle_irq;
+               dev->evport_offset = SONYPI_TYPE3_OFFSET;
+               dev->event_types = type3_events;
                goto out;
        }
 
        /* default */
-       dev->control = &spic_types[1];
+       dev->model = SONYPI_DEVICE_TYPE2;
+       dev->evport_offset = SONYPI_TYPE2_OFFSET;
+       dev->event_types = type2_events;
 
 out:
        if (pcidev)
                pci_dev_put(pcidev);
 
        printk(KERN_INFO DRV_PFX "detected Type%d model\n",
-                       dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
-                       dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
+                       dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
+                       dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
 }
 
 /* camera tests and poweron/poweroff */
@@ -2566,7 +2546,7 @@ static int sony_pic_enable(struct acpi_device *device,
        buffer.pointer = resource;
 
        /* setup Type 1 resources */
-       if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) {
+       if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
 
                /* setup io resources */
                resource->res1.type = ACPI_RESOURCE_TYPE_IO;
@@ -2649,29 +2629,28 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
                data_mask = inb_p(dev->cur_ioport->io2.minimum);
        else
                data_mask = inb_p(dev->cur_ioport->io1.minimum +
-                               dev->control->evport_offset);
+                               dev->evport_offset);
 
        dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
                        ev, data_mask, dev->cur_ioport->io1.minimum,
-                       dev->control->evport_offset);
+                       dev->evport_offset);
 
        if (ev == 0x00 || ev == 0xff)
                return IRQ_HANDLED;
 
-       for (i = 0; dev->control->event_types[i].mask; i++) {
+       for (i = 0; dev->event_types[i].mask; i++) {
 
-               if ((data_mask & dev->control->event_types[i].data) !=
-                   dev->control->event_types[i].data)
+               if ((data_mask & dev->event_types[i].data) !=
+                   dev->event_types[i].data)
                        continue;
 
-               if (!(mask & dev->control->event_types[i].mask))
+               if (!(mask & dev->event_types[i].mask))
                        continue;
 
-               for (j = 0; dev->control->event_types[i].events[j].event; j++) {
-                       if (ev == dev->control->event_types[i].events[j].data) {
+               for (j = 0; dev->event_types[i].events[j].event; j++) {
+                       if (ev == dev->event_types[i].events[j].data) {
                                device_event =
-                                       dev->control->
-                                               event_types[i].events[j].event;
+                                       dev->event_types[i].events[j].event;
                                goto found;
                        }
                }
@@ -2679,13 +2658,12 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
        /* Still not able to decode the event try to pass
         * it over to the minidriver
         */
-       if (dev->control->handle_irq &&
-                       dev->control->handle_irq(data_mask, ev) == 0)
+       if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0)
                return IRQ_HANDLED;
 
        dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
                        ev, data_mask, dev->cur_ioport->io1.minimum,
-                       dev->control->evport_offset);
+                       dev->evport_offset);
        return IRQ_HANDLED;
 
 found:
@@ -2816,7 +2794,7 @@ static int sony_pic_add(struct acpi_device *device)
        /* request IRQ */
        list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
                if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
-                                       IRQF_SHARED, "sony-laptop", &spic_dev)) {
+                                       IRQF_DISABLED, "sony-laptop", &spic_dev)) {
                        dprintk("IRQ: %d - triggering: %d - "
                                        "polarity: %d - shr: %d\n",
                                        irq->irq.interrupts[0],
@@ -2949,6 +2927,7 @@ static int __init sony_laptop_init(void)
                                        "Unable to register SPIC driver.");
                        goto out;
                }
+               spic_drv_registered = 1;
        }
 
        result = acpi_bus_register_driver(&sony_nc_driver);
@@ -2960,7 +2939,7 @@ static int __init sony_laptop_init(void)
        return 0;
 
 out_unregister_pic:
-       if (!no_spic)
+       if (spic_drv_registered)
                acpi_bus_unregister_driver(&sony_pic_driver);
 out:
        return result;
@@ -2969,7 +2948,7 @@ out:
 static void __exit sony_laptop_exit(void)
 {
        acpi_bus_unregister_driver(&sony_nc_driver);
-       if (!no_spic)
+       if (spic_drv_registered)
                acpi_bus_unregister_driver(&sony_pic_driver);
 }
 
index 1b78f639ead390547445c5e939d20235914e9894..76769978285f0cd28a15eb2004b633bce16a6418 100644 (file)
@@ -125,7 +125,7 @@ static int qstat_seq_open(struct inode *inode, struct file *filp)
                           filp->f_path.dentry->d_inode->i_private);
 }
 
-static struct file_operations debugfs_fops = {
+static const struct file_operations debugfs_fops = {
        .owner   = THIS_MODULE,
        .open    = qstat_seq_open,
        .read    = seq_read,
index eff943923c6fac1d3e0862c0134b3a2a9920efa0..968e3c7c263269bda6c7d04261871729ce8bbbe6 100644 (file)
@@ -84,7 +84,7 @@ static int qdio_perf_seq_open(struct inode *inode, struct file *filp)
        return single_open(filp, qdio_perf_proc_show, NULL);
 }
 
-static struct file_operations qdio_perf_proc_fops = {
+static const struct file_operations qdio_perf_proc_fops = {
        .owner   = THIS_MODULE,
        .open    = qdio_perf_seq_open,
        .read    = seq_read,
index 0cb049f5cc567c0f107b6b8f913ab4f258e58d4d..747a5e5c1276f62feb3f12f4c2ade154797e6d0b 100644 (file)
@@ -1317,7 +1317,7 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
        }
 }
 
-static struct file_operations sg_fops = {
+static const struct file_operations sg_fops = {
        .owner = THIS_MODULE,
        .read = sg_read,
        .write = sg_write,
@@ -2194,9 +2194,11 @@ static int sg_proc_seq_show_int(struct seq_file *s, void *v);
 static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
 static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
                                  size_t count, loff_t *off);
-static struct file_operations adio_fops = {
-       /* .owner, .read and .llseek added in sg_proc_init() */
+static const struct file_operations adio_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_single_open_adio,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .write = sg_proc_write_adio,
        .release = single_release,
 };
@@ -2204,23 +2206,32 @@ static struct file_operations adio_fops = {
 static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
 static ssize_t sg_proc_write_dressz(struct file *filp, 
                const char __user *buffer, size_t count, loff_t *off);
-static struct file_operations dressz_fops = {
+static const struct file_operations dressz_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_single_open_dressz,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .write = sg_proc_write_dressz,
        .release = single_release,
 };
 
 static int sg_proc_seq_show_version(struct seq_file *s, void *v);
 static int sg_proc_single_open_version(struct inode *inode, struct file *file);
-static struct file_operations version_fops = {
+static const struct file_operations version_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_single_open_version,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .release = single_release,
 };
 
 static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
 static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
-static struct file_operations devhdr_fops = {
+static const struct file_operations devhdr_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_single_open_devhdr,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .release = single_release,
 };
 
@@ -2229,8 +2240,11 @@ static int sg_proc_open_dev(struct inode *inode, struct file *file);
 static void * dev_seq_start(struct seq_file *s, loff_t *pos);
 static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
 static void dev_seq_stop(struct seq_file *s, void *v);
-static struct file_operations dev_fops = {
+static const struct file_operations dev_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_open_dev,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .release = seq_release,
 };
 static const struct seq_operations dev_seq_ops = {
@@ -2242,8 +2256,11 @@ static const struct seq_operations dev_seq_ops = {
 
 static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
 static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
-static struct file_operations devstrs_fops = {
+static const struct file_operations devstrs_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_open_devstrs,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .release = seq_release,
 };
 static const struct seq_operations devstrs_seq_ops = {
@@ -2255,8 +2272,11 @@ static const struct seq_operations devstrs_seq_ops = {
 
 static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
 static int sg_proc_open_debug(struct inode *inode, struct file *file);
-static struct file_operations debug_fops = {
+static const struct file_operations debug_fops = {
+       .owner = THIS_MODULE,
        .open = sg_proc_open_debug,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .release = seq_release,
 };
 static const struct seq_operations debug_seq_ops = {
@@ -2269,7 +2289,7 @@ static const struct seq_operations debug_seq_ops = {
 
 struct sg_proc_leaf {
        const char * name;
-       struct file_operations * fops;
+       const struct file_operations * fops;
 };
 
 static struct sg_proc_leaf sg_proc_leaf_arr[] = {
@@ -2295,9 +2315,6 @@ sg_proc_init(void)
        for (k = 0; k < num_leaves; ++k) {
                leaf = &sg_proc_leaf_arr[k];
                mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO;
-               leaf->fops->owner = THIS_MODULE;
-               leaf->fops->read = seq_read;
-               leaf->fops->llseek = seq_lseek;
                proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops);
        }
        return 0;
index 2209620d2349337a44b6a9b035c8cd6583f96b79..b1ae774016f12b5271ed4d90dc3150838f1415d6 100644 (file)
@@ -64,6 +64,8 @@ static int serial_index(struct uart_port *port)
        return (serial8250_reg.minor - 64) + port->line;
 }
 
+static unsigned int skip_txen_test; /* force skip of txen test at init time */
+
 /*
  * Debugging.
  */
@@ -2108,7 +2110,7 @@ static int serial8250_startup(struct uart_port *port)
           is variable. So, let's just don't test if we receive
           TX irq. This way, we'll never enable UART_BUG_TXEN.
         */
-       if (up->port.flags & UPF_NO_TXEN_TEST)
+       if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
                goto dont_test_tx_en;
 
        /*
@@ -3248,6 +3250,9 @@ MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
 module_param(nr_uarts, uint, 0644);
 MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
 
+module_param(skip_txen_test, uint, 0644);
+MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
+
 #ifdef CONFIG_SERIAL_8250_RSA
 module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
 MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
index e70712044a7ec9a18705150ae0d08864b72d6fc4..e52257257279a5a7cc1ae50d134c7e08d91b7243 100644 (file)
@@ -862,7 +862,7 @@ config SERIAL_IMX_CONSOLE
 
 config SERIAL_UARTLITE
        tristate "Xilinx uartlite serial port support"
-       depends on PPC32 || MICROBLAZE
+       depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE
        select SERIAL_CORE
        help
          Say Y here if you want to use the Xilinx uartlite serial controller.
index 2d7feecaf492368294e92b884dc3fbd349f6a648..0028b6f89ce6aa7b48755e19c092e14b182da96e 100644 (file)
@@ -307,7 +307,7 @@ static void stop_processor(struct icom_port *icom_port)
        if (port < 4) {
                temp = readl(stop_proc[port].global_control_reg);
                temp =
-                       (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
+                       (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
                writel(temp, stop_proc[port].global_control_reg);
 
                /* write flush */
@@ -336,7 +336,7 @@ static void start_processor(struct icom_port *icom_port)
        if (port < 4) {
                temp = readl(start_proc[port].global_control_reg);
                temp =
-                       (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
+                       (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
                writel(temp, start_proc[port].global_control_reg);
 
                /* write flush */
@@ -509,8 +509,8 @@ static void load_code(struct icom_port *icom_port)
                dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
        }
 
-      if (new_page != NULL)
-             pci_free_consistent(dev, 4096, new_page, temp_pci);
+       if (new_page != NULL)
+               pci_free_consistent(dev, 4096, new_page, temp_pci);
 }
 
 static int startup(struct icom_port *icom_port)
@@ -1493,15 +1493,15 @@ static int __devinit icom_probe(struct pci_dev *dev,
                                const struct pci_device_id *ent)
 {
        int index;
-        unsigned int command_reg;
-        int retval;
-        struct icom_adapter *icom_adapter;
-        struct icom_port *icom_port;
+       unsigned int command_reg;
+       int retval;
+       struct icom_adapter *icom_adapter;
+       struct icom_port *icom_port;
 
-        retval = pci_enable_device(dev);
-        if (retval) {
+       retval = pci_enable_device(dev);
+       if (retval) {
                dev_err(&dev->dev, "Device enable FAILED\n");
-                return retval;
+               return retval;
        }
 
        if ( (retval = pci_request_regions(dev, "icom"))) {
@@ -1510,23 +1510,23 @@ static int __devinit icom_probe(struct pci_dev *dev,
                 return retval;
         }
 
-        pci_set_master(dev);
+       pci_set_master(dev);
 
-        if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
+       if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
                dev_err(&dev->dev, "PCI Config read FAILED\n");
-                return retval;
-        }
+               return retval;
+       }
 
        pci_write_config_dword(dev, PCI_COMMAND,
                command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
                | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
 
-        if (ent->driver_data == ADAPTER_V1) {
+       if (ent->driver_data == ADAPTER_V1) {
                pci_write_config_dword(dev, 0x44, 0x8300830A);
-        } else {
+       } else {
                pci_write_config_dword(dev, 0x44, 0x42004200);
                pci_write_config_dword(dev, 0x48, 0x42004200);
-         }
+       }
 
 
        retval = icom_alloc_adapter(&icom_adapter);
@@ -1536,10 +1536,10 @@ static int __devinit icom_probe(struct pci_dev *dev,
                 goto probe_exit0;
        }
 
-        icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
-        icom_adapter->pci_dev = dev;
-        icom_adapter->version = ent->driver_data;
-        icom_adapter->subsystem_id = ent->subdevice;
+       icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
+       icom_adapter->pci_dev = dev;
+       icom_adapter->version = ent->driver_data;
+       icom_adapter->subsystem_id = ent->subdevice;
 
 
        retval = icom_init_ports(icom_adapter);
@@ -1548,7 +1548,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
                goto probe_exit1;
        }
 
-        icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
+       icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
 
        if (!icom_adapter->base_addr)
                goto probe_exit1;
@@ -1562,7 +1562,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
 
        retval = icom_load_ports(icom_adapter);
 
-        for (index = 0; index < icom_adapter->numb_ports; index++) {
+       for (index = 0; index < icom_adapter->numb_ports; index++) {
                icom_port = &icom_adapter->port_info[index];
 
                if (icom_port->status == ICOM_PORT_ACTIVE) {
@@ -1579,7 +1579,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
                                icom_port->status = ICOM_PORT_OFF;
                                dev_err(&dev->dev, "Device add failed\n");
                         } else
-                               dev_info(&dev->dev, "Device added\n");
+                               dev_info(&dev->dev, "Device added\n");
                }
        }
 
@@ -1595,9 +1595,7 @@ probe_exit0:
        pci_release_regions(dev);
        pci_disable_device(dev);
 
-        return retval;
-
-
+       return retval;
 }
 
 static void __devexit icom_remove(struct pci_dev *dev)
index 7f5e26873220b6f4b17fb5b6d34de3fbedd72d2a..2199d819a9870b2d8d52d4ab8bb6ae6832d56c00 100644 (file)
@@ -638,7 +638,7 @@ static void __init sa1100_init_ports(void)
        PPSR |= PPC_TXD1 | PPC_TXD3;
 }
 
-void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns)
+void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns)
 {
        if (fns->get_mctrl)
                sa1100_pops.get_mctrl = fns->get_mctrl;
index 0f7cf4c453e6edd0cfa79ea1f44fd3d40352ee87..c50e9fbbf743cbf5aa98f164afc759fd305e46d4 100644 (file)
@@ -221,21 +221,26 @@ sio_quot_set(struct uart_txx9_port *up, int quot)
                sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6);
 }
 
+static struct uart_txx9_port *to_uart_txx9_port(struct uart_port *port)
+{
+       return container_of(port, struct uart_txx9_port, port);
+}
+
 static void serial_txx9_stop_tx(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
 }
 
 static void serial_txx9_start_tx(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
 }
 
 static void serial_txx9_stop_rx(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        up->port.read_status_mask &= ~TXX9_SIDISR_RDIS;
 }
 
@@ -246,7 +251,7 @@ static void serial_txx9_enable_ms(struct uart_port *port)
 
 static void serial_txx9_initialize(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned int tmout = 10000;
 
        sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
@@ -414,7 +419,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id)
 
 static unsigned int serial_txx9_tx_empty(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned long flags;
        unsigned int ret;
 
@@ -427,7 +432,7 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port)
 
 static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned int ret;
 
        /* no modem control lines */
@@ -440,7 +445,7 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
 
 static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
 
        if (mctrl & TIOCM_RTS)
                sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
@@ -450,7 +455,7 @@ static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
 static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned long flags;
 
        spin_lock_irqsave(&up->port.lock, flags);
@@ -494,7 +499,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port)
 {
        unsigned int ier;
        unsigned char c;
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
 
        /*
         *      First save the IER then disable the interrupts
@@ -520,7 +525,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port)
 static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
 {
        unsigned int ier;
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
 
        /*
         *      First save the IER then disable the interrupts
@@ -551,7 +556,7 @@ static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
 
 static int serial_txx9_startup(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned long flags;
        int retval;
 
@@ -596,7 +601,7 @@ static int serial_txx9_startup(struct uart_port *port)
 
 static void serial_txx9_shutdown(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned long flags;
 
        /*
@@ -636,7 +641,7 @@ static void
 serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
                       struct ktermios *old)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        unsigned int cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
@@ -814,19 +819,19 @@ static void serial_txx9_release_resource(struct uart_txx9_port *up)
 
 static void serial_txx9_release_port(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        serial_txx9_release_resource(up);
 }
 
 static int serial_txx9_request_port(struct uart_port *port)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        return serial_txx9_request_resource(up);
 }
 
 static void serial_txx9_config_port(struct uart_port *port, int uflags)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
        int ret;
 
        /*
@@ -897,7 +902,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv,
 
 static void serial_txx9_console_putchar(struct uart_port *port, int ch)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       struct uart_txx9_port *up = to_uart_txx9_port(port);
 
        wait_for_xmitr(up);
        sio_out(up, TXX9_SITFIFO, ch);
index d3b496800477b065b42b1b92a0a0b201e5503b78..b204a09291393406acd9450ba641d754fd0707ed 100644 (file)
@@ -90,7 +90,11 @@ static struct sfi_table_simple *syst_va __read_mostly;
  */
 static u32 sfi_use_ioremap __read_mostly;
 
-static void __iomem *sfi_map_memory(u64 phys, u32 size)
+/*
+ * sfi_un/map_memory calls early_ioremap/iounmap which is a __init function
+ * and introduces section mismatch. So use __ref to make it calm.
+ */
+static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
 {
        if (!phys || !size)
                return NULL;
@@ -101,7 +105,7 @@ static void __iomem *sfi_map_memory(u64 phys, u32 size)
                return early_ioremap(phys, size);
 }
 
-static void sfi_unmap_memory(void __iomem *virt, u32 size)
+static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
 {
        if (!virt || !size)
                return;
@@ -125,7 +129,7 @@ static void sfi_print_table_header(unsigned long long pa,
  * sfi_verify_table()
  * Sanity check table lengh, calculate checksum
  */
-static __init int sfi_verify_table(struct sfi_table_header *table)
+static int sfi_verify_table(struct sfi_table_header *table)
 {
 
        u8 checksum = 0;
@@ -213,12 +217,17 @@ static int sfi_table_check_key(struct sfi_table_header *th,
  *    the mapped virt address will be returned, and the virt space
  *    will be released by call sfi_put_table() later
  *
+ * This two cases are from two different functions with two different
+ * sections and causes section mismatch warning. So use __ref to tell
+ * modpost not to make any noise.
+ *
  * Return value:
  *     NULL:                   when can't find a table matching the key
  *     ERR_PTR(error):         error value
  *     virt table address:     when a matched table is found
  */
-struct sfi_table_header *sfi_check_table(u64 pa, struct sfi_table_key *key)
+struct sfi_table_header *
+ __ref sfi_check_table(u64 pa, struct sfi_table_key *key)
 {
        struct sfi_table_header *th;
        void *ret = NULL;
index 6d7a3f82c54b400e3d51adf59b3189857e699833..21a118269cac1feb030b23977eb6dd454740345b 100644 (file)
@@ -17,7 +17,7 @@ obj-$(CONFIG_SPI_BITBANG)             += spi_bitbang.o
 obj-$(CONFIG_SPI_AU1550)               += au1550_spi.o
 obj-$(CONFIG_SPI_BUTTERFLY)            += spi_butterfly.o
 obj-$(CONFIG_SPI_GPIO)                 += spi_gpio.o
-obj-$(CONFIG_SPI_IMX)                  += mxc_spi.o
+obj-$(CONFIG_SPI_IMX)                  += spi_imx.o
 obj-$(CONFIG_SPI_LM70_LLP)             += spi_lm70llp.o
 obj-$(CONFIG_SPI_PXA2XX)               += pxa2xx_spi.o
 obj-$(CONFIG_SPI_OMAP_UWIRE)           += omap_uwire.o
similarity index 55%
rename from drivers/spi/mxc_spi.c
rename to drivers/spi/spi_imx.c
index b1447236ae81044f7ad43986bb833103360b579a..89c22efedfb0db8102339a06a35847205424771a 100644 (file)
 #define MXC_INT_RR     (1 << 0) /* Receive data ready interrupt */
 #define MXC_INT_TE     (1 << 1) /* Transmit FIFO empty interrupt */
 
-struct mxc_spi_config {
+struct spi_imx_config {
        unsigned int speed_hz;
        unsigned int bpw;
        unsigned int mode;
        int cs;
 };
 
-struct mxc_spi_data {
+struct spi_imx_data {
        struct spi_bitbang bitbang;
 
        struct completion xfer_done;
@@ -66,43 +66,43 @@ struct mxc_spi_data {
        int *chipselect;
 
        unsigned int count;
-       void (*tx)(struct mxc_spi_data *);
-       void (*rx)(struct mxc_spi_data *);
+       void (*tx)(struct spi_imx_data *);
+       void (*rx)(struct spi_imx_data *);
        void *rx_buf;
        const void *tx_buf;
        unsigned int txfifo; /* number of words pushed in tx FIFO */
 
        /* SoC specific functions */
-       void (*intctrl)(struct mxc_spi_data *, int);
-       int (*config)(struct mxc_spi_data *, struct mxc_spi_config *);
-       void (*trigger)(struct mxc_spi_data *);
-       int (*rx_available)(struct mxc_spi_data *);
+       void (*intctrl)(struct spi_imx_data *, int);
+       int (*config)(struct spi_imx_data *, struct spi_imx_config *);
+       void (*trigger)(struct spi_imx_data *);
+       int (*rx_available)(struct spi_imx_data *);
 };
 
 #define MXC_SPI_BUF_RX(type)                                           \
-static void mxc_spi_buf_rx_##type(struct mxc_spi_data *mxc_spi)                \
+static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx)                \
 {                                                                      \
-       unsigned int val = readl(mxc_spi->base + MXC_CSPIRXDATA);       \
+       unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA);       \
                                                                        \
-       if (mxc_spi->rx_buf) {                                          \
-               *(type *)mxc_spi->rx_buf = val;                         \
-               mxc_spi->rx_buf += sizeof(type);                        \
+       if (spi_imx->rx_buf) {                                          \
+               *(type *)spi_imx->rx_buf = val;                         \
+               spi_imx->rx_buf += sizeof(type);                        \
        }                                                               \
 }
 
 #define MXC_SPI_BUF_TX(type)                                           \
-static void mxc_spi_buf_tx_##type(struct mxc_spi_data *mxc_spi)                \
+static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx)                \
 {                                                                      \
        type val = 0;                                                   \
                                                                        \
-       if (mxc_spi->tx_buf) {                                          \
-               val = *(type *)mxc_spi->tx_buf;                         \
-               mxc_spi->tx_buf += sizeof(type);                        \
+       if (spi_imx->tx_buf) {                                          \
+               val = *(type *)spi_imx->tx_buf;                         \
+               spi_imx->tx_buf += sizeof(type);                        \
        }                                                               \
                                                                        \
-       mxc_spi->count -= sizeof(type);                                 \
+       spi_imx->count -= sizeof(type);                                 \
                                                                        \
-       writel(val, mxc_spi->base + MXC_CSPITXDATA);                    \
+       writel(val, spi_imx->base + MXC_CSPITXDATA);                    \
 }
 
 MXC_SPI_BUF_RX(u8)
@@ -119,7 +119,7 @@ static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
        256, 384, 512, 768, 1024};
 
 /* MX21, MX27 */
-static unsigned int mxc_spi_clkdiv_1(unsigned int fin,
+static unsigned int spi_imx_clkdiv_1(unsigned int fin,
                unsigned int fspi)
 {
        int i, max;
@@ -137,7 +137,7 @@ static unsigned int mxc_spi_clkdiv_1(unsigned int fin,
 }
 
 /* MX1, MX31, MX35 */
-static unsigned int mxc_spi_clkdiv_2(unsigned int fin,
+static unsigned int spi_imx_clkdiv_2(unsigned int fin,
                unsigned int fspi)
 {
        int i, div = 4;
@@ -174,7 +174,7 @@ static unsigned int mxc_spi_clkdiv_2(unsigned int fin,
  * the i.MX35 has a slightly different register layout for bits
  * we do not use here.
  */
-static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable)
+static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable)
 {
        unsigned int val = 0;
 
@@ -183,24 +183,24 @@ static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable)
        if (enable & MXC_INT_RR)
                val |= MX31_INTREG_RREN;
 
-       writel(val, mxc_spi->base + MXC_CSPIINT);
+       writel(val, spi_imx->base + MXC_CSPIINT);
 }
 
-static void mx31_trigger(struct mxc_spi_data *mxc_spi)
+static void mx31_trigger(struct spi_imx_data *spi_imx)
 {
        unsigned int reg;
 
-       reg = readl(mxc_spi->base + MXC_CSPICTRL);
+       reg = readl(spi_imx->base + MXC_CSPICTRL);
        reg |= MX31_CSPICTRL_XCH;
-       writel(reg, mxc_spi->base + MXC_CSPICTRL);
+       writel(reg, spi_imx->base + MXC_CSPICTRL);
 }
 
-static int mx31_config(struct mxc_spi_data *mxc_spi,
-               struct mxc_spi_config *config)
+static int mx31_config(struct spi_imx_data *spi_imx,
+               struct spi_imx_config *config)
 {
        unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
 
-       reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) <<
+       reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
                MX31_CSPICTRL_DR_SHIFT;
 
        if (cpu_is_mx31())
@@ -223,14 +223,14 @@ static int mx31_config(struct mxc_spi_data *mxc_spi,
                        reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
        }
 
-       writel(reg, mxc_spi->base + MXC_CSPICTRL);
+       writel(reg, spi_imx->base + MXC_CSPICTRL);
 
        return 0;
 }
 
-static int mx31_rx_available(struct mxc_spi_data *mxc_spi)
+static int mx31_rx_available(struct spi_imx_data *spi_imx)
 {
-       return readl(mxc_spi->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
+       return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
 }
 
 #define MX27_INTREG_RR         (1 << 4)
@@ -246,7 +246,7 @@ static int mx31_rx_available(struct mxc_spi_data *mxc_spi)
 #define MX27_CSPICTRL_DR_SHIFT 14
 #define MX27_CSPICTRL_CS_SHIFT 19
 
-static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable)
+static void mx27_intctrl(struct spi_imx_data *spi_imx, int enable)
 {
        unsigned int val = 0;
 
@@ -255,24 +255,24 @@ static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable)
        if (enable & MXC_INT_RR)
                val |= MX27_INTREG_RREN;
 
-       writel(val, mxc_spi->base + MXC_CSPIINT);
+       writel(val, spi_imx->base + MXC_CSPIINT);
 }
 
-static void mx27_trigger(struct mxc_spi_data *mxc_spi)
+static void mx27_trigger(struct spi_imx_data *spi_imx)
 {
        unsigned int reg;
 
-       reg = readl(mxc_spi->base + MXC_CSPICTRL);
+       reg = readl(spi_imx->base + MXC_CSPICTRL);
        reg |= MX27_CSPICTRL_XCH;
-       writel(reg, mxc_spi->base + MXC_CSPICTRL);
+       writel(reg, spi_imx->base + MXC_CSPICTRL);
 }
 
-static int mx27_config(struct mxc_spi_data *mxc_spi,
-               struct mxc_spi_config *config)
+static int mx27_config(struct spi_imx_data *spi_imx,
+               struct spi_imx_config *config)
 {
        unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER;
 
-       reg |= mxc_spi_clkdiv_1(mxc_spi->spi_clk, config->speed_hz) <<
+       reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz) <<
                MX27_CSPICTRL_DR_SHIFT;
        reg |= config->bpw - 1;
 
@@ -285,14 +285,14 @@ static int mx27_config(struct mxc_spi_data *mxc_spi,
        if (config->cs < 0)
                reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT;
 
-       writel(reg, mxc_spi->base + MXC_CSPICTRL);
+       writel(reg, spi_imx->base + MXC_CSPICTRL);
 
        return 0;
 }
 
-static int mx27_rx_available(struct mxc_spi_data *mxc_spi)
+static int mx27_rx_available(struct spi_imx_data *spi_imx)
 {
-       return readl(mxc_spi->base + MXC_CSPIINT) & MX27_INTREG_RR;
+       return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR;
 }
 
 #define MX1_INTREG_RR          (1 << 3)
@@ -306,7 +306,7 @@ static int mx27_rx_available(struct mxc_spi_data *mxc_spi)
 #define MX1_CSPICTRL_MASTER    (1 << 10)
 #define MX1_CSPICTRL_DR_SHIFT  13
 
-static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable)
+static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable)
 {
        unsigned int val = 0;
 
@@ -315,24 +315,24 @@ static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable)
        if (enable & MXC_INT_RR)
                val |= MX1_INTREG_RREN;
 
-       writel(val, mxc_spi->base + MXC_CSPIINT);
+       writel(val, spi_imx->base + MXC_CSPIINT);
 }
 
-static void mx1_trigger(struct mxc_spi_data *mxc_spi)
+static void mx1_trigger(struct spi_imx_data *spi_imx)
 {
        unsigned int reg;
 
-       reg = readl(mxc_spi->base + MXC_CSPICTRL);
+       reg = readl(spi_imx->base + MXC_CSPICTRL);
        reg |= MX1_CSPICTRL_XCH;
-       writel(reg, mxc_spi->base + MXC_CSPICTRL);
+       writel(reg, spi_imx->base + MXC_CSPICTRL);
 }
 
-static int mx1_config(struct mxc_spi_data *mxc_spi,
-               struct mxc_spi_config *config)
+static int mx1_config(struct spi_imx_data *spi_imx,
+               struct spi_imx_config *config)
 {
        unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER;
 
-       reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) <<
+       reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
                MX1_CSPICTRL_DR_SHIFT;
        reg |= config->bpw - 1;
 
@@ -341,156 +341,151 @@ static int mx1_config(struct mxc_spi_data *mxc_spi,
        if (config->mode & SPI_CPOL)
                reg |= MX1_CSPICTRL_POL;
 
-       writel(reg, mxc_spi->base + MXC_CSPICTRL);
+       writel(reg, spi_imx->base + MXC_CSPICTRL);
 
        return 0;
 }
 
-static int mx1_rx_available(struct mxc_spi_data *mxc_spi)
+static int mx1_rx_available(struct spi_imx_data *spi_imx)
 {
-       return readl(mxc_spi->base + MXC_CSPIINT) & MX1_INTREG_RR;
+       return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR;
 }
 
-static void mxc_spi_chipselect(struct spi_device *spi, int is_active)
+static void spi_imx_chipselect(struct spi_device *spi, int is_active)
 {
-       struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master);
-       unsigned int cs = 0;
-       int gpio = mxc_spi->chipselect[spi->chip_select];
-       struct mxc_spi_config config;
+       struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+       int gpio = spi_imx->chipselect[spi->chip_select];
+       int active = is_active != BITBANG_CS_INACTIVE;
+       int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH);
 
-       if (spi->mode & SPI_CS_HIGH)
-               cs = 1;
-
-       if (is_active == BITBANG_CS_INACTIVE) {
-               if (gpio >= 0)
-                       gpio_set_value(gpio, !cs);
+       if (gpio < 0)
                return;
-       }
-
-       config.bpw = spi->bits_per_word;
-       config.speed_hz = spi->max_speed_hz;
-       config.mode = spi->mode;
-       config.cs = mxc_spi->chipselect[spi->chip_select];
-
-       mxc_spi->config(mxc_spi, &config);
-
-       /* Initialize the functions for transfer */
-       if (config.bpw <= 8) {
-               mxc_spi->rx = mxc_spi_buf_rx_u8;
-               mxc_spi->tx = mxc_spi_buf_tx_u8;
-       } else if (config.bpw <= 16) {
-               mxc_spi->rx = mxc_spi_buf_rx_u16;
-               mxc_spi->tx = mxc_spi_buf_tx_u16;
-       } else if (config.bpw <= 32) {
-               mxc_spi->rx = mxc_spi_buf_rx_u32;
-               mxc_spi->tx = mxc_spi_buf_tx_u32;
-       } else
-               BUG();
 
-       if (gpio >= 0)
-               gpio_set_value(gpio, cs);
-
-       return;
+       gpio_set_value(gpio, dev_is_lowactive ^ active);
 }
 
-static void mxc_spi_push(struct mxc_spi_data *mxc_spi)
+static void spi_imx_push(struct spi_imx_data *spi_imx)
 {
-       while (mxc_spi->txfifo < 8) {
-               if (!mxc_spi->count)
+       while (spi_imx->txfifo < 8) {
+               if (!spi_imx->count)
                        break;
-               mxc_spi->tx(mxc_spi);
-               mxc_spi->txfifo++;
+               spi_imx->tx(spi_imx);
+               spi_imx->txfifo++;
        }
 
-       mxc_spi->trigger(mxc_spi);
+       spi_imx->trigger(spi_imx);
 }
 
-static irqreturn_t mxc_spi_isr(int irq, void *dev_id)
+static irqreturn_t spi_imx_isr(int irq, void *dev_id)
 {
-       struct mxc_spi_data *mxc_spi = dev_id;
+       struct spi_imx_data *spi_imx = dev_id;
 
-       while (mxc_spi->rx_available(mxc_spi)) {
-               mxc_spi->rx(mxc_spi);
-               mxc_spi->txfifo--;
+       while (spi_imx->rx_available(spi_imx)) {
+               spi_imx->rx(spi_imx);
+               spi_imx->txfifo--;
        }
 
-       if (mxc_spi->count) {
-               mxc_spi_push(mxc_spi);
+       if (spi_imx->count) {
+               spi_imx_push(spi_imx);
                return IRQ_HANDLED;
        }
 
-       if (mxc_spi->txfifo) {
+       if (spi_imx->txfifo) {
                /* No data left to push, but still waiting for rx data,
                 * enable receive data available interrupt.
                 */
-               mxc_spi->intctrl(mxc_spi, MXC_INT_RR);
+               spi_imx->intctrl(spi_imx, MXC_INT_RR);
                return IRQ_HANDLED;
        }
 
-       mxc_spi->intctrl(mxc_spi, 0);
-       complete(&mxc_spi->xfer_done);
+       spi_imx->intctrl(spi_imx, 0);
+       complete(&spi_imx->xfer_done);
 
        return IRQ_HANDLED;
 }
 
-static int mxc_spi_setupxfer(struct spi_device *spi,
+static int spi_imx_setupxfer(struct spi_device *spi,
                                 struct spi_transfer *t)
 {
-       struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master);
-       struct mxc_spi_config config;
+       struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+       struct spi_imx_config config;
 
        config.bpw = t ? t->bits_per_word : spi->bits_per_word;
        config.speed_hz  = t ? t->speed_hz : spi->max_speed_hz;
        config.mode = spi->mode;
+       config.cs = spi_imx->chipselect[spi->chip_select];
+
+       if (!config.speed_hz)
+               config.speed_hz = spi->max_speed_hz;
+       if (!config.bpw)
+               config.bpw = spi->bits_per_word;
+       if (!config.speed_hz)
+               config.speed_hz = spi->max_speed_hz;
+
+       /* Initialize the functions for transfer */
+       if (config.bpw <= 8) {
+               spi_imx->rx = spi_imx_buf_rx_u8;
+               spi_imx->tx = spi_imx_buf_tx_u8;
+       } else if (config.bpw <= 16) {
+               spi_imx->rx = spi_imx_buf_rx_u16;
+               spi_imx->tx = spi_imx_buf_tx_u16;
+       } else if (config.bpw <= 32) {
+               spi_imx->rx = spi_imx_buf_rx_u32;
+               spi_imx->tx = spi_imx_buf_tx_u32;
+       } else
+               BUG();
 
-       mxc_spi->config(mxc_spi, &config);
+       spi_imx->config(spi_imx, &config);
 
        return 0;
 }
 
-static int mxc_spi_transfer(struct spi_device *spi,
+static int spi_imx_transfer(struct spi_device *spi,
                                struct spi_transfer *transfer)
 {
-       struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master);
+       struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
 
-       mxc_spi->tx_buf = transfer->tx_buf;
-       mxc_spi->rx_buf = transfer->rx_buf;
-       mxc_spi->count = transfer->len;
-       mxc_spi->txfifo = 0;
+       spi_imx->tx_buf = transfer->tx_buf;
+       spi_imx->rx_buf = transfer->rx_buf;
+       spi_imx->count = transfer->len;
+       spi_imx->txfifo = 0;
 
-       init_completion(&mxc_spi->xfer_done);
+       init_completion(&spi_imx->xfer_done);
 
-       mxc_spi_push(mxc_spi);
+       spi_imx_push(spi_imx);
 
-       mxc_spi->intctrl(mxc_spi, MXC_INT_TE);
+       spi_imx->intctrl(spi_imx, MXC_INT_TE);
 
-       wait_for_completion(&mxc_spi->xfer_done);
+       wait_for_completion(&spi_imx->xfer_done);
 
        return transfer->len;
 }
 
-static int mxc_spi_setup(struct spi_device *spi)
+static int spi_imx_setup(struct spi_device *spi)
 {
-       if (!spi->bits_per_word)
-               spi->bits_per_word = 8;
+       struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+       int gpio = spi_imx->chipselect[spi->chip_select];
 
        pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__,
                 spi->mode, spi->bits_per_word, spi->max_speed_hz);
 
-       mxc_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+       if (gpio >= 0)
+               gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
+
+       spi_imx_chipselect(spi, BITBANG_CS_INACTIVE);
 
        return 0;
 }
 
-static void mxc_spi_cleanup(struct spi_device *spi)
+static void spi_imx_cleanup(struct spi_device *spi)
 {
 }
 
-static int __init mxc_spi_probe(struct platform_device *pdev)
+static int __init spi_imx_probe(struct platform_device *pdev)
 {
        struct spi_imx_master *mxc_platform_info;
        struct spi_master *master;
-       struct mxc_spi_data *mxc_spi;
+       struct spi_imx_data *spi_imx;
        struct resource *res;
        int i, ret;
 
@@ -500,7 +495,7 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       master = spi_alloc_master(&pdev->dev, sizeof(struct mxc_spi_data));
+       master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data));
        if (!master)
                return -ENOMEM;
 
@@ -509,32 +504,32 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
        master->bus_num = pdev->id;
        master->num_chipselect = mxc_platform_info->num_chipselect;
 
-       mxc_spi = spi_master_get_devdata(master);
-       mxc_spi->bitbang.master = spi_master_get(master);
-       mxc_spi->chipselect = mxc_platform_info->chipselect;
+       spi_imx = spi_master_get_devdata(master);
+       spi_imx->bitbang.master = spi_master_get(master);
+       spi_imx->chipselect = mxc_platform_info->chipselect;
 
        for (i = 0; i < master->num_chipselect; i++) {
-               if (mxc_spi->chipselect[i] < 0)
+               if (spi_imx->chipselect[i] < 0)
                        continue;
-               ret = gpio_request(mxc_spi->chipselect[i], DRIVER_NAME);
+               ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
                if (ret) {
                        i--;
                        while (i > 0)
-                               if (mxc_spi->chipselect[i] >= 0)
-                                       gpio_free(mxc_spi->chipselect[i--]);
+                               if (spi_imx->chipselect[i] >= 0)
+                                       gpio_free(spi_imx->chipselect[i--]);
                        dev_err(&pdev->dev, "can't get cs gpios");
                        goto out_master_put;
                }
-               gpio_direction_output(mxc_spi->chipselect[i], 1);
        }
 
-       mxc_spi->bitbang.chipselect = mxc_spi_chipselect;
-       mxc_spi->bitbang.setup_transfer = mxc_spi_setupxfer;
-       mxc_spi->bitbang.txrx_bufs = mxc_spi_transfer;
-       mxc_spi->bitbang.master->setup = mxc_spi_setup;
-       mxc_spi->bitbang.master->cleanup = mxc_spi_cleanup;
+       spi_imx->bitbang.chipselect = spi_imx_chipselect;
+       spi_imx->bitbang.setup_transfer = spi_imx_setupxfer;
+       spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
+       spi_imx->bitbang.master->setup = spi_imx_setup;
+       spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
+       spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
-       init_completion(&mxc_spi->xfer_done);
+       init_completion(&spi_imx->xfer_done);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
@@ -549,58 +544,58 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
                goto out_gpio_free;
        }
 
-       mxc_spi->base = ioremap(res->start, resource_size(res));
-       if (!mxc_spi->base) {
+       spi_imx->base = ioremap(res->start, resource_size(res));
+       if (!spi_imx->base) {
                ret = -EINVAL;
                goto out_release_mem;
        }
 
-       mxc_spi->irq = platform_get_irq(pdev, 0);
-       if (!mxc_spi->irq) {
+       spi_imx->irq = platform_get_irq(pdev, 0);
+       if (!spi_imx->irq) {
                ret = -EINVAL;
                goto out_iounmap;
        }
 
-       ret = request_irq(mxc_spi->irq, mxc_spi_isr, 0, DRIVER_NAME, mxc_spi);
+       ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx);
        if (ret) {
-               dev_err(&pdev->dev, "can't get irq%d: %d\n", mxc_spi->irq, ret);
+               dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
                goto out_iounmap;
        }
 
        if (cpu_is_mx31() || cpu_is_mx35()) {
-               mxc_spi->intctrl = mx31_intctrl;
-               mxc_spi->config = mx31_config;
-               mxc_spi->trigger = mx31_trigger;
-               mxc_spi->rx_available = mx31_rx_available;
+               spi_imx->intctrl = mx31_intctrl;
+               spi_imx->config = mx31_config;
+               spi_imx->trigger = mx31_trigger;
+               spi_imx->rx_available = mx31_rx_available;
        } else  if (cpu_is_mx27() || cpu_is_mx21()) {
-               mxc_spi->intctrl = mx27_intctrl;
-               mxc_spi->config = mx27_config;
-               mxc_spi->trigger = mx27_trigger;
-               mxc_spi->rx_available = mx27_rx_available;
+               spi_imx->intctrl = mx27_intctrl;
+               spi_imx->config = mx27_config;
+               spi_imx->trigger = mx27_trigger;
+               spi_imx->rx_available = mx27_rx_available;
        } else if (cpu_is_mx1()) {
-               mxc_spi->intctrl = mx1_intctrl;
-               mxc_spi->config = mx1_config;
-               mxc_spi->trigger = mx1_trigger;
-               mxc_spi->rx_available = mx1_rx_available;
+               spi_imx->intctrl = mx1_intctrl;
+               spi_imx->config = mx1_config;
+               spi_imx->trigger = mx1_trigger;
+               spi_imx->rx_available = mx1_rx_available;
        } else
                BUG();
 
-       mxc_spi->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(mxc_spi->clk)) {
+       spi_imx->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(spi_imx->clk)) {
                dev_err(&pdev->dev, "unable to get clock\n");
-               ret = PTR_ERR(mxc_spi->clk);
+               ret = PTR_ERR(spi_imx->clk);
                goto out_free_irq;
        }
 
-       clk_enable(mxc_spi->clk);
-       mxc_spi->spi_clk = clk_get_rate(mxc_spi->clk);
+       clk_enable(spi_imx->clk);
+       spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
 
        if (!cpu_is_mx31() || !cpu_is_mx35())
-               writel(1, mxc_spi->base + MXC_RESET);
+               writel(1, spi_imx->base + MXC_RESET);
 
-       mxc_spi->intctrl(mxc_spi, 0);
+       spi_imx->intctrl(spi_imx, 0);
 
-       ret = spi_bitbang_start(&mxc_spi->bitbang);
+       ret = spi_bitbang_start(&spi_imx->bitbang);
        if (ret) {
                dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
                goto out_clk_put;
@@ -611,18 +606,18 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
        return ret;
 
 out_clk_put:
-       clk_disable(mxc_spi->clk);
-       clk_put(mxc_spi->clk);
+       clk_disable(spi_imx->clk);
+       clk_put(spi_imx->clk);
 out_free_irq:
-       free_irq(mxc_spi->irq, mxc_spi);
+       free_irq(spi_imx->irq, spi_imx);
 out_iounmap:
-       iounmap(mxc_spi->base);
+       iounmap(spi_imx->base);
 out_release_mem:
        release_mem_region(res->start, resource_size(res));
 out_gpio_free:
        for (i = 0; i < master->num_chipselect; i++)
-               if (mxc_spi->chipselect[i] >= 0)
-                       gpio_free(mxc_spi->chipselect[i]);
+               if (spi_imx->chipselect[i] >= 0)
+                       gpio_free(spi_imx->chipselect[i]);
 out_master_put:
        spi_master_put(master);
        kfree(master);
@@ -630,24 +625,24 @@ out_master_put:
        return ret;
 }
 
-static int __exit mxc_spi_remove(struct platform_device *pdev)
+static int __exit spi_imx_remove(struct platform_device *pdev)
 {
        struct spi_master *master = platform_get_drvdata(pdev);
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       struct mxc_spi_data *mxc_spi = spi_master_get_devdata(master);
+       struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
        int i;
 
-       spi_bitbang_stop(&mxc_spi->bitbang);
+       spi_bitbang_stop(&spi_imx->bitbang);
 
-       writel(0, mxc_spi->base + MXC_CSPICTRL);
-       clk_disable(mxc_spi->clk);
-       clk_put(mxc_spi->clk);
-       free_irq(mxc_spi->irq, mxc_spi);
-       iounmap(mxc_spi->base);
+       writel(0, spi_imx->base + MXC_CSPICTRL);
+       clk_disable(spi_imx->clk);
+       clk_put(spi_imx->clk);
+       free_irq(spi_imx->irq, spi_imx);
+       iounmap(spi_imx->base);
 
        for (i = 0; i < master->num_chipselect; i++)
-               if (mxc_spi->chipselect[i] >= 0)
-                       gpio_free(mxc_spi->chipselect[i]);
+               if (spi_imx->chipselect[i] >= 0)
+                       gpio_free(spi_imx->chipselect[i]);
 
        spi_master_put(master);
 
@@ -658,27 +653,27 @@ static int __exit mxc_spi_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct platform_driver mxc_spi_driver = {
+static struct platform_driver spi_imx_driver = {
        .driver = {
                   .name = DRIVER_NAME,
                   .owner = THIS_MODULE,
                   },
-       .probe = mxc_spi_probe,
-       .remove = __exit_p(mxc_spi_remove),
+       .probe = spi_imx_probe,
+       .remove = __exit_p(spi_imx_remove),
 };
 
-static int __init mxc_spi_init(void)
+static int __init spi_imx_init(void)
 {
-       return platform_driver_register(&mxc_spi_driver);
+       return platform_driver_register(&spi_imx_driver);
 }
 
-static void __exit mxc_spi_exit(void)
+static void __exit spi_imx_exit(void)
 {
-       platform_driver_unregister(&mxc_spi_driver);
+       platform_driver_unregister(&spi_imx_driver);
 }
 
-module_init(mxc_spi_init);
-module_exit(mxc_spi_exit);
+module_init(spi_imx_init);
+module_exit(spi_imx_exit);
 
 MODULE_DESCRIPTION("SPI Master Controller driver");
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
index f921bd1109e1c1ff9a26e851e19a484860b19c08..5d23983f02fc7a70f69a1989f4bcccac46bba6a8 100644 (file)
@@ -537,7 +537,7 @@ static int spidev_release(struct inode *inode, struct file *filp)
        return status;
 }
 
-static struct file_operations spidev_fops = {
+static const struct file_operations spidev_fops = {
        .owner =        THIS_MODULE,
        /* REVISIT switch to aio primitives, so that userspace
         * gets more complete API coverage.  It'll simplify things
index ac8577358ba096126b38106e25c58d1268c25c37..c24e4e0367a276ce787140154156b25ac73707bb 100644 (file)
@@ -102,7 +102,7 @@ static int dst_request(struct request_queue *q, struct bio *bio)
        struct dst_node *n = q->queuedata;
        int err = -EIO;
 
-       if (bio_empty_barrier(bio) && !q->prepare_discard_fn) {
+       if (bio_empty_barrier(bio) && !blk_queue_discard(q)) {
                /*
                 * This is a dirty^Wnice hack, but if we complete this
                 * operation with -EOPNOTSUPP like intended, XFS
@@ -847,7 +847,7 @@ static dst_command_func dst_commands[] = {
 /*
  * Configuration parser.
  */
-static void cn_dst_callback(struct cn_msg *msg)
+static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
        struct dst_ctl *ctl;
        int err;
@@ -855,6 +855,11 @@ static void cn_dst_callback(struct cn_msg *msg)
        struct dst_node *n = NULL, *tmp;
        unsigned int hash;
 
+       if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto out;
+       }
+
        if (msg->len < sizeof(struct dst_ctl)) {
                err = -EBADMSG;
                goto out;
index ea8a5efc19bca41120bd4e5e4d2789b9afb11c36..fc2107f4c049b4b88905bbe06ee06aa7f1c45f45 100644 (file)
@@ -239,10 +239,6 @@ static int __devexit tsl2561_remove(struct i2c_client *client)
        return tsl2561_powerdown(client);
 }
 
-static unsigned short normal_i2c[] = { 0x29, 0x39, 0x49, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
 static const struct i2c_device_id tsl2561_id[] = {
        { "tsl2561", 0 },
        { }
index 90f962ee5fd8865a17622481a6a0d9c4e72d9966..5d04bf5b021a8c24b9534339ec194bc3f5659e05 100644 (file)
@@ -527,10 +527,13 @@ out_unlock:
        return err;
 }
 
-static void pohmelfs_cn_callback(struct cn_msg *msg)
+static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
        int err;
 
+       if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+               return;
+
        switch (msg->flags) {
                case POHMELFS_FLAGS_ADD:
                case POHMELFS_FLAGS_DEL:
index 333ee02e7b2b2a7bcf94baf5a2af0245185c0da7..864f0ba6a344ada55735e0f06d02f6033edb1cdd 100644 (file)
@@ -993,7 +993,7 @@ skip_io_on_zombie:
        return retval;
 }
 
-static struct file_operations fops = {
+static const struct file_operations fops = {
        .owner          = THIS_MODULE,
        .read           = usbtmc_read,
        .write          = usbtmc_write,
index c44367fea185822919231f87e16fcf9a6d994461..bf0f6520c6df3946b91f2a40f9b1a6c786918f6d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/wait.h>
 #include <linux/compiler.h>
 #include <asm/uaccess.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
index 29500154d00c57d5f74a299fcfaa90610fecad03..2d867fd22413f9ab0a9af24bacc9aa306cf6df85 100644 (file)
@@ -875,7 +875,7 @@ printer_ioctl(struct file *fd, unsigned int code, unsigned long arg)
 }
 
 /* used after endpoint configuration */
-static struct file_operations printer_io_operations = {
+static const struct file_operations printer_io_operations = {
        .owner =        THIS_MODULE,
        .open =         printer_open,
        .read =         printer_read,
index cf2d45946c57c67e783a9eb44238dda29dd9b771..2273c815941fe1cf4a886c19831bc63cb871d0f9 100644 (file)
@@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode, struct file *file)
        return single_open(file, pzl_print, inode->i_private);
 }
 
-static struct file_operations di_fops = {
+static const struct file_operations di_fops = {
        .open    = di_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
@@ -142,7 +142,7 @@ static struct file_operations di_fops = {
        .owner   = THIS_MODULE,
 };
 
-static struct file_operations asl_fops = {
+static const struct file_operations asl_fops = {
        .open    = asl_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
@@ -150,7 +150,7 @@ static struct file_operations asl_fops = {
        .owner   = THIS_MODULE,
 };
 
-static struct file_operations pzl_fops = {
+static const struct file_operations pzl_fops = {
        .open    = pzl_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
index d645f3899fe1c52a09599e90d241006337591381..32d0199d0c3220a1c037856e5143bbd641b2cf38 100644 (file)
@@ -429,8 +429,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
        return read_count;
 }
 
-static struct
-file_operations usb_rio_fops = {
+static const struct file_operations usb_rio_fops = {
        .owner =        THIS_MODULE,
        .read =         read_rio,
        .write =        write_rio,
index 4a42993700c1aaadc3dbe55dd75c8d3738f04aff..2eecec0c13c9bf1bba5013865fdfdd799c175af0 100644 (file)
@@ -205,7 +205,7 @@ static ssize_t command_write(struct file *file, const char __user *buf,
        return ret < 0 ? ret : len;
 }
 
-static struct file_operations command_fops = {
+static const struct file_operations command_fops = {
        .open   = command_open,
        .write  = command_write,
        .read   = NULL,
@@ -255,7 +255,7 @@ static int reservations_open(struct inode *inode, struct file *file)
        return single_open(file, reservations_print, inode->i_private);
 }
 
-static struct file_operations reservations_fops = {
+static const struct file_operations reservations_fops = {
        .open    = reservations_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
@@ -283,7 +283,7 @@ static int drp_avail_open(struct inode *inode, struct file *file)
        return single_open(file, drp_avail_print, inode->i_private);
 }
 
-static struct file_operations drp_avail_fops = {
+static const struct file_operations drp_avail_fops = {
        .open    = drp_avail_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
index e98baf6916b88fd9c8d6f25b1161c5ce099a4d99..e35232a1857199926882234faf795e61cd755cc7 100644 (file)
@@ -67,11 +67,14 @@ static DEFINE_MUTEX(uvfb_lock);
  * find the kernel part of the task struct, copy the registers and
  * the buffer contents and then complete the task.
  */
-static void uvesafb_cn_callback(struct cn_msg *msg)
+static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
        struct uvesafb_task *utask;
        struct uvesafb_ktask *task;
 
+       if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+               return;
+
        if (msg->seq >= UVESAFB_TASKS_MAX)
                return;
 
index df52cb355f7dd10b093bff43796c283c62c9bb26..406caa6a71cbb1bc40d54e44f957079a1b4f1b06 100644 (file)
 #include "../w1.h"
 #include "../w1_int.h"
 
-/**
- * Address is selected using 2 pins, resulting in 4 possible addresses.
- *  0x18, 0x19, 0x1a, 0x1b
- * However, the chip cannot be detected without doing an i2c write,
- * so use the force module parameter.
- */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/**
- * Insmod parameters
- */
-I2C_CLIENT_INSMOD_1(ds2482);
-
 /**
  * The DS2482 registers - there are 3 registers that are addressed by a read
  * pointer. The read pointer is set by the last command executed.
@@ -96,8 +83,6 @@ static const u8 ds2482_chan_rd[8] =
 
 static int ds2482_probe(struct i2c_client *client,
                        const struct i2c_device_id *id);
-static int ds2482_detect(struct i2c_client *client, int kind,
-                        struct i2c_board_info *info);
 static int ds2482_remove(struct i2c_client *client);
 
 
@@ -117,8 +102,6 @@ static struct i2c_driver ds2482_driver = {
        .probe          = ds2482_probe,
        .remove         = ds2482_remove,
        .id_table       = ds2482_id,
-       .detect         = ds2482_detect,
-       .address_data   = &addr_data,
 };
 
 /*
@@ -425,19 +408,6 @@ static u8 ds2482_w1_reset_bus(void *data)
 }
 
 
-static int ds2482_detect(struct i2c_client *client, int kind,
-                        struct i2c_board_info *info)
-{
-       if (!i2c_check_functionality(client->adapter,
-                                    I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
-                                    I2C_FUNC_SMBUS_BYTE))
-               return -ENODEV;
-
-       strlcpy(info->type, "ds2482", I2C_NAME_SIZE);
-
-       return 0;
-}
-
 static int ds2482_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
@@ -446,6 +416,11 @@ static int ds2482_probe(struct i2c_client *client,
        int temp1;
        int idx;
 
+       if (!i2c_check_functionality(client->adapter,
+                                    I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+                                    I2C_FUNC_SMBUS_BYTE))
+               return -ENODEV;
+
        if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
                err = -ENOMEM;
                goto exit;
index 52ccb3d3a96378aee4fb4f21cd984f9bb43a2925..45c126fea31dcdad608a666964d316214386e1fb 100644 (file)
@@ -306,7 +306,7 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
        return error;
 }
 
-static void w1_cn_callback(struct cn_msg *msg)
+static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
        struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1);
        struct w1_netlink_cmd *cmd;
index a9592d981b107de1ca1447d1972cd4e12a3252b4..6c4269b836b7f22ddadc2ca39d5531e467cffc95 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/mount.h>
 #include <linux/pagemap.h>
diff --git a/fs/afs/cache.h b/fs/afs/cache.h
deleted file mode 100644 (file)
index 5c4f6b4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* AFS local cache management interface
- *
- * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/fscache.h>
index 106be66dafd2ca7edc9388dac55d8a218ab52dc6..6ece2a13bf711fd477098d18b60a34a4861fea59 100644 (file)
 #include <linux/key.h>
 #include <linux/workqueue.h>
 #include <linux/sched.h>
+#include <linux/fscache.h>
 
 #include "afs.h"
 #include "afs_vl.h"
-#include "cache.h"
 
 #define AFS_CELL_MAX_ADDRS 15
 
index d11c51fc2a3fd144ac8de14702207078743cd353..2ca7a7cafdbf9359ccf1a706a5fdda11f3fe157e 100644 (file)
@@ -8,8 +8,10 @@
  *
  */
 
+#include <linux/cred.h>
 #include <linux/file.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
index 76738005c8e8af43c3b084a48d4f752e36e2186d..402cb84a92a1dbd538dc4eead68cd474bea3389b 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -249,6 +249,7 @@ void bio_free(struct bio *bio, struct bio_set *bs)
 
        mempool_free(p, bs->bio_pool);
 }
+EXPORT_SYMBOL(bio_free);
 
 void bio_init(struct bio *bio)
 {
@@ -257,6 +258,7 @@ void bio_init(struct bio *bio)
        bio->bi_comp_cpu = -1;
        atomic_set(&bio->bi_cnt, 1);
 }
+EXPORT_SYMBOL(bio_init);
 
 /**
  * bio_alloc_bioset - allocate a bio for I/O
@@ -311,6 +313,7 @@ err_free:
        mempool_free(p, bs->bio_pool);
        return NULL;
 }
+EXPORT_SYMBOL(bio_alloc_bioset);
 
 static void bio_fs_destructor(struct bio *bio)
 {
@@ -337,6 +340,7 @@ struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
 
        return bio;
 }
+EXPORT_SYMBOL(bio_alloc);
 
 static void bio_kmalloc_destructor(struct bio *bio)
 {
@@ -380,6 +384,7 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
 
        return bio;
 }
+EXPORT_SYMBOL(bio_kmalloc);
 
 void zero_fill_bio(struct bio *bio)
 {
@@ -416,6 +421,7 @@ void bio_put(struct bio *bio)
                bio->bi_destructor(bio);
        }
 }
+EXPORT_SYMBOL(bio_put);
 
 inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
 {
@@ -424,6 +430,7 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
 
        return bio->bi_phys_segments;
 }
+EXPORT_SYMBOL(bio_phys_segments);
 
 /**
  *     __bio_clone     -       clone a bio
@@ -451,6 +458,7 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
        bio->bi_size = bio_src->bi_size;
        bio->bi_idx = bio_src->bi_idx;
 }
+EXPORT_SYMBOL(__bio_clone);
 
 /**
  *     bio_clone       -       clone a bio
@@ -482,6 +490,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
 
        return b;
 }
+EXPORT_SYMBOL(bio_clone);
 
 /**
  *     bio_get_nr_vecs         - return approx number of vecs
@@ -505,6 +514,7 @@ int bio_get_nr_vecs(struct block_device *bdev)
 
        return nr_pages;
 }
+EXPORT_SYMBOL(bio_get_nr_vecs);
 
 static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                          *page, unsigned int len, unsigned int offset,
@@ -635,6 +645,7 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page,
        return __bio_add_page(q, bio, page, len, offset,
                              queue_max_hw_sectors(q));
 }
+EXPORT_SYMBOL(bio_add_pc_page);
 
 /**
  *     bio_add_page    -       attempt to add page to bio
@@ -655,6 +666,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
        struct request_queue *q = bdev_get_queue(bio->bi_bdev);
        return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q));
 }
+EXPORT_SYMBOL(bio_add_page);
 
 struct bio_map_data {
        struct bio_vec *iovecs;
@@ -776,6 +788,7 @@ int bio_uncopy_user(struct bio *bio)
        bio_put(bio);
        return ret;
 }
+EXPORT_SYMBOL(bio_uncopy_user);
 
 /**
  *     bio_copy_user_iov       -       copy user data to bio
@@ -920,6 +933,7 @@ struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data,
 
        return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask);
 }
+EXPORT_SYMBOL(bio_copy_user);
 
 static struct bio *__bio_map_user_iov(struct request_queue *q,
                                      struct block_device *bdev,
@@ -1050,6 +1064,7 @@ struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev,
 
        return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask);
 }
+EXPORT_SYMBOL(bio_map_user);
 
 /**
  *     bio_map_user_iov - map user sg_iovec table into bio
@@ -1117,13 +1132,13 @@ void bio_unmap_user(struct bio *bio)
        __bio_unmap_user(bio);
        bio_put(bio);
 }
+EXPORT_SYMBOL(bio_unmap_user);
 
 static void bio_map_kern_endio(struct bio *bio, int err)
 {
        bio_put(bio);
 }
 
-
 static struct bio *__bio_map_kern(struct request_queue *q, void *data,
                                  unsigned int len, gfp_t gfp_mask)
 {
@@ -1189,6 +1204,7 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
        bio_put(bio);
        return ERR_PTR(-EINVAL);
 }
+EXPORT_SYMBOL(bio_map_kern);
 
 static void bio_copy_kern_endio(struct bio *bio, int err)
 {
@@ -1250,6 +1266,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
 
        return bio;
 }
+EXPORT_SYMBOL(bio_copy_kern);
 
 /*
  * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions
@@ -1400,6 +1417,7 @@ void bio_endio(struct bio *bio, int error)
        if (bio->bi_end_io)
                bio->bi_end_io(bio, error);
 }
+EXPORT_SYMBOL(bio_endio);
 
 void bio_pair_release(struct bio_pair *bp)
 {
@@ -1410,6 +1428,7 @@ void bio_pair_release(struct bio_pair *bp)
                mempool_free(bp, bp->bio2.bi_private);
        }
 }
+EXPORT_SYMBOL(bio_pair_release);
 
 static void bio_pair_end_1(struct bio *bi, int err)
 {
@@ -1477,6 +1496,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
 
        return bp;
 }
+EXPORT_SYMBOL(bio_split);
 
 /**
  *      bio_sector_offset - Find hardware sector offset in bio
@@ -1547,6 +1567,7 @@ void bioset_free(struct bio_set *bs)
 
        kfree(bs);
 }
+EXPORT_SYMBOL(bioset_free);
 
 /**
  * bioset_create  - Create a bio_set
@@ -1592,6 +1613,7 @@ bad:
        bioset_free(bs);
        return NULL;
 }
+EXPORT_SYMBOL(bioset_create);
 
 static void __init biovec_init_slabs(void)
 {
@@ -1636,29 +1658,4 @@ static int __init init_bio(void)
 
        return 0;
 }
-
 subsys_initcall(init_bio);
-
-EXPORT_SYMBOL(bio_alloc);
-EXPORT_SYMBOL(bio_kmalloc);
-EXPORT_SYMBOL(bio_put);
-EXPORT_SYMBOL(bio_free);
-EXPORT_SYMBOL(bio_endio);
-EXPORT_SYMBOL(bio_init);
-EXPORT_SYMBOL(__bio_clone);
-EXPORT_SYMBOL(bio_clone);
-EXPORT_SYMBOL(bio_phys_segments);
-EXPORT_SYMBOL(bio_add_page);
-EXPORT_SYMBOL(bio_add_pc_page);
-EXPORT_SYMBOL(bio_get_nr_vecs);
-EXPORT_SYMBOL(bio_map_user);
-EXPORT_SYMBOL(bio_unmap_user);
-EXPORT_SYMBOL(bio_map_kern);
-EXPORT_SYMBOL(bio_copy_kern);
-EXPORT_SYMBOL(bio_pair_release);
-EXPORT_SYMBOL(bio_split);
-EXPORT_SYMBOL(bio_copy_user);
-EXPORT_SYMBOL(bio_uncopy_user);
-EXPORT_SYMBOL(bioset_create);
-EXPORT_SYMBOL(bioset_free);
-EXPORT_SYMBOL(bio_alloc_bioset);
index f128427b995b108382fde3b3fea6d0582f841666..69b355ae7f49139d928ec398807b9f0bc908c307 100644 (file)
@@ -27,7 +27,7 @@
 #include "btrfs_inode.h"
 #include "xattr.h"
 
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_BTRFS_POSIX_ACL
 
 static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
 {
@@ -313,7 +313,7 @@ struct xattr_handler btrfs_xattr_acl_access_handler = {
        .set    = btrfs_xattr_acl_access_set,
 };
 
-#else /* CONFIG_FS_POSIX_ACL */
+#else /* CONFIG_BTRFS_POSIX_ACL */
 
 int btrfs_acl_chmod(struct inode *inode)
 {
@@ -325,4 +325,4 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
        return 0;
 }
 
-#endif /* CONFIG_FS_POSIX_ACL */
+#endif /* CONFIG_BTRFS_POSIX_ACL */
index 82ee56bba29966e5dee552d764bb0e60fbc8bca9..a54d354cefcb71894a89975fae23ff94a9b939ad 100644 (file)
@@ -127,6 +127,14 @@ struct btrfs_inode {
         */
        u64 last_unlink_trans;
 
+       /*
+        * These two counters are for delalloc metadata reservations.  We keep
+        * track of how many extents we've accounted for vs how many extents we
+        * have.
+        */
+       int delalloc_reserved_extents;
+       int delalloc_extents;
+
        /*
         * ordered_data_close is set by truncate when a file that used
         * to have good data has been truncated to zero.  When it is set
index 80599b4e42bd350f5e6b7a094c3711a3dd32e8a8..dd8ced9814c4a5d0bc35e9bd8ef12cd8745382b9 100644 (file)
@@ -675,18 +675,19 @@ struct btrfs_space_info {
                                   current allocations */
        u64 bytes_readonly;     /* total bytes that are read only */
        u64 bytes_super;        /* total bytes reserved for the super blocks */
-
-       /* delalloc accounting */
-       u64 bytes_delalloc;     /* number of bytes reserved for allocation,
-                                  this space is not necessarily reserved yet
-                                  by the allocator */
+       u64 bytes_root;         /* the number of bytes needed to commit a
+                                  transaction */
        u64 bytes_may_use;      /* number of bytes that may be used for
-                                  delalloc */
+                                  delalloc/allocations */
+       u64 bytes_delalloc;     /* number of bytes currently reserved for
+                                  delayed allocation */
 
        int full;               /* indicates that we cannot allocate any more
                                   chunks for this space */
        int force_alloc;        /* set if we need to force a chunk alloc for
                                   this space */
+       int force_delalloc;     /* make people start doing filemap_flush until
+                                  we're under a threshold */
 
        struct list_head list;
 
@@ -695,6 +696,9 @@ struct btrfs_space_info {
        spinlock_t lock;
        struct rw_semaphore groups_sem;
        atomic_t caching_threads;
+
+       int allocating_chunk;
+       wait_queue_head_t wait;
 };
 
 /*
@@ -2022,7 +2026,12 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
 void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);
 void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
 
-int btrfs_check_metadata_free_space(struct btrfs_root *root);
+int btrfs_reserve_metadata_space(struct btrfs_root *root, int num_items);
+int btrfs_unreserve_metadata_space(struct btrfs_root *root, int num_items);
+int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
+                                         struct inode *inode, int num_items);
+int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
+                                       struct inode *inode, int num_items);
 int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
                                u64 bytes);
 void btrfs_free_reserved_data_space(struct btrfs_root *root,
@@ -2326,7 +2335,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync);
 int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                            int skip_pinned);
 int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
-extern struct file_operations btrfs_file_operations;
+extern const struct file_operations btrfs_file_operations;
 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
                       struct btrfs_root *root, struct inode *inode,
                       u64 start, u64 end, u64 locked_end,
@@ -2357,7 +2366,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options);
 int btrfs_sync_fs(struct super_block *sb, int wait);
 
 /* acl.c */
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_BTRFS_POSIX_ACL
 int btrfs_check_acl(struct inode *inode, int mask);
 #else
 #define btrfs_check_acl NULL
index 644e796fd643e045ca0b0ed057743b7eb5e88438..af0435f79fa605e96f0461efd496599c576eb7e2 100644 (file)
@@ -822,14 +822,14 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
 
 int btrfs_write_tree_block(struct extent_buffer *buf)
 {
-       return btrfs_fdatawrite_range(buf->first_page->mapping, buf->start,
-                                     buf->start + buf->len - 1, WB_SYNC_ALL);
+       return filemap_fdatawrite_range(buf->first_page->mapping, buf->start,
+                                       buf->start + buf->len - 1);
 }
 
 int btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
 {
-       return btrfs_wait_on_page_writeback_range(buf->first_page->mapping,
-                                 buf->start, buf->start + buf->len - 1);
+       return filemap_fdatawait_range(buf->first_page->mapping,
+                                      buf->start, buf->start + buf->len - 1);
 }
 
 struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
@@ -1630,7 +1630,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        fs_info->sb = sb;
        fs_info->max_extent = (u64)-1;
        fs_info->max_inline = 8192 * 1024;
-       fs_info->metadata_ratio = 8;
+       fs_info->metadata_ratio = 0;
 
        fs_info->thread_pool_size = min_t(unsigned long,
                                          num_online_cpus() + 2, 8);
index 993f93ff7ba695c97b490f5e2d5d6d3b5939980c..359a754c782cd8338f0a1bf0d456306e3240c32c 100644 (file)
@@ -68,6 +68,8 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
                          struct extent_buffer **must_clean);
 static int find_next_key(struct btrfs_path *path, int level,
                         struct btrfs_key *key);
+static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
+                           int dump_block_groups);
 
 static noinline int
 block_group_cache_done(struct btrfs_block_group_cache *cache)
@@ -2765,67 +2767,346 @@ void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode)
                                                       alloc_target);
 }
 
+static u64 calculate_bytes_needed(struct btrfs_root *root, int num_items)
+{
+       u64 num_bytes;
+       int level;
+
+       level = BTRFS_MAX_LEVEL - 2;
+       /*
+        * NOTE: these calculations are absolutely the worst possible case.
+        * This assumes that _every_ item we insert will require a new leaf, and
+        * that the tree has grown to its maximum level size.
+        */
+
+       /*
+        * for every item we insert we could insert both an extent item and a
+        * extent ref item.  Then for ever item we insert, we will need to cow
+        * both the original leaf, plus the leaf to the left and right of it.
+        *
+        * Unless we are talking about the extent root, then we just want the
+        * number of items * 2, since we just need the extent item plus its ref.
+        */
+       if (root == root->fs_info->extent_root)
+               num_bytes = num_items * 2;
+       else
+               num_bytes = (num_items + (2 * num_items)) * 3;
+
+       /*
+        * num_bytes is total number of leaves we could need times the leaf
+        * size, and then for every leaf we could end up cow'ing 2 nodes per
+        * level, down to the leaf level.
+        */
+       num_bytes = (num_bytes * root->leafsize) +
+               (num_bytes * (level * 2)) * root->nodesize;
+
+       return num_bytes;
+}
+
 /*
- * for now this just makes sure we have at least 5% of our metadata space free
- * for use.
+ * Unreserve metadata space for delalloc.  If we have less reserved credits than
+ * we have extents, this function does nothing.
  */
-int btrfs_check_metadata_free_space(struct btrfs_root *root)
+int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
+                                         struct inode *inode, int num_items)
 {
        struct btrfs_fs_info *info = root->fs_info;
        struct btrfs_space_info *meta_sinfo;
-       u64 alloc_target, thresh;
-       int committed = 0, ret;
+       u64 num_bytes;
+       u64 alloc_target;
+       bool bug = false;
 
        /* get the space info for where the metadata will live */
        alloc_target = btrfs_get_alloc_profile(root, 0);
        meta_sinfo = __find_space_info(info, alloc_target);
-       if (!meta_sinfo)
-               goto alloc;
 
-again:
+       num_bytes = calculate_bytes_needed(root->fs_info->extent_root,
+                                          num_items);
+
        spin_lock(&meta_sinfo->lock);
-       if (!meta_sinfo->full)
-               thresh = meta_sinfo->total_bytes * 80;
-       else
-               thresh = meta_sinfo->total_bytes * 95;
+       if (BTRFS_I(inode)->delalloc_reserved_extents <=
+           BTRFS_I(inode)->delalloc_extents) {
+               spin_unlock(&meta_sinfo->lock);
+               return 0;
+       }
+
+       BTRFS_I(inode)->delalloc_reserved_extents--;
+       BUG_ON(BTRFS_I(inode)->delalloc_reserved_extents < 0);
+
+       if (meta_sinfo->bytes_delalloc < num_bytes) {
+               bug = true;
+               meta_sinfo->bytes_delalloc = 0;
+       } else {
+               meta_sinfo->bytes_delalloc -= num_bytes;
+       }
+       spin_unlock(&meta_sinfo->lock);
 
+       BUG_ON(bug);
+
+       return 0;
+}
+
+static void check_force_delalloc(struct btrfs_space_info *meta_sinfo)
+{
+       u64 thresh;
+
+       thresh = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
+               meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
+               meta_sinfo->bytes_super + meta_sinfo->bytes_root +
+               meta_sinfo->bytes_may_use;
+
+       thresh = meta_sinfo->total_bytes - thresh;
+       thresh *= 80;
        do_div(thresh, 100);
+       if (thresh <= meta_sinfo->bytes_delalloc)
+               meta_sinfo->force_delalloc = 1;
+       else
+               meta_sinfo->force_delalloc = 0;
+}
 
-       if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
-           meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
-           meta_sinfo->bytes_super > thresh) {
-               struct btrfs_trans_handle *trans;
-               if (!meta_sinfo->full) {
-                       meta_sinfo->force_alloc = 1;
+static int maybe_allocate_chunk(struct btrfs_root *root,
+                                struct btrfs_space_info *info)
+{
+       struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+       struct btrfs_trans_handle *trans;
+       bool wait = false;
+       int ret = 0;
+       u64 min_metadata;
+       u64 free_space;
+
+       free_space = btrfs_super_total_bytes(disk_super);
+       /*
+        * we allow the metadata to grow to a max of either 5gb or 5% of the
+        * space in the volume.
+        */
+       min_metadata = min((u64)5 * 1024 * 1024 * 1024,
+                            div64_u64(free_space * 5, 100));
+       if (info->total_bytes >= min_metadata) {
+               spin_unlock(&info->lock);
+               return 0;
+       }
+
+       if (info->full) {
+               spin_unlock(&info->lock);
+               return 0;
+       }
+
+       if (!info->allocating_chunk) {
+               info->force_alloc = 1;
+               info->allocating_chunk = 1;
+               init_waitqueue_head(&info->wait);
+       } else {
+               wait = true;
+       }
+
+       spin_unlock(&info->lock);
+
+       if (wait) {
+               wait_event(info->wait,
+                          !info->allocating_chunk);
+               return 1;
+       }
+
+       trans = btrfs_start_transaction(root, 1);
+       if (!trans) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = do_chunk_alloc(trans, root->fs_info->extent_root,
+                            4096 + 2 * 1024 * 1024,
+                            info->flags, 0);
+       btrfs_end_transaction(trans, root);
+       if (ret)
+               goto out;
+out:
+       spin_lock(&info->lock);
+       info->allocating_chunk = 0;
+       spin_unlock(&info->lock);
+       wake_up(&info->wait);
+
+       if (ret)
+               return 0;
+       return 1;
+}
+
+/*
+ * Reserve metadata space for delalloc.
+ */
+int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
+                                       struct inode *inode, int num_items)
+{
+       struct btrfs_fs_info *info = root->fs_info;
+       struct btrfs_space_info *meta_sinfo;
+       u64 num_bytes;
+       u64 used;
+       u64 alloc_target;
+       int flushed = 0;
+       int force_delalloc;
+
+       /* get the space info for where the metadata will live */
+       alloc_target = btrfs_get_alloc_profile(root, 0);
+       meta_sinfo = __find_space_info(info, alloc_target);
+
+       num_bytes = calculate_bytes_needed(root->fs_info->extent_root,
+                                          num_items);
+again:
+       spin_lock(&meta_sinfo->lock);
+
+       force_delalloc = meta_sinfo->force_delalloc;
+
+       if (unlikely(!meta_sinfo->bytes_root))
+               meta_sinfo->bytes_root = calculate_bytes_needed(root, 6);
+
+       if (!flushed)
+               meta_sinfo->bytes_delalloc += num_bytes;
+
+       used = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
+               meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
+               meta_sinfo->bytes_super + meta_sinfo->bytes_root +
+               meta_sinfo->bytes_may_use + meta_sinfo->bytes_delalloc;
+
+       if (used > meta_sinfo->total_bytes) {
+               flushed++;
+
+               if (flushed == 1) {
+                       if (maybe_allocate_chunk(root, meta_sinfo))
+                               goto again;
+                       flushed++;
+               } else {
                        spin_unlock(&meta_sinfo->lock);
-alloc:
-                       trans = btrfs_start_transaction(root, 1);
-                       if (!trans)
-                               return -ENOMEM;
+               }
 
-                       ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-                                            2 * 1024 * 1024, alloc_target, 0);
-                       btrfs_end_transaction(trans, root);
-                       if (!meta_sinfo) {
-                               meta_sinfo = __find_space_info(info,
-                                                              alloc_target);
-                       }
+               if (flushed == 2) {
+                       filemap_flush(inode->i_mapping);
+                       goto again;
+               } else if (flushed == 3) {
+                       btrfs_start_delalloc_inodes(root);
+                       btrfs_wait_ordered_extents(root, 0);
                        goto again;
                }
+               spin_lock(&meta_sinfo->lock);
+               meta_sinfo->bytes_delalloc -= num_bytes;
                spin_unlock(&meta_sinfo->lock);
+               printk(KERN_ERR "enospc, has %d, reserved %d\n",
+                      BTRFS_I(inode)->delalloc_extents,
+                      BTRFS_I(inode)->delalloc_reserved_extents);
+               dump_space_info(meta_sinfo, 0, 0);
+               return -ENOSPC;
+       }
 
-               if (!committed) {
-                       committed = 1;
-                       trans = btrfs_join_transaction(root, 1);
-                       if (!trans)
-                               return -ENOMEM;
-                       ret = btrfs_commit_transaction(trans, root);
-                       if (ret)
-                               return ret;
+       BTRFS_I(inode)->delalloc_reserved_extents++;
+       check_force_delalloc(meta_sinfo);
+       spin_unlock(&meta_sinfo->lock);
+
+       if (!flushed && force_delalloc)
+               filemap_flush(inode->i_mapping);
+
+       return 0;
+}
+
+/*
+ * unreserve num_items number of items worth of metadata space.  This needs to
+ * be paired with btrfs_reserve_metadata_space.
+ *
+ * NOTE: if you have the option, run this _AFTER_ you do a
+ * btrfs_end_transaction, since btrfs_end_transaction will run delayed ref
+ * oprations which will result in more used metadata, so we want to make sure we
+ * can do that without issue.
+ */
+int btrfs_unreserve_metadata_space(struct btrfs_root *root, int num_items)
+{
+       struct btrfs_fs_info *info = root->fs_info;
+       struct btrfs_space_info *meta_sinfo;
+       u64 num_bytes;
+       u64 alloc_target;
+       bool bug = false;
+
+       /* get the space info for where the metadata will live */
+       alloc_target = btrfs_get_alloc_profile(root, 0);
+       meta_sinfo = __find_space_info(info, alloc_target);
+
+       num_bytes = calculate_bytes_needed(root, num_items);
+
+       spin_lock(&meta_sinfo->lock);
+       if (meta_sinfo->bytes_may_use < num_bytes) {
+               bug = true;
+               meta_sinfo->bytes_may_use = 0;
+       } else {
+               meta_sinfo->bytes_may_use -= num_bytes;
+       }
+       spin_unlock(&meta_sinfo->lock);
+
+       BUG_ON(bug);
+
+       return 0;
+}
+
+/*
+ * Reserve some metadata space for use.  We'll calculate the worste case number
+ * of bytes that would be needed to modify num_items number of items.  If we
+ * have space, fantastic, if not, you get -ENOSPC.  Please call
+ * btrfs_unreserve_metadata_space when you are done for the _SAME_ number of
+ * items you reserved, since whatever metadata you needed should have already
+ * been allocated.
+ *
+ * This will commit the transaction to make more space if we don't have enough
+ * metadata space.  THe only time we don't do this is if we're reserving space
+ * inside of a transaction, then we will just return -ENOSPC and it is the
+ * callers responsibility to handle it properly.
+ */
+int btrfs_reserve_metadata_space(struct btrfs_root *root, int num_items)
+{
+       struct btrfs_fs_info *info = root->fs_info;
+       struct btrfs_space_info *meta_sinfo;
+       u64 num_bytes;
+       u64 used;
+       u64 alloc_target;
+       int retries = 0;
+
+       /* get the space info for where the metadata will live */
+       alloc_target = btrfs_get_alloc_profile(root, 0);
+       meta_sinfo = __find_space_info(info, alloc_target);
+
+       num_bytes = calculate_bytes_needed(root, num_items);
+again:
+       spin_lock(&meta_sinfo->lock);
+
+       if (unlikely(!meta_sinfo->bytes_root))
+               meta_sinfo->bytes_root = calculate_bytes_needed(root, 6);
+
+       if (!retries)
+               meta_sinfo->bytes_may_use += num_bytes;
+
+       used = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
+               meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
+               meta_sinfo->bytes_super + meta_sinfo->bytes_root +
+               meta_sinfo->bytes_may_use + meta_sinfo->bytes_delalloc;
+
+       if (used > meta_sinfo->total_bytes) {
+               retries++;
+               if (retries == 1) {
+                       if (maybe_allocate_chunk(root, meta_sinfo))
+                               goto again;
+                       retries++;
+               } else {
+                       spin_unlock(&meta_sinfo->lock);
+               }
+
+               if (retries == 2) {
+                       btrfs_start_delalloc_inodes(root);
+                       btrfs_wait_ordered_extents(root, 0);
                        goto again;
                }
+               spin_lock(&meta_sinfo->lock);
+               meta_sinfo->bytes_may_use -= num_bytes;
+               spin_unlock(&meta_sinfo->lock);
+
+               dump_space_info(meta_sinfo, 0, 0);
                return -ENOSPC;
        }
+
+       check_force_delalloc(meta_sinfo);
        spin_unlock(&meta_sinfo->lock);
 
        return 0;
@@ -2888,7 +3169,7 @@ alloc:
                spin_unlock(&data_sinfo->lock);
 
                /* commit the current transaction and try again */
-               if (!committed) {
+               if (!committed && !root->fs_info->open_ioctl_trans) {
                        committed = 1;
                        trans = btrfs_join_transaction(root, 1);
                        if (!trans)
@@ -2916,7 +3197,7 @@ alloc:
        BTRFS_I(inode)->reserved_bytes += bytes;
        spin_unlock(&data_sinfo->lock);
 
-       return btrfs_check_metadata_free_space(root);
+       return 0;
 }
 
 /*
@@ -3015,17 +3296,15 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
        BUG_ON(!space_info);
 
        spin_lock(&space_info->lock);
-       if (space_info->force_alloc) {
+       if (space_info->force_alloc)
                force = 1;
-               space_info->force_alloc = 0;
-       }
        if (space_info->full) {
                spin_unlock(&space_info->lock);
                goto out;
        }
 
        thresh = space_info->total_bytes - space_info->bytes_readonly;
-       thresh = div_factor(thresh, 6);
+       thresh = div_factor(thresh, 8);
        if (!force &&
           (space_info->bytes_used + space_info->bytes_pinned +
            space_info->bytes_reserved + alloc_bytes) < thresh) {
@@ -3039,7 +3318,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
         * we keep a reasonable number of metadata chunks allocated in the
         * FS as well.
         */
-       if (flags & BTRFS_BLOCK_GROUP_DATA) {
+       if (flags & BTRFS_BLOCK_GROUP_DATA && fs_info->metadata_ratio) {
                fs_info->data_chunk_allocations++;
                if (!(fs_info->data_chunk_allocations %
                      fs_info->metadata_ratio))
@@ -3047,8 +3326,11 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
        }
 
        ret = btrfs_alloc_chunk(trans, extent_root, flags);
+       spin_lock(&space_info->lock);
        if (ret)
                space_info->full = 1;
+       space_info->force_alloc = 0;
+       spin_unlock(&space_info->lock);
 out:
        mutex_unlock(&extent_root->fs_info->chunk_mutex);
        return ret;
@@ -4063,21 +4345,32 @@ loop:
        return ret;
 }
 
-static void dump_space_info(struct btrfs_space_info *info, u64 bytes)
+static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
+                           int dump_block_groups)
 {
        struct btrfs_block_group_cache *cache;
 
+       spin_lock(&info->lock);
        printk(KERN_INFO "space_info has %llu free, is %sfull\n",
               (unsigned long long)(info->total_bytes - info->bytes_used -
-                                   info->bytes_pinned - info->bytes_reserved),
+                                   info->bytes_pinned - info->bytes_reserved -
+                                   info->bytes_super),
               (info->full) ? "" : "not ");
        printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu,"
-              " may_use=%llu, used=%llu\n",
+              " may_use=%llu, used=%llu, root=%llu, super=%llu, reserved=%llu"
+              "\n",
               (unsigned long long)info->total_bytes,
               (unsigned long long)info->bytes_pinned,
               (unsigned long long)info->bytes_delalloc,
               (unsigned long long)info->bytes_may_use,
-              (unsigned long long)info->bytes_used);
+              (unsigned long long)info->bytes_used,
+              (unsigned long long)info->bytes_root,
+              (unsigned long long)info->bytes_super,
+              (unsigned long long)info->bytes_reserved);
+       spin_unlock(&info->lock);
+
+       if (!dump_block_groups)
+               return;
 
        down_read(&info->groups_sem);
        list_for_each_entry(cache, &info->block_groups, list) {
@@ -4145,7 +4438,7 @@ again:
                printk(KERN_ERR "btrfs allocation failed flags %llu, "
                       "wanted %llu\n", (unsigned long long)data,
                       (unsigned long long)num_bytes);
-               dump_space_info(sinfo, num_bytes);
+               dump_space_info(sinfo, num_bytes, 1);
        }
 
        return ret;
index 0cb88f8146ea85efa5bc944c9d95995a3d0ad772..de1793ba004aa472afc8c983521cea7380ef4720 100644 (file)
@@ -280,6 +280,14 @@ static struct extent_buffer *buffer_search(struct extent_io_tree *tree,
        return NULL;
 }
 
+static void merge_cb(struct extent_io_tree *tree, struct extent_state *new,
+                    struct extent_state *other)
+{
+       if (tree->ops && tree->ops->merge_extent_hook)
+               tree->ops->merge_extent_hook(tree->mapping->host, new,
+                                            other);
+}
+
 /*
  * utility function to look for merge candidates inside a given range.
  * Any extents with matching state are merged together into a single
@@ -303,6 +311,7 @@ static int merge_state(struct extent_io_tree *tree,
                other = rb_entry(other_node, struct extent_state, rb_node);
                if (other->end == state->start - 1 &&
                    other->state == state->state) {
+                       merge_cb(tree, state, other);
                        state->start = other->start;
                        other->tree = NULL;
                        rb_erase(&other->rb_node, &tree->state);
@@ -314,33 +323,37 @@ static int merge_state(struct extent_io_tree *tree,
                other = rb_entry(other_node, struct extent_state, rb_node);
                if (other->start == state->end + 1 &&
                    other->state == state->state) {
+                       merge_cb(tree, state, other);
                        other->start = state->start;
                        state->tree = NULL;
                        rb_erase(&state->rb_node, &tree->state);
                        free_extent_state(state);
+                       state = NULL;
                }
        }
+
        return 0;
 }
 
-static void set_state_cb(struct extent_io_tree *tree,
+static int set_state_cb(struct extent_io_tree *tree,
                         struct extent_state *state,
                         unsigned long bits)
 {
        if (tree->ops && tree->ops->set_bit_hook) {
-               tree->ops->set_bit_hook(tree->mapping->host, state->start,
-                                       state->end, state->state, bits);
+               return tree->ops->set_bit_hook(tree->mapping->host,
+                                              state->start, state->end,
+                                              state->state, bits);
        }
+
+       return 0;
 }
 
 static void clear_state_cb(struct extent_io_tree *tree,
                           struct extent_state *state,
                           unsigned long bits)
 {
-       if (tree->ops && tree->ops->clear_bit_hook) {
-               tree->ops->clear_bit_hook(tree->mapping->host, state->start,
-                                         state->end, state->state, bits);
-       }
+       if (tree->ops && tree->ops->clear_bit_hook)
+               tree->ops->clear_bit_hook(tree->mapping->host, state, bits);
 }
 
 /*
@@ -358,6 +371,7 @@ static int insert_state(struct extent_io_tree *tree,
                        int bits)
 {
        struct rb_node *node;
+       int ret;
 
        if (end < start) {
                printk(KERN_ERR "btrfs end < start %llu %llu\n",
@@ -365,11 +379,14 @@ static int insert_state(struct extent_io_tree *tree,
                       (unsigned long long)start);
                WARN_ON(1);
        }
-       if (bits & EXTENT_DIRTY)
-               tree->dirty_bytes += end - start + 1;
        state->start = start;
        state->end = end;
-       set_state_cb(tree, state, bits);
+       ret = set_state_cb(tree, state, bits);
+       if (ret)
+               return ret;
+
+       if (bits & EXTENT_DIRTY)
+               tree->dirty_bytes += end - start + 1;
        state->state |= bits;
        node = tree_insert(&tree->state, end, &state->rb_node);
        if (node) {
@@ -387,6 +404,15 @@ static int insert_state(struct extent_io_tree *tree,
        return 0;
 }
 
+static int split_cb(struct extent_io_tree *tree, struct extent_state *orig,
+                    u64 split)
+{
+       if (tree->ops && tree->ops->split_extent_hook)
+               return tree->ops->split_extent_hook(tree->mapping->host,
+                                                   orig, split);
+       return 0;
+}
+
 /*
  * split a given extent state struct in two, inserting the preallocated
  * struct 'prealloc' as the newly created second half.  'split' indicates an
@@ -405,6 +431,9 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig,
                       struct extent_state *prealloc, u64 split)
 {
        struct rb_node *node;
+
+       split_cb(tree, orig, split);
+
        prealloc->start = orig->start;
        prealloc->end = split - 1;
        prealloc->state = orig->state;
@@ -542,8 +571,8 @@ hit_next:
                if (err)
                        goto out;
                if (state->end <= end) {
-                       set |= clear_state_bit(tree, state, bits,
-                                       wake, delete);
+                       set |= clear_state_bit(tree, state, bits, wake,
+                                              delete);
                        if (last_end == (u64)-1)
                                goto out;
                        start = last_end + 1;
@@ -561,12 +590,11 @@ hit_next:
                        prealloc = alloc_extent_state(GFP_ATOMIC);
                err = split_state(tree, state, prealloc, end + 1);
                BUG_ON(err == -EEXIST);
-
                if (wake)
                        wake_up(&state->wq);
 
-               set |= clear_state_bit(tree, prealloc, bits,
-                                      wake, delete);
+               set |= clear_state_bit(tree, prealloc, bits, wake, delete);
+
                prealloc = NULL;
                goto out;
        }
@@ -667,16 +695,23 @@ out:
        return 0;
 }
 
-static void set_state_bits(struct extent_io_tree *tree,
+static int set_state_bits(struct extent_io_tree *tree,
                           struct extent_state *state,
                           int bits)
 {
+       int ret;
+
+       ret = set_state_cb(tree, state, bits);
+       if (ret)
+               return ret;
+
        if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) {
                u64 range = state->end - state->start + 1;
                tree->dirty_bytes += range;
        }
-       set_state_cb(tree, state, bits);
        state->state |= bits;
+
+       return 0;
 }
 
 static void cache_state(struct extent_state *state,
@@ -758,7 +793,10 @@ hit_next:
                        goto out;
                }
 
-               set_state_bits(tree, state, bits);
+               err = set_state_bits(tree, state, bits);
+               if (err)
+                       goto out;
+
                cache_state(state, cached_state);
                merge_state(tree, state);
                if (last_end == (u64)-1)
@@ -805,7 +843,9 @@ hit_next:
                if (err)
                        goto out;
                if (state->end <= end) {
-                       set_state_bits(tree, state, bits);
+                       err = set_state_bits(tree, state, bits);
+                       if (err)
+                               goto out;
                        cache_state(state, cached_state);
                        merge_state(tree, state);
                        if (last_end == (u64)-1)
@@ -829,11 +869,13 @@ hit_next:
                        this_end = last_start - 1;
                err = insert_state(tree, prealloc, start, this_end,
                                   bits);
-               cache_state(prealloc, cached_state);
-               prealloc = NULL;
                BUG_ON(err == -EEXIST);
-               if (err)
+               if (err) {
+                       prealloc = NULL;
                        goto out;
+               }
+               cache_state(prealloc, cached_state);
+               prealloc = NULL;
                start = this_end + 1;
                goto search_again;
        }
@@ -852,7 +894,11 @@ hit_next:
                err = split_state(tree, state, prealloc, end + 1);
                BUG_ON(err == -EEXIST);
 
-               set_state_bits(tree, prealloc, bits);
+               err = set_state_bits(tree, prealloc, bits);
+               if (err) {
+                       prealloc = NULL;
+                       goto out;
+               }
                cache_state(prealloc, cached_state);
                merge_state(tree, prealloc);
                prealloc = NULL;
index 14ed16fd862df22a93b7286c4c4811a8c12fa6ba..4794ec891fed31a3998098cb1999818627aacb12 100644 (file)
@@ -60,8 +60,13 @@ struct extent_io_ops {
                                      struct extent_state *state, int uptodate);
        int (*set_bit_hook)(struct inode *inode, u64 start, u64 end,
                            unsigned long old, unsigned long bits);
-       int (*clear_bit_hook)(struct inode *inode, u64 start, u64 end,
-                           unsigned long old, unsigned long bits);
+       int (*clear_bit_hook)(struct inode *inode, struct extent_state *state,
+                             unsigned long bits);
+       int (*merge_extent_hook)(struct inode *inode,
+                                struct extent_state *new,
+                                struct extent_state *other);
+       int (*split_extent_hook)(struct inode *inode,
+                                struct extent_state *orig, u64 split);
        int (*write_cache_pages_lock_hook)(struct page *page);
 };
 
@@ -79,10 +84,14 @@ struct extent_state {
        u64 start;
        u64 end; /* inclusive */
        struct rb_node rb_node;
+
+       /* ADD NEW ELEMENTS AFTER THIS */
        struct extent_io_tree *tree;
        wait_queue_head_t wq;
        atomic_t refs;
        unsigned long state;
+       u64 split_start;
+       u64 split_end;
 
        /* for use by the FS */
        u64 private;
index a3492a3ad96b960fecec513d4023f7ee641fcf81..f19e1259a971d52d62a9979ba311d3f136289e05 100644 (file)
@@ -123,7 +123,10 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
                    root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
 
        end_of_last_block = start_pos + num_bytes - 1;
-       btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+       err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+       if (err)
+               return err;
+
        for (i = 0; i < num_pages; i++) {
                struct page *p = pages[i];
                SetPageUptodate(p);
@@ -917,21 +920,35 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
        start_pos = pos;
 
        vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+
+       /* do the reserve before the mutex lock in case we have to do some
+        * flushing.  We wouldn't deadlock, but this is more polite.
+        */
+       err = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+       if (err)
+               goto out_nolock;
+
+       mutex_lock(&inode->i_mutex);
+
        current->backing_dev_info = inode->i_mapping->backing_dev_info;
        err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
        if (err)
-               goto out_nolock;
+               goto out;
+
        if (count == 0)
-               goto out_nolock;
+               goto out;
 
        err = file_remove_suid(file);
        if (err)
-               goto out_nolock;
+               goto out;
+
        file_update_time(file);
 
        pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
 
-       mutex_lock(&inode->i_mutex);
+       /* generic_write_checks can change our pos */
+       start_pos = pos;
+
        BTRFS_I(inode)->sequence++;
        first_index = pos >> PAGE_CACHE_SHIFT;
        last_index = (pos + count) >> PAGE_CACHE_SHIFT;
@@ -1005,9 +1022,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
                }
 
                if (will_write) {
-                       btrfs_fdatawrite_range(inode->i_mapping, pos,
-                                              pos + write_bytes - 1,
-                                              WB_SYNC_ALL);
+                       filemap_fdatawrite_range(inode->i_mapping, pos,
+                                                pos + write_bytes - 1);
                } else {
                        balance_dirty_pages_ratelimited_nr(inode->i_mapping,
                                                           num_pages);
@@ -1028,6 +1044,7 @@ out:
        mutex_unlock(&inode->i_mutex);
        if (ret)
                err = ret;
+       btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
 
 out_nolock:
        kfree(pages);
@@ -1196,7 +1213,7 @@ static int btrfs_file_mmap(struct file    *filp, struct vm_area_struct *vma)
        return 0;
 }
 
-struct file_operations btrfs_file_operations = {
+const struct file_operations btrfs_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
        .aio_read       = generic_file_aio_read,
index e9b76bcd1c129e0d1f4664f54fefd33caba72e08..112e5aa85892c35dbaf921ba16bba119d4c2c49e 100644 (file)
@@ -62,7 +62,7 @@ static const struct inode_operations btrfs_special_inode_operations;
 static const struct inode_operations btrfs_file_inode_operations;
 static const struct address_space_operations btrfs_aops;
 static const struct address_space_operations btrfs_symlink_aops;
-static struct file_operations btrfs_dir_file_operations;
+static const struct file_operations btrfs_dir_file_operations;
 static struct extent_io_ops btrfs_extent_io_ops;
 
 static struct kmem_cache *btrfs_inode_cachep;
@@ -1159,6 +1159,83 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
        return ret;
 }
 
+static int btrfs_split_extent_hook(struct inode *inode,
+                                   struct extent_state *orig, u64 split)
+{
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       u64 size;
+
+       if (!(orig->state & EXTENT_DELALLOC))
+               return 0;
+
+       size = orig->end - orig->start + 1;
+       if (size > root->fs_info->max_extent) {
+               u64 num_extents;
+               u64 new_size;
+
+               new_size = orig->end - split + 1;
+               num_extents = div64_u64(size + root->fs_info->max_extent - 1,
+                                       root->fs_info->max_extent);
+
+               /*
+                * if we break a large extent up then leave delalloc_extents be,
+                * since we've already accounted for the large extent.
+                */
+               if (div64_u64(new_size + root->fs_info->max_extent - 1,
+                             root->fs_info->max_extent) < num_extents)
+                       return 0;
+       }
+
+       BTRFS_I(inode)->delalloc_extents++;
+
+       return 0;
+}
+
+/*
+ * extent_io.c merge_extent_hook, used to track merged delayed allocation
+ * extents so we can keep track of new extents that are just merged onto old
+ * extents, such as when we are doing sequential writes, so we can properly
+ * account for the metadata space we'll need.
+ */
+static int btrfs_merge_extent_hook(struct inode *inode,
+                                  struct extent_state *new,
+                                  struct extent_state *other)
+{
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       u64 new_size, old_size;
+       u64 num_extents;
+
+       /* not delalloc, ignore it */
+       if (!(other->state & EXTENT_DELALLOC))
+               return 0;
+
+       old_size = other->end - other->start + 1;
+       if (new->start < other->start)
+               new_size = other->end - new->start + 1;
+       else
+               new_size = new->end - other->start + 1;
+
+       /* we're not bigger than the max, unreserve the space and go */
+       if (new_size <= root->fs_info->max_extent) {
+               BTRFS_I(inode)->delalloc_extents--;
+               return 0;
+       }
+
+       /*
+        * If we grew by another max_extent, just return, we want to keep that
+        * reserved amount.
+        */
+       num_extents = div64_u64(old_size + root->fs_info->max_extent - 1,
+                               root->fs_info->max_extent);
+       if (div64_u64(new_size + root->fs_info->max_extent - 1,
+                     root->fs_info->max_extent) > num_extents)
+               return 0;
+
+       BTRFS_I(inode)->delalloc_extents--;
+
+       return 0;
+}
+
 /*
  * extent_io.c set_bit_hook, used to track delayed allocation
  * bytes in this file, and to maintain the list of inodes that
@@ -1167,6 +1244,7 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
 static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
                       unsigned long old, unsigned long bits)
 {
+
        /*
         * set_bit and clear bit hooks normally require _irqsave/restore
         * but in this case, we are only testeing for the DELALLOC
@@ -1174,6 +1252,8 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
         */
        if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
+
+               BTRFS_I(inode)->delalloc_extents++;
                btrfs_delalloc_reserve_space(root, inode, end - start + 1);
                spin_lock(&root->fs_info->delalloc_lock);
                BTRFS_I(inode)->delalloc_bytes += end - start + 1;
@@ -1190,22 +1270,27 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
 /*
  * extent_io.c clear_bit_hook, see set_bit_hook for why
  */
-static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
-                        unsigned long old, unsigned long bits)
+static int btrfs_clear_bit_hook(struct inode *inode,
+                               struct extent_state *state, unsigned long bits)
 {
        /*
         * set_bit and clear bit hooks normally require _irqsave/restore
         * but in this case, we are only testeing for the DELALLOC
         * bit, which is only set or cleared with irqs on
         */
-       if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
+       if ((state->state & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
 
+               BTRFS_I(inode)->delalloc_extents--;
+               btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
+
                spin_lock(&root->fs_info->delalloc_lock);
-               if (end - start + 1 > root->fs_info->delalloc_bytes) {
+               if (state->end - state->start + 1 >
+                   root->fs_info->delalloc_bytes) {
                        printk(KERN_INFO "btrfs warning: delalloc account "
                               "%llu %llu\n",
-                              (unsigned long long)end - start + 1,
+                              (unsigned long long)
+                              state->end - state->start + 1,
                               (unsigned long long)
                               root->fs_info->delalloc_bytes);
                        btrfs_delalloc_free_space(root, inode, (u64)-1);
@@ -1213,9 +1298,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
                        BTRFS_I(inode)->delalloc_bytes = 0;
                } else {
                        btrfs_delalloc_free_space(root, inode,
-                                                 end - start + 1);
-                       root->fs_info->delalloc_bytes -= end - start + 1;
-                       BTRFS_I(inode)->delalloc_bytes -= end - start + 1;
+                                                 state->end -
+                                                 state->start + 1);
+                       root->fs_info->delalloc_bytes -= state->end -
+                               state->start + 1;
+                       BTRFS_I(inode)->delalloc_bytes -= state->end -
+                               state->start + 1;
                }
                if (BTRFS_I(inode)->delalloc_bytes == 0 &&
                    !list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
@@ -2950,7 +3038,12 @@ again:
                goto again;
        }
 
-       btrfs_set_extent_delalloc(inode, page_start, page_end);
+       ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+       if (ret) {
+               unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+               goto out_unlock;
+       }
+
        ret = 0;
        if (offset != PAGE_CACHE_SIZE) {
                kaddr = kmap(page);
@@ -2981,15 +3074,11 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
        u64 last_byte;
        u64 cur_offset;
        u64 hole_size;
-       int err;
+       int err = 0;
 
        if (size <= hole_start)
                return 0;
 
-       err = btrfs_check_metadata_free_space(root);
-       if (err)
-               return err;
-
        btrfs_truncate_page(inode->i_mapping, inode->i_size);
 
        while (1) {
@@ -3024,12 +3113,18 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
                                                 cur_offset, &hint_byte, 1);
                        if (err)
                                break;
+
+                       err = btrfs_reserve_metadata_space(root, 1);
+                       if (err)
+                               break;
+
                        err = btrfs_insert_file_extent(trans, root,
                                        inode->i_ino, cur_offset, 0,
                                        0, hole_size, 0, hole_size,
                                        0, 0, 0);
                        btrfs_drop_extent_cache(inode, hole_start,
                                        last_byte - 1, 0);
+                       btrfs_unreserve_metadata_space(root, 1);
                }
                free_extent_map(em);
                cur_offset = last_byte;
@@ -3990,11 +4085,18 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        if (!new_valid_dev(rdev))
                return -EINVAL;
 
-       err = btrfs_check_metadata_free_space(root);
+       /*
+        * 2 for inode item and ref
+        * 2 for dir items
+        * 1 for xattr if selinux is on
+        */
+       err = btrfs_reserve_metadata_space(root, 5);
        if (err)
-               goto fail;
+               return err;
 
        trans = btrfs_start_transaction(root, 1);
+       if (!trans)
+               goto fail;
        btrfs_set_trans_block_group(trans, dir);
 
        err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -4032,6 +4134,7 @@ out_unlock:
        nr = trans->blocks_used;
        btrfs_end_transaction_throttle(trans, root);
 fail:
+       btrfs_unreserve_metadata_space(root, 5);
        if (drop_inode) {
                inode_dec_link_count(inode);
                iput(inode);
@@ -4052,10 +4155,18 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        u64 objectid;
        u64 index = 0;
 
-       err = btrfs_check_metadata_free_space(root);
+       /*
+        * 2 for inode item and ref
+        * 2 for dir items
+        * 1 for xattr if selinux is on
+        */
+       err = btrfs_reserve_metadata_space(root, 5);
        if (err)
-               goto fail;
+               return err;
+
        trans = btrfs_start_transaction(root, 1);
+       if (!trans)
+               goto fail;
        btrfs_set_trans_block_group(trans, dir);
 
        err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -4096,6 +4207,7 @@ out_unlock:
        nr = trans->blocks_used;
        btrfs_end_transaction_throttle(trans, root);
 fail:
+       btrfs_unreserve_metadata_space(root, 5);
        if (drop_inode) {
                inode_dec_link_count(inode);
                iput(inode);
@@ -4118,10 +4230,16 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
        if (inode->i_nlink == 0)
                return -ENOENT;
 
-       btrfs_inc_nlink(inode);
-       err = btrfs_check_metadata_free_space(root);
+       /*
+        * 1 item for inode ref
+        * 2 items for dir items
+        */
+       err = btrfs_reserve_metadata_space(root, 3);
        if (err)
-               goto fail;
+               return err;
+
+       btrfs_inc_nlink(inode);
+
        err = btrfs_set_inode_index(dir, &index);
        if (err)
                goto fail;
@@ -4145,6 +4263,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
        nr = trans->blocks_used;
        btrfs_end_transaction_throttle(trans, root);
 fail:
+       btrfs_unreserve_metadata_space(root, 3);
        if (drop_inode) {
                inode_dec_link_count(inode);
                iput(inode);
@@ -4164,17 +4283,21 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        u64 index = 0;
        unsigned long nr = 1;
 
-       err = btrfs_check_metadata_free_space(root);
+       /*
+        * 2 items for inode and ref
+        * 2 items for dir items
+        * 1 for xattr if selinux is on
+        */
+       err = btrfs_reserve_metadata_space(root, 5);
        if (err)
-               goto out_unlock;
+               return err;
 
        trans = btrfs_start_transaction(root, 1);
-       btrfs_set_trans_block_group(trans, dir);
-
-       if (IS_ERR(trans)) {
-               err = PTR_ERR(trans);
+       if (!trans) {
+               err = -ENOMEM;
                goto out_unlock;
        }
+       btrfs_set_trans_block_group(trans, dir);
 
        err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
        if (err) {
@@ -4223,6 +4346,7 @@ out_fail:
        btrfs_end_transaction_throttle(trans, root);
 
 out_unlock:
+       btrfs_unreserve_metadata_space(root, 5);
        if (drop_on_err)
                iput(inode);
        btrfs_btree_balance_dirty(root, nr);
@@ -4747,6 +4871,13 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
                goto out;
        }
 
+       ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+       if (ret) {
+               btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+               ret = VM_FAULT_SIGBUS;
+               goto out;
+       }
+
        ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
 again:
        lock_page(page);
@@ -4778,7 +4909,23 @@ again:
                goto again;
        }
 
-       btrfs_set_extent_delalloc(inode, page_start, page_end);
+       /*
+        * XXX - page_mkwrite gets called every time the page is dirtied, even
+        * if it was already dirty, so for space accounting reasons we need to
+        * clear any delalloc bits for the range we are fixing to save.  There
+        * is probably a better way to do this, but for now keep consistent with
+        * prepare_pages in the normal write path.
+        */
+       clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+                         EXTENT_DIRTY | EXTENT_DELALLOC, GFP_NOFS);
+
+       ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+       if (ret) {
+               unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+               ret = VM_FAULT_SIGBUS;
+               btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+               goto out_unlock;
+       }
        ret = 0;
 
        /* page is wholly or partially inside EOF */
@@ -4801,6 +4948,7 @@ again:
        unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
 
 out_unlock:
+       btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
        if (!ret)
                return VM_FAULT_LOCKED;
        unlock_page(page);
@@ -4917,6 +5065,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
                return NULL;
        ei->last_trans = 0;
        ei->logged_trans = 0;
+       ei->delalloc_extents = 0;
+       ei->delalloc_reserved_extents = 0;
        btrfs_ordered_inode_tree_init(&ei->ordered_tree);
        INIT_LIST_HEAD(&ei->i_orphan);
        INIT_LIST_HEAD(&ei->ordered_operations);
@@ -5070,7 +5220,12 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
            new_inode->i_size > BTRFS_EMPTY_DIR_SIZE)
                return -ENOTEMPTY;
 
-       ret = btrfs_check_metadata_free_space(root);
+       /*
+        * 2 items for dir items
+        * 1 item for orphan entry
+        * 1 item for ref
+        */
+       ret = btrfs_reserve_metadata_space(root, 4);
        if (ret)
                return ret;
 
@@ -5185,6 +5340,8 @@ out_fail:
 
        if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
                up_read(&root->fs_info->subvol_sem);
+
+       btrfs_unreserve_metadata_space(root, 4);
        return ret;
 }
 
@@ -5256,11 +5413,18 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root))
                return -ENAMETOOLONG;
 
-       err = btrfs_check_metadata_free_space(root);
+       /*
+        * 2 items for inode item and ref
+        * 2 items for dir items
+        * 1 item for xattr if selinux is on
+        */
+       err = btrfs_reserve_metadata_space(root, 5);
        if (err)
-               goto out_fail;
+               return err;
 
        trans = btrfs_start_transaction(root, 1);
+       if (!trans)
+               goto out_fail;
        btrfs_set_trans_block_group(trans, dir);
 
        err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -5341,6 +5505,7 @@ out_unlock:
        nr = trans->blocks_used;
        btrfs_end_transaction_throttle(trans, root);
 out_fail:
+       btrfs_unreserve_metadata_space(root, 5);
        if (drop_inode) {
                inode_dec_link_count(inode);
                iput(inode);
@@ -5362,6 +5527,11 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans,
 
        while (num_bytes > 0) {
                alloc_size = min(num_bytes, root->fs_info->max_extent);
+
+               ret = btrfs_reserve_metadata_space(root, 1);
+               if (ret)
+                       goto out;
+
                ret = btrfs_reserve_extent(trans, root, alloc_size,
                                           root->sectorsize, 0, alloc_hint,
                                           (u64)-1, &ins, 1);
@@ -5381,6 +5551,7 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans,
                num_bytes -= ins.offset;
                cur_offset += ins.offset;
                alloc_hint = ins.objectid + ins.offset;
+               btrfs_unreserve_metadata_space(root, 1);
        }
 out:
        if (cur_offset > start) {
@@ -5544,7 +5715,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
        .permission     = btrfs_permission,
 };
 
-static struct file_operations btrfs_dir_file_operations = {
+static const struct file_operations btrfs_dir_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = btrfs_real_readdir,
@@ -5566,6 +5737,8 @@ static struct extent_io_ops btrfs_extent_io_ops = {
        .readpage_io_failed_hook = btrfs_io_failed_hook,
        .set_bit_hook = btrfs_set_bit_hook,
        .clear_bit_hook = btrfs_clear_bit_hook,
+       .merge_extent_hook = btrfs_merge_extent_hook,
+       .split_extent_hook = btrfs_split_extent_hook,
 };
 
 /*
index a8577a7f26ab248984357a0b8b6505013cff3dba..9a780c8d0ac83df7bc2444d90830e3214649e8a4 100644 (file)
@@ -239,7 +239,13 @@ static noinline int create_subvol(struct btrfs_root *root,
        u64 index = 0;
        unsigned long nr = 1;
 
-       ret = btrfs_check_metadata_free_space(root);
+       /*
+        * 1 - inode item
+        * 2 - refs
+        * 1 - root item
+        * 2 - dir items
+        */
+       ret = btrfs_reserve_metadata_space(root, 6);
        if (ret)
                return ret;
 
@@ -340,6 +346,9 @@ fail:
        err = btrfs_commit_transaction(trans, root);
        if (err && !ret)
                ret = err;
+
+       btrfs_unreserve_metadata_space(root, 6);
+       btrfs_btree_balance_dirty(root, nr);
        return ret;
 }
 
@@ -355,19 +364,27 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
        if (!root->ref_cows)
                return -EINVAL;
 
-       ret = btrfs_check_metadata_free_space(root);
+       /*
+        * 1 - inode item
+        * 2 - refs
+        * 1 - root item
+        * 2 - dir items
+        */
+       ret = btrfs_reserve_metadata_space(root, 6);
        if (ret)
                goto fail_unlock;
 
        pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
        if (!pending_snapshot) {
                ret = -ENOMEM;
+               btrfs_unreserve_metadata_space(root, 6);
                goto fail_unlock;
        }
        pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS);
        if (!pending_snapshot->name) {
                ret = -ENOMEM;
                kfree(pending_snapshot);
+               btrfs_unreserve_metadata_space(root, 6);
                goto fail_unlock;
        }
        memcpy(pending_snapshot->name, name, namelen);
@@ -1215,15 +1232,15 @@ static long btrfs_ioctl_trans_start(struct file *file)
        struct inode *inode = fdentry(file)->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
-       int ret = 0;
+       int ret;
 
+       ret = -EPERM;
        if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
+               goto out;
 
-       if (file->private_data) {
-               ret = -EINPROGRESS;
+       ret = -EINPROGRESS;
+       if (file->private_data)
                goto out;
-       }
 
        ret = mnt_want_write(file->f_path.mnt);
        if (ret)
@@ -1233,12 +1250,19 @@ static long btrfs_ioctl_trans_start(struct file *file)
        root->fs_info->open_ioctl_trans++;
        mutex_unlock(&root->fs_info->trans_mutex);
 
+       ret = -ENOMEM;
        trans = btrfs_start_ioctl_transaction(root, 0);
-       if (trans)
-               file->private_data = trans;
-       else
-               ret = -ENOMEM;
-       /*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/
+       if (!trans)
+               goto out_drop;
+
+       file->private_data = trans;
+       return 0;
+
+out_drop:
+       mutex_lock(&root->fs_info->trans_mutex);
+       root->fs_info->open_ioctl_trans--;
+       mutex_unlock(&root->fs_info->trans_mutex);
+       mnt_drop_write(file->f_path.mnt);
 out:
        return ret;
 }
@@ -1254,24 +1278,20 @@ long btrfs_ioctl_trans_end(struct file *file)
        struct inode *inode = fdentry(file)->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
-       int ret = 0;
 
        trans = file->private_data;
-       if (!trans) {
-               ret = -EINVAL;
-               goto out;
-       }
-       btrfs_end_transaction(trans, root);
+       if (!trans)
+               return -EINVAL;
        file->private_data = NULL;
 
+       btrfs_end_transaction(trans, root);
+
        mutex_lock(&root->fs_info->trans_mutex);
        root->fs_info->open_ioctl_trans--;
        mutex_unlock(&root->fs_info->trans_mutex);
 
        mnt_drop_write(file->f_path.mnt);
-
-out:
-       return ret;
+       return 0;
 }
 
 long btrfs_ioctl(struct file *file, unsigned int
index b5d6d24726b0014463f15041bbc9ddd74fdb110e..897fba835f897a0d02f1d4677447fdcf70d115d7 100644 (file)
@@ -458,7 +458,7 @@ void btrfs_start_ordered_extent(struct inode *inode,
         * start IO on any dirty ones so the wait doesn't stall waiting
         * for pdflush to find them
         */
-       btrfs_fdatawrite_range(inode->i_mapping, start, end, WB_SYNC_ALL);
+       filemap_fdatawrite_range(inode->i_mapping, start, end);
        if (wait) {
                wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE,
                                                 &entry->flags));
@@ -488,17 +488,15 @@ again:
        /* start IO across the range first to instantiate any delalloc
         * extents
         */
-       btrfs_fdatawrite_range(inode->i_mapping, start, orig_end, WB_SYNC_ALL);
+       filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
 
        /* The compression code will leave pages locked but return from
         * writepage without setting the page writeback.  Starting again
         * with WB_SYNC_ALL will end up waiting for the IO to actually start.
         */
-       btrfs_fdatawrite_range(inode->i_mapping, start, orig_end, WB_SYNC_ALL);
+       filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
 
-       btrfs_wait_on_page_writeback_range(inode->i_mapping,
-                                          start >> PAGE_CACHE_SHIFT,
-                                          orig_end >> PAGE_CACHE_SHIFT);
+       filemap_fdatawait_range(inode->i_mapping, start, orig_end);
 
        end = orig_end;
        found = 0;
@@ -716,89 +714,6 @@ out:
 }
 
 
-/**
- * taken from mm/filemap.c because it isn't exported
- *
- * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range
- * @mapping:   address space structure to write
- * @start:     offset in bytes where the range starts
- * @end:       offset in bytes where the range ends (inclusive)
- * @sync_mode: enable synchronous operation
- *
- * Start writeback against all of a mapping's dirty pages that lie
- * within the byte offsets <start, end> inclusive.
- *
- * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as
- * opposed to a regular memory cleansing writeback.  The difference between
- * these two operations is that if a dirty page/buffer is encountered, it must
- * be waited upon, and not just skipped over.
- */
-int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
-                          loff_t end, int sync_mode)
-{
-       struct writeback_control wbc = {
-               .sync_mode = sync_mode,
-               .nr_to_write = mapping->nrpages * 2,
-               .range_start = start,
-               .range_end = end,
-       };
-       return btrfs_writepages(mapping, &wbc);
-}
-
-/**
- * taken from mm/filemap.c because it isn't exported
- *
- * wait_on_page_writeback_range - wait for writeback to complete
- * @mapping:   target address_space
- * @start:     beginning page index
- * @end:       ending page index
- *
- * Wait for writeback to complete against pages indexed by start->end
- * inclusive
- */
-int btrfs_wait_on_page_writeback_range(struct address_space *mapping,
-                                      pgoff_t start, pgoff_t end)
-{
-       struct pagevec pvec;
-       int nr_pages;
-       int ret = 0;
-       pgoff_t index;
-
-       if (end < start)
-               return 0;
-
-       pagevec_init(&pvec, 0);
-       index = start;
-       while ((index <= end) &&
-                       (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-                       PAGECACHE_TAG_WRITEBACK,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1)) != 0) {
-               unsigned i;
-
-               for (i = 0; i < nr_pages; i++) {
-                       struct page *page = pvec.pages[i];
-
-                       /* until radix tree lookup accepts end_index */
-                       if (page->index > end)
-                               continue;
-
-                       wait_on_page_writeback(page);
-                       if (PageError(page))
-                               ret = -EIO;
-               }
-               pagevec_release(&pvec);
-               cond_resched();
-       }
-
-       /* Check for outstanding write errors */
-       if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
-               ret = -ENOSPC;
-       if (test_and_clear_bit(AS_EIO, &mapping->flags))
-               ret = -EIO;
-
-       return ret;
-}
-
 /*
  * add a given inode to the list of inodes that must be fully on
  * disk before a transaction commit finishes.
index 993a7ea45c702a580c784908584408684913e233..f82e87488ca8f47d158c37281a3aafa746d5031d 100644 (file)
@@ -153,10 +153,6 @@ btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset);
 int btrfs_ordered_update_i_size(struct inode *inode,
                                struct btrfs_ordered_extent *ordered);
 int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum);
-int btrfs_wait_on_page_writeback_range(struct address_space *mapping,
-                                      pgoff_t start, pgoff_t end);
-int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
-                          loff_t end, int sync_mode);
 int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only);
 int btrfs_run_ordered_operations(struct btrfs_root *root, int wait);
 int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
index 67035385444cf29c31a59951311af66702fa80a8..9de9b22364190de829c4479cc74b81578f41b18a 100644 (file)
@@ -344,7 +344,9 @@ static int btrfs_fill_super(struct super_block *sb,
        sb->s_export_op = &btrfs_export_ops;
        sb->s_xattr = btrfs_xattr_handlers;
        sb->s_time_gran = 1;
+#ifdef CONFIG_BTRFS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
+#endif
 
        tree_root = open_ctree(sb, fs_devices, (char *)data);
 
index 88f866f85e7affa4b387cc3cc72fae5a472bb786..0b8f36d4400a70919d055cac8b467b7a0f9c24d7 100644 (file)
@@ -186,6 +186,9 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
        h->alloc_exclude_start = 0;
        h->delayed_ref_updates = 0;
 
+       if (!current->journal_info)
+               current->journal_info = h;
+
        root->fs_info->running_transaction->use_count++;
        record_root_in_trans(h, root);
        mutex_unlock(&root->fs_info->trans_mutex);
@@ -317,6 +320,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
                wake_up(&cur_trans->writer_wait);
        put_transaction(cur_trans);
        mutex_unlock(&info->trans_mutex);
+
+       if (current->journal_info == trans)
+               current->journal_info = NULL;
        memset(trans, 0, sizeof(*trans));
        kmem_cache_free(btrfs_trans_handle_cachep, trans);
 
@@ -743,6 +749,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        memcpy(&pending->root_key, &key, sizeof(key));
 fail:
        kfree(new_root_item);
+       btrfs_unreserve_metadata_space(root, 6);
        return ret;
 }
 
@@ -1059,6 +1066,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        mutex_unlock(&root->fs_info->trans_mutex);
 
+       if (current->journal_info == trans)
+               current->journal_info = NULL;
+
        kmem_cache_free(btrfs_trans_handle_cachep, trans);
        return ret;
 }
index 23e7d36ff32554eb7e781ab7c8e9b8102fddc235..7eda483d7b5aa0cd5e5bd96d149cca6fe2fc8f16 100644 (file)
@@ -446,8 +446,10 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
                        goto error;
 
                device->name = kstrdup(orig_dev->name, GFP_NOFS);
-               if (!device->name)
+               if (!device->name) {
+                       kfree(device);
                        goto error;
+               }
 
                device->devid = orig_dev->devid;
                device->work.func = pending_bios_fn;
index a9d3bf4d2689a5924f1de8765bc38e3c5481c215..b0fc93f95fd0c7f18ac60471c60d767221df37af 100644 (file)
@@ -260,7 +260,7 @@ err:
  * attributes are handled directly.
  */
 struct xattr_handler *btrfs_xattr_handlers[] = {
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_BTRFS_POSIX_ACL
        &btrfs_xattr_acl_access_handler,
        &btrfs_xattr_acl_default_handler,
 #endif
index 0376ac66c44a6127199c5389f33f138f73c53fba..be4392ca20983345ae180a450fd0497442b135a8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/time.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
index d5c0ea2e8f2da53412fae66e6b758cf8c0e6850a..9f2d45d75b1a70084e5f153c94d49a2b5f863321 100644 (file)
@@ -26,20 +26,6 @@ config EXT4_FS
 
          If unsure, say N.
 
-config EXT4DEV_COMPAT
-       bool "Enable ext4dev compatibility"
-       depends on EXT4_FS
-       help
-         Starting with 2.6.28, the name of the ext4 filesystem was
-         renamed from ext4dev to ext4.  Unfortunately there are some
-         legacy userspace programs (such as klibc's fstype) have
-         "ext4dev" hardcoded.
-
-         To enable backwards compatibility so that systems that are
-         still expecting to mount ext4 filesystems using ext4dev,
-         choose Y here.   This feature will go away by 2.6.31, so
-         please arrange to get your userspace programs fixed!
-
 config EXT4_FS_XATTR
        bool "Ext4 extended attributes"
        depends on EXT4_FS
index ec367bce7215a4f0a1dca7abde474617c61fba5b..5c5bc5dafff818991b26f5fd7ebdf6ebf4e83c67 100644 (file)
@@ -1146,8 +1146,8 @@ static int check_block_validity(struct inode *inode, const char *msg,
 }
 
 /*
- * Return the number of dirty pages in the given inode starting at
- * page frame idx.
+ * Return the number of contiguous dirty pages in a given inode
+ * starting at page frame idx.
  */
 static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
                                    unsigned int max_pages)
@@ -1181,15 +1181,15 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
                                unlock_page(page);
                                break;
                        }
-                       head = page_buffers(page);
-                       bh = head;
-                       do {
-                               if (!buffer_delay(bh) &&
-                                   !buffer_unwritten(bh)) {
-                                       done = 1;
-                                       break;
-                               }
-                       } while ((bh = bh->b_this_page) != head);
+                       if (page_has_buffers(page)) {
+                               bh = head = page_buffers(page);
+                               do {
+                                       if (!buffer_delay(bh) &&
+                                           !buffer_unwritten(bh))
+                                               done = 1;
+                                       bh = bh->b_this_page;
+                               } while (!done && (bh != head));
+                       }
                        unlock_page(page);
                        if (done)
                                break;
@@ -3378,6 +3378,7 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
        ssize_t ret;
        int orphan = 0;
        size_t count = iov_length(iov, nr_segs);
+       int retries = 0;
 
        if (rw == WRITE) {
                loff_t final_size = offset + count;
@@ -3400,9 +3401,12 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
                }
        }
 
+retry:
        ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
                                 offset, nr_segs,
                                 ext4_get_block, NULL);
+       if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+               goto retry;
 
        if (orphan) {
                int err;
@@ -5612,14 +5616,12 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
  */
 void ext4_dirty_inode(struct inode *inode)
 {
-       handle_t *current_handle = ext4_journal_current_handle();
        handle_t *handle;
 
        handle = ext4_journal_start(inode, 2);
        if (IS_ERR(handle))
                goto out;
 
-       jbd_debug(5, "marking dirty.  outer handle=%p\n", current_handle);
        ext4_mark_inode_dirty(handle, inode);
 
        ext4_journal_stop(handle);
index 12e726a7073fac69631f8d516c01dbce2babb2e2..312211ee05af39618274736a49096cb88ff067de 100644 (file)
@@ -3966,27 +3966,6 @@ static struct file_system_type ext4_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV,
 };
 
-#ifdef CONFIG_EXT4DEV_COMPAT
-static int ext4dev_get_sb(struct file_system_type *fs_type, int flags,
-                         const char *dev_name, void *data,struct vfsmount *mnt)
-{
-       printk(KERN_WARNING "EXT4-fs (%s): Update your userspace programs "
-              "to mount using ext4\n", dev_name);
-       printk(KERN_WARNING "EXT4-fs (%s): ext4dev backwards compatibility "
-              "will go away by 2.6.31\n", dev_name);
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
-}
-
-static struct file_system_type ext4dev_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "ext4dev",
-       .get_sb         = ext4dev_get_sb,
-       .kill_sb        = kill_block_super,
-       .fs_flags       = FS_REQUIRES_DEV,
-};
-MODULE_ALIAS("ext4dev");
-#endif
-
 static int __init init_ext4_fs(void)
 {
        int err;
@@ -4011,13 +3990,6 @@ static int __init init_ext4_fs(void)
        err = register_filesystem(&ext4_fs_type);
        if (err)
                goto out;
-#ifdef CONFIG_EXT4DEV_COMPAT
-       err = register_filesystem(&ext4dev_fs_type);
-       if (err) {
-               unregister_filesystem(&ext4_fs_type);
-               goto out;
-       }
-#endif
        return 0;
 out:
        destroy_inodecache();
@@ -4036,9 +4008,6 @@ out4:
 static void __exit exit_ext4_fs(void)
 {
        unregister_filesystem(&ext4_fs_type);
-#ifdef CONFIG_EXT4DEV_COMPAT
-       unregister_filesystem(&ext4dev_fs_type);
-#endif
        destroy_inodecache();
        exit_ext4_xattr();
        exit_ext4_mballoc();
index 761af77491f5940529d6ee62b859dbdecd030cbe..b0ab5219becbd92e34c6676a93716e102e70abe9 100644 (file)
@@ -770,7 +770,7 @@ static int jbd2_seq_info_release(struct inode *inode, struct file *file)
        return seq_release(inode, file);
 }
 
-static struct file_operations jbd2_seq_info_fops = {
+static const struct file_operations jbd2_seq_info_fops = {
        .owner          = THIS_MODULE,
        .open           = jbd2_seq_info_open,
        .read           = seq_read,
index 00388d2a3c9970a3fdfccec1c4dda85904b6fd4e..5c01fc148ce880e02a557a3ade47a00056d563f3 100644 (file)
@@ -176,7 +176,7 @@ static const struct file_operations exports_operations = {
 extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
 extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
 
-static struct file_operations pool_stats_operations = {
+static const struct file_operations pool_stats_operations = {
        .open           = nfsd_pool_stats_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
index 1a4fa04cf071bd8a82ae9f21d079612e963b419b..e097099bfc8f0923480e110243979d9ace0be924 100644 (file)
@@ -697,7 +697,7 @@ not_empty:
        return 0;
 }
 
-struct file_operations nilfs_dir_operations = {
+const struct file_operations nilfs_dir_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = nilfs_readdir,
index 7d7b4983dee3d631c22456d0c2d6581bf4239b9c..30292df443cea081b6b4c94690f41aaf8cad01ec 100644 (file)
@@ -134,7 +134,7 @@ static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
  * We have mostly NULL's here: the current defaults are ok for
  * the nilfs filesystem.
  */
-struct file_operations nilfs_file_operations = {
+const struct file_operations nilfs_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
index b18c4998f8d0c1834727ecf089d48d3235851766..f6326112d647537c5ea0419d36ec4b73d466fbbd 100644 (file)
@@ -433,7 +433,7 @@ static const struct address_space_operations def_mdt_aops = {
 };
 
 static const struct inode_operations def_mdt_iops;
-static struct file_operations def_mdt_fops;
+static const struct file_operations def_mdt_fops;
 
 /*
  * NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile,
index bad7368782d08a7759ca5964c9dda18b130f4819..4da6f67e9a915aeb2096cc03cb47ec09a40f0338 100644 (file)
@@ -294,9 +294,9 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *);
 /*
  * Inodes and files operations
  */
-extern struct file_operations nilfs_dir_operations;
+extern const struct file_operations nilfs_dir_operations;
 extern const struct inode_operations nilfs_file_inode_operations;
-extern struct file_operations nilfs_file_operations;
+extern const struct file_operations nilfs_file_operations;
 extern const struct address_space_operations nilfs_aops;
 extern const struct inode_operations nilfs_dir_inode_operations;
 extern const struct inode_operations nilfs_special_inode_operations;
index 09cc25d04611bfac57adfd422ba519a1c7a5664b..c452d116b89251690bcc393681340bf743a5ac20 100644 (file)
@@ -966,7 +966,7 @@ static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
 }
 #endif  /* CONFIG_DEBUG_FS */
 
-static struct file_operations o2hb_debug_fops = {
+static const struct file_operations o2hb_debug_fops = {
        .open =         o2hb_debug_open,
        .release =      o2hb_debug_release,
        .read =         o2hb_debug_read,
index cfb2be708abe33b255ed8f3208f93569a92339e8..da794bc07a6c27ba82b964179a968c6b720317fb 100644 (file)
@@ -207,7 +207,7 @@ static int nst_fop_release(struct inode *inode, struct file *file)
        return seq_release_private(inode, file);
 }
 
-static struct file_operations nst_seq_fops = {
+static const struct file_operations nst_seq_fops = {
        .open = nst_fop_open,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -388,7 +388,7 @@ static int sc_fop_release(struct inode *inode, struct file *file)
        return seq_release_private(inode, file);
 }
 
-static struct file_operations sc_seq_fops = {
+static const struct file_operations sc_seq_fops = {
        .open = sc_fop_open,
        .read = seq_read,
        .llseek = seq_lseek,
index ca46002ec10ea7ae1fa3da82e27a5f010f47bd92..42b0bad7a612459c8f3e6857cbf829cab964bd57 100644 (file)
@@ -478,7 +478,7 @@ bail:
        return -ENOMEM;
 }
 
-static struct file_operations debug_purgelist_fops = {
+static const struct file_operations debug_purgelist_fops = {
        .open =         debug_purgelist_open,
        .release =      debug_buffer_release,
        .read =         debug_buffer_read,
@@ -538,7 +538,7 @@ bail:
        return -ENOMEM;
 }
 
-static struct file_operations debug_mle_fops = {
+static const struct file_operations debug_mle_fops = {
        .open =         debug_mle_open,
        .release =      debug_buffer_release,
        .read =         debug_buffer_read,
@@ -741,7 +741,7 @@ static int debug_lockres_release(struct inode *inode, struct file *file)
        return seq_release_private(inode, file);
 }
 
-static struct file_operations debug_lockres_fops = {
+static const struct file_operations debug_lockres_fops = {
        .open =         debug_lockres_open,
        .release =      debug_lockres_release,
        .read =         seq_read,
@@ -925,7 +925,7 @@ bail:
        return -ENOMEM;
 }
 
-static struct file_operations debug_state_fops = {
+static const struct file_operations debug_state_fops = {
        .open =         debug_state_open,
        .release =      debug_buffer_release,
        .read =         debug_buffer_read,
index 4cc3c890a2cd48a0d13dc8cb7da4efabf0c22e16..c0e48aeebb1c3877862853ec1761bed05e6f9355 100644 (file)
@@ -373,7 +373,7 @@ static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static struct file_operations ocfs2_osb_debug_fops = {
+static const struct file_operations ocfs2_osb_debug_fops = {
        .open =         ocfs2_osb_debug_open,
        .release =      ocfs2_debug_release,
        .read =         ocfs2_debug_read,
index 3680bae335b5b37464dbf6ba126855be69e8d021..b42d6241903472820723c5c2cb693f1b040158e0 100644 (file)
@@ -498,7 +498,7 @@ const struct inode_operations omfs_dir_inops = {
        .rmdir = omfs_rmdir,
 };
 
-struct file_operations omfs_dir_operations = {
+const struct file_operations omfs_dir_operations = {
        .read = generic_read_dir,
        .readdir = omfs_readdir,
        .llseek = generic_file_llseek,
index 4845fbb18e6e96c579384e3dfa53271a0b577343..399487c093646a86ea910756d127d53e4e813668 100644 (file)
@@ -322,7 +322,7 @@ static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
        return generic_block_bmap(mapping, block, omfs_get_block);
 }
 
-struct file_operations omfs_file_operations = {
+const struct file_operations omfs_file_operations = {
        .llseek = generic_file_llseek,
        .read = do_sync_read,
        .write = do_sync_write,
index df71039945ac2f15124bdba6e2a7c3c16ac485dc..ebe2fdbe535ec07f95aa0981e2cc53f12d912cdf 100644 (file)
@@ -44,14 +44,14 @@ extern int omfs_allocate_range(struct super_block *sb, int min_request,
 extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
 
 /* dir.c */
-extern struct file_operations omfs_dir_operations;
+extern const struct file_operations omfs_dir_operations;
 extern const struct inode_operations omfs_dir_inops;
 extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
 extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
                        u64 fsblock);
 
 /* file.c */
-extern struct file_operations omfs_file_operations;
+extern const struct file_operations omfs_file_operations;
 extern const struct inode_operations omfs_file_inops;
 extern const struct address_space_operations omfs_aops;
 extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
index 7b685e10cbad8cc9b052cec48737fbf7bf6f7afb..f38fee0311a7a82b3ee19ece135c3e17b38e1cdd 100644 (file)
@@ -248,19 +248,11 @@ ssize_t part_stat_show(struct device *dev,
                part_stat_read(p, merges[WRITE]),
                (unsigned long long)part_stat_read(p, sectors[WRITE]),
                jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
-               part_in_flight(p),
+               p->in_flight,
                jiffies_to_msecs(part_stat_read(p, io_ticks)),
                jiffies_to_msecs(part_stat_read(p, time_in_queue)));
 }
 
-ssize_t part_inflight_show(struct device *dev,
-                       struct device_attribute *attr, char *buf)
-{
-       struct hd_struct *p = dev_to_part(dev);
-
-       return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]);
-}
-
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 ssize_t part_fail_show(struct device *dev,
                       struct device_attribute *attr, char *buf)
@@ -289,7 +281,6 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
 static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
-static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
        __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -301,7 +292,6 @@ static struct attribute *part_attrs[] = {
        &dev_attr_size.attr,
        &dev_attr_alignment_offset.attr,
        &dev_attr_stat.attr,
-       &dev_attr_inflight.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
        &dev_attr_fail.attr,
 #endif
index a201fc370223b01c918ae9767432c3060c6de95e..fd38ce2e32e349ba3c418dbc454957dd0e3ad958 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index 9cca3785cab881c854236b00a37fa5e478f06a3a..66d6106a2067fefc1f4154e500d93ea889f94cd6 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _ASM_GENERIC_GPIO_H
 #define _ASM_GENERIC_GPIO_H
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 
index 086e5c362d3a7c57064278135d36064f3a6c2a2a..817b23705c91f62d1ed3a066eddcffc724da77c4 100644 (file)
@@ -397,7 +397,7 @@ struct atmdev_ops { /* only send is required */
        int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
            void __user *optval,int optlen);
        int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
-           void __user *optval,int optlen);
+           void __user *optval,unsigned int optlen);
        int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
        int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
        void (*phy_put)(struct atm_dev *dev,unsigned char value,
index e23a86cae5ac9a328fd2fe1cc7c4eecc0741760c..25119041e034c9f51bdbbbfe4d3ad146ac9ad9c4 100644 (file)
@@ -82,7 +82,6 @@ enum rq_cmd_type_bits {
 enum {
        REQ_LB_OP_EJECT = 0x40,         /* eject request */
        REQ_LB_OP_FLUSH = 0x41,         /* flush request */
-       REQ_LB_OP_DISCARD = 0x42,       /* discard sectors */
 };
 
 /*
@@ -261,7 +260,6 @@ typedef void (request_fn_proc) (struct request_queue *q);
 typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
 typedef int (prep_rq_fn) (struct request_queue *, struct request *);
 typedef void (unplug_fn) (struct request_queue *);
-typedef int (prepare_discard_fn) (struct request_queue *, struct request *);
 
 struct bio_vec;
 struct bvec_merge_data {
@@ -313,6 +311,7 @@ struct queue_limits {
        unsigned int            alignment_offset;
        unsigned int            io_min;
        unsigned int            io_opt;
+       unsigned int            max_discard_sectors;
 
        unsigned short          logical_block_size;
        unsigned short          max_hw_segments;
@@ -340,7 +339,6 @@ struct request_queue
        make_request_fn         *make_request_fn;
        prep_rq_fn              *prep_rq_fn;
        unplug_fn               *unplug_fn;
-       prepare_discard_fn      *prepare_discard_fn;
        merge_bvec_fn           *merge_bvec_fn;
        prepare_flush_fn        *prepare_flush_fn;
        softirq_done_fn         *softirq_done_fn;
@@ -460,6 +458,7 @@ struct request_queue
 #define QUEUE_FLAG_VIRT        QUEUE_FLAG_NONROT /* paravirt device */
 #define QUEUE_FLAG_IO_STAT     15      /* do IO stats */
 #define QUEUE_FLAG_CQ         16       /* hardware does queuing */
+#define QUEUE_FLAG_DISCARD     17      /* supports DISCARD */
 
 #define QUEUE_FLAG_DEFAULT     ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_CLUSTER) |            \
@@ -591,6 +590,7 @@ enum {
 #define blk_queue_flushing(q)  ((q)->ordseq)
 #define blk_queue_stackable(q) \
        test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
+#define blk_queue_discard(q)   test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
 
 #define blk_fs_request(rq)     ((rq)->cmd_type == REQ_TYPE_FS)
 #define blk_pc_request(rq)     ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
@@ -929,6 +929,8 @@ extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
 extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
 extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
 extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
+extern void blk_queue_max_discard_sectors(struct request_queue *q,
+               unsigned int max_discard_sectors);
 extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
 extern void blk_queue_physical_block_size(struct request_queue *, unsigned short);
 extern void blk_queue_alignment_offset(struct request_queue *q,
@@ -955,7 +957,6 @@ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
 extern void blk_queue_dma_alignment(struct request_queue *, int);
 extern void blk_queue_update_dma_alignment(struct request_queue *, int);
 extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
-extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *);
 extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
 extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
@@ -1080,25 +1081,37 @@ static inline unsigned int queue_physical_block_size(struct request_queue *q)
        return q->limits.physical_block_size;
 }
 
+static inline int bdev_physical_block_size(struct block_device *bdev)
+{
+       return queue_physical_block_size(bdev_get_queue(bdev));
+}
+
 static inline unsigned int queue_io_min(struct request_queue *q)
 {
        return q->limits.io_min;
 }
 
+static inline int bdev_io_min(struct block_device *bdev)
+{
+       return queue_io_min(bdev_get_queue(bdev));
+}
+
 static inline unsigned int queue_io_opt(struct request_queue *q)
 {
        return q->limits.io_opt;
 }
 
+static inline int bdev_io_opt(struct block_device *bdev)
+{
+       return queue_io_opt(bdev_get_queue(bdev));
+}
+
 static inline int queue_alignment_offset(struct request_queue *q)
 {
-       if (q && q->limits.misaligned)
+       if (q->limits.misaligned)
                return -1;
 
-       if (q && q->limits.alignment_offset)
-               return q->limits.alignment_offset;
-
-       return 0;
+       return q->limits.alignment_offset;
 }
 
 static inline int queue_sector_alignment_offset(struct request_queue *q,
@@ -1108,6 +1121,19 @@ static inline int queue_sector_alignment_offset(struct request_queue *q,
                & (q->limits.io_min - 1);
 }
 
+static inline int bdev_alignment_offset(struct block_device *bdev)
+{
+       struct request_queue *q = bdev_get_queue(bdev);
+
+       if (q->limits.misaligned)
+               return -1;
+
+       if (bdev != bdev->bd_contains)
+               return bdev->bd_part->alignment_offset;
+
+       return q->limits.alignment_offset;
+}
+
 static inline int queue_dma_alignment(struct request_queue *q)
 {
        return q ? q->dma_alignment : 511;
@@ -1146,7 +1172,11 @@ static inline void put_dev_sector(Sector p)
 }
 
 struct work_struct;
+struct delayed_work;
 int kblockd_schedule_work(struct request_queue *q, struct work_struct *work);
+int kblockd_schedule_delayed_work(struct request_queue *q,
+                                       struct delayed_work *work,
+                                       unsigned long delay);
 
 #define MODULE_ALIAS_BLOCKDEV(major,minor) \
        MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
index 7e4350ece0f8dd495398ca4cbf41c95e995b6525..3b73b9992b261125a22ef70a46bebc88a2eba23a 100644 (file)
@@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
                           char __user *arg);
 extern int blk_trace_startstop(struct request_queue *q, int start);
 extern int blk_trace_remove(struct request_queue *q);
+extern void blk_trace_remove_sysfs(struct device *dev);
 extern int blk_trace_init_sysfs(struct device *dev);
 
 extern struct attribute_group blk_trace_attr_group;
@@ -211,6 +212,7 @@ extern struct attribute_group blk_trace_attr_group;
 # define blk_trace_startstop(q, start)                 (-ENOTTY)
 # define blk_trace_remove(q)                           (-ENOTTY)
 # define blk_add_trace_msg(q, fmt, ...)                        do { } while (0)
+# define blk_trace_remove_sysfs(dev)                   do { } while (0)
 static inline int blk_trace_init_sysfs(struct device *dev)
 {
        return 0;
index b62bb9294d0c594618515c5f0214e963f7e3a904..0008dee665148850f2b46af2918b23635cedc7c0 100644 (file)
@@ -37,7 +37,7 @@ extern void cgroup_exit(struct task_struct *p, int run_callbacks);
 extern int cgroupstats_build(struct cgroupstats *stats,
                                struct dentry *dentry);
 
-extern struct file_operations proc_cgroup_operations;
+extern const struct file_operations proc_cgroup_operations;
 
 /* Define the enumeration of all cgroup subsystems */
 #define SUBSYS(_x) _x ## _subsys_id,
index 47ebf416f5129aa67026eee08fc64948d2f69259..3a14615fd35c57cb2c42940c8f3e0e3dd9c78c9b 100644 (file)
@@ -132,11 +132,8 @@ struct cn_callback_id {
 };
 
 struct cn_callback_data {
-       void (*destruct_data) (void *);
-       void *ddata;
-       
-       void *callback_priv;
-       void (*callback) (struct cn_msg *);
+       struct sk_buff *skb;
+       void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
 
        void *free;
 };
@@ -167,11 +164,11 @@ struct cn_dev {
        struct cn_queue_dev *cbdev;
 };
 
-int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *));
+int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
 void cn_del_callback(struct cb_id *);
 int cn_netlink_send(struct cn_msg *, u32, gfp_t);
 
-int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *));
+int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
 void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
 
 int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work);
index 2adaa2529f184fda637a6a2aeea55bda41693104..2620a8c63571a673f29a802a8144fec5014575f3 100644 (file)
@@ -300,6 +300,10 @@ struct inodes_stat_t {
 #define BLKTRACESTOP _IO(0x12,117)
 #define BLKTRACETEARDOWN _IO(0x12,118)
 #define BLKDISCARD _IO(0x12,119)
+#define BLKIOMIN _IO(0x12,120)
+#define BLKIOOPT _IO(0x12,121)
+#define BLKALIGNOFF _IO(0x12,122)
+#define BLKPBSZGET _IO(0x12,123)
 
 #define BMAP_IOCTL 1           /* obsolete - kept for compatibility */
 #define FIBMAP    _IO(0x00,1)  /* bmap access */
@@ -2446,7 +2450,7 @@ static int __fops ## _open(struct inode *inode, struct file *file)        \
        __simple_attr_check_format(__fmt, 0ull);                        \
        return simple_attr_open(inode, file, __get, __set, __fmt);      \
 }                                                                      \
-static struct file_operations __fops = {                               \
+static const struct file_operations __fops = {                         \
        .owner   = THIS_MODULE,                                         \
        .open    = __fops ## _open,                                     \
        .release = simple_attr_release,                                 \
index 297df45ffd0ad27e8219aaf3715a00d030f5bf54..7beaa21b3880051c341d55358b5312cdfb10c65a 100644 (file)
@@ -98,7 +98,7 @@ struct hd_struct {
        int make_it_fail;
 #endif
        unsigned long stamp;
-       int in_flight[2];
+       int in_flight;
 #ifdef CONFIG_SMP
        struct disk_stats *dkstats;
 #else
@@ -322,23 +322,18 @@ static inline void free_part_stats(struct hd_struct *part)
 #define part_stat_sub(cpu, gendiskp, field, subnd)                     \
        part_stat_add(cpu, gendiskp, field, -subnd)
 
-static inline void part_inc_in_flight(struct hd_struct *part, int rw)
+static inline void part_inc_in_flight(struct hd_struct *part)
 {
-       part->in_flight[rw]++;
+       part->in_flight++;
        if (part->partno)
-               part_to_disk(part)->part0.in_flight[rw]++;
+               part_to_disk(part)->part0.in_flight++;
 }
 
-static inline void part_dec_in_flight(struct hd_struct *part, int rw)
+static inline void part_dec_in_flight(struct hd_struct *part)
 {
-       part->in_flight[rw]--;
+       part->in_flight--;
        if (part->partno)
-               part_to_disk(part)->part0.in_flight[rw]--;
-}
-
-static inline int part_in_flight(struct hd_struct *part)
-{
-       return part->in_flight[0] + part->in_flight[1];
+               part_to_disk(part)->part0.in_flight--;
 }
 
 /* block/blk-core.c */
@@ -551,8 +546,6 @@ extern ssize_t part_size_show(struct device *dev,
                              struct device_attribute *attr, char *buf);
 extern ssize_t part_stat_show(struct device *dev,
                              struct device_attribute *attr, char *buf);
-extern ssize_t part_inflight_show(struct device *dev,
-                             struct device_attribute *attr, char *buf);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 extern ssize_t part_fail_show(struct device *dev,
                              struct device_attribute *attr, char *buf);
index 0d45b4e8d367e0ec6219f2a98a2b642d9f7e85f4..08bc776d05e27952c92d400eee106cd5d75d8cbe 100644 (file)
@@ -145,14 +145,14 @@ static inline int ip_mroute_opt(int opt)
 #endif
 
 #ifdef CONFIG_IP_MROUTE
-extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
+extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
 extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
 extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
 extern int ip_mr_init(void);
 #else
 static inline
 int ip_mroute_setsockopt(struct sock *sock,
-                        int optname, char __user *optval, int optlen)
+                        int optname, char __user *optval, unsigned int optlen)
 {
        return -ENOPROTOOPT;
 }
index 43dc97e32183b3f7ac2f444b65966bb62e6140e1..b191865a6ca37e71cb287db4151002523b018d1f 100644 (file)
@@ -134,7 +134,7 @@ static inline int ip6_mroute_opt(int opt)
 struct sock;
 
 #ifdef CONFIG_IPV6_MROUTE
-extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
+extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
 extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
 extern int ip6_mr_input(struct sk_buff *skb);
 extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
@@ -143,7 +143,7 @@ extern void ip6_mr_cleanup(void);
 #else
 static inline
 int ip6_mroute_setsockopt(struct sock *sock,
-                         int optname, char __user *optval, int optlen)
+                         int optname, char __user *optval, unsigned int optlen)
 {
        return -ENOPROTOOPT;
 }
index 9040a10584f7fe0b11ae5012d42e3cf5bec9fcf2..529a0931711da5875cc70e88953dbe9621afd5d3 100644 (file)
@@ -178,11 +178,11 @@ struct proto_ops {
        int             (*listen)    (struct socket *sock, int len);
        int             (*shutdown)  (struct socket *sock, int flags);
        int             (*setsockopt)(struct socket *sock, int level,
-                                     int optname, char __user *optval, int optlen);
+                                     int optname, char __user *optval, unsigned int optlen);
        int             (*getsockopt)(struct socket *sock, int level,
                                      int optname, char __user *optval, int __user *optlen);
        int             (*compat_setsockopt)(struct socket *sock, int level,
-                                     int optname, char __user *optval, int optlen);
+                                     int optname, char __user *optval, unsigned int optlen);
        int             (*compat_getsockopt)(struct socket *sock, int level,
                                      int optname, char __user *optval, int __user *optlen);
        int             (*sendmsg)   (struct kiocb *iocb, struct socket *sock,
@@ -256,7 +256,7 @@ extern int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
 extern int kernel_getsockopt(struct socket *sock, int level, int optname,
                             char *optval, int *optlen);
 extern int kernel_setsockopt(struct socket *sock, int level, int optname,
-                            char *optval, int optlen);
+                            char *optval, unsigned int optlen);
 extern int kernel_sendpage(struct socket *sock, struct page *page, int offset,
                           size_t size, int flags);
 extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
@@ -313,7 +313,7 @@ SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
 SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
 SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
 SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
-                        char __user *optval, int optlen), (sock, level, optname, optval, optlen)) \
+                        char __user *optval, unsigned int optlen), (sock, level, optname, optval, optlen)) \
 SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \
                         char __user *optval, int __user *optlen), (sock, level, optname, optval, optlen)) \
 SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len), \
index 48cfe51bfddcd989396d5c3fc2c71b2581f3caa2..6132b5e6d9d336e80571b4c5e3f4e99ac6427a61 100644 (file)
@@ -221,12 +221,12 @@ __ret;})
 
 /* Call setsockopt() */
 int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
-                 int len);
+                 unsigned int len);
 int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
                  int *len);
 
 int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
-               char __user *opt, int len);
+               char __user *opt, unsigned int len);
 int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
                char __user *opt, int *len);
 
index fa287f25138dc2a243e27825f92d670b210a4b6b..6673743946f776d2bd7a61bacd68afdc6fd94f36 100644 (file)
@@ -6,10 +6,10 @@
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
+#include <linux/ktime.h>
 #include <linux/wait.h>
 #include <linux/string.h>
 #include <linux/fs.h>
-#include <linux/sched.h>
 #include <asm/uaccess.h>
 
 /* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
index 731af71cddc9b1a8f3fb326f08f4d0bec048e08e..fcb9884df6181827120dcb64efd7a2104fd157d7 100644 (file)
@@ -114,8 +114,7 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent);
 int __must_check res_counter_charge_locked(struct res_counter *counter,
                unsigned long val);
 int __must_check res_counter_charge(struct res_counter *counter,
-               unsigned long val, struct res_counter **limit_fail_at,
-               struct res_counter **soft_limit_at);
+               unsigned long val, struct res_counter **limit_fail_at);
 
 /*
  * uncharge - tell that some portion of the resource is released
@@ -128,8 +127,7 @@ int __must_check res_counter_charge(struct res_counter *counter,
  */
 
 void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val);
-void res_counter_uncharge(struct res_counter *counter, unsigned long val,
-                               bool *was_soft_limit_excess);
+void res_counter_uncharge(struct res_counter *counter, unsigned long val);
 
 static inline bool res_counter_limit_check_locked(struct res_counter *cnt)
 {
index 5bbf8bf9efea73f5eb714cf97d8e8d2c1a5ef95c..7c3002832d05a62f98be2fcc9145807f618e9095 100644 (file)
@@ -40,8 +40,8 @@ extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
 
 extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
 
-extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, int,
-       int (*)(struct sock *, int, int, char __user *, int));
+extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, unsigned int,
+       int (*)(struct sock *, int, int, char __user *, unsigned int));
 extern int compat_mc_getsockopt(struct sock *, int, int, char __user *,
        int __user *, int (*)(struct sock *, int, int, char __user *,
                                int __user *));
index 03cffd9f64e3ee8413caf2d5f72368f00d5fbecb..696d6e4ce68a0e72b857b1d569c1bb98c5ceeca0 100644 (file)
@@ -48,13 +48,13 @@ struct inet_connection_sock_af_ops {
        u16         net_header_len;
        u16         sockaddr_len;
        int         (*setsockopt)(struct sock *sk, int level, int optname, 
-                                 char __user *optval, int optlen);
+                                 char __user *optval, unsigned int optlen);
        int         (*getsockopt)(struct sock *sk, int level, int optname, 
                                  char __user *optval, int __user *optlen);
 #ifdef CONFIG_COMPAT
        int         (*compat_setsockopt)(struct sock *sk,
                                int level, int optname,
-                               char __user *optval, int optlen);
+                               char __user *optval, unsigned int optlen);
        int         (*compat_getsockopt)(struct sock *sk,
                                int level, int optname,
                                char __user *optval, int __user *optlen);
@@ -332,5 +332,5 @@ extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
 extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
                                      char __user *optval, int __user *optlen);
 extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
-                                     char __user *optval, int optlen);
+                                     char __user *optval, unsigned int optlen);
 #endif /* _INET_CONNECTION_SOCK_H */
index 5b26a0bd178ecc031d357786f519bfdacde0f8eb..2f47e5482b552a1d5bf95a54d5101ab80ca0899a 100644 (file)
@@ -381,10 +381,10 @@ extern int ip_options_rcv_srr(struct sk_buff *skb);
 extern void    ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
 extern int     ip_cmsg_send(struct net *net,
                             struct msghdr *msg, struct ipcm_cookie *ipc);
-extern int     ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen);
+extern int     ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen);
 extern int     ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);
 extern int     compat_ip_setsockopt(struct sock *sk, int level,
-                       int optname, char __user *optval, int optlen);
+                       int optname, char __user *optval, unsigned int optlen);
 extern int     compat_ip_getsockopt(struct sock *sk, int level,
                        int optname, char __user *optval, int __user *optlen);
 extern int     ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
index ad9a5113025444d77d24fb0721e312c6ac83e9f6..8c31d8a0c1fe8812104bb91049cf208aea412b4a 100644 (file)
@@ -550,7 +550,7 @@ extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
 extern int                     ipv6_setsockopt(struct sock *sk, int level, 
                                                int optname,
                                                char __user *optval, 
-                                               int optlen);
+                                               unsigned int optlen);
 extern int                     ipv6_getsockopt(struct sock *sk, int level, 
                                                int optname,
                                                char __user *optval, 
@@ -559,7 +559,7 @@ extern int                  compat_ipv6_setsockopt(struct sock *sk,
                                                int level,
                                                int optname,
                                                char __user *optval,
-                                               int optlen);
+                                               unsigned int optlen);
 extern int                     compat_ipv6_getsockopt(struct sock *sk,
                                                int level,
                                                int optname,
index 42d00ced5eb876da48c61fcac021bd1658e532ca..6e5f0e0c7967e9f78589ba4f5d1f56ab09c2e2aa 100644 (file)
@@ -544,7 +544,7 @@ struct sctp_af {
                                         int level,
                                         int optname,
                                         char __user *optval,
-                                        int optlen);
+                                        unsigned int optlen);
        int             (*getsockopt)   (struct sock *sk,
                                         int level,
                                         int optname,
@@ -554,7 +554,7 @@ struct sctp_af {
                                         int level,
                                         int optname,
                                         char __user *optval,
-                                        int optlen);
+                                        unsigned int optlen);
        int             (*compat_getsockopt)    (struct sock *sk,
                                         int level,
                                         int optname,
index 950409dcec3d5763bf4822c4fb8599e20808c728..1621935aad5bc5b3e69299c136c685dd42dbff92 100644 (file)
@@ -624,7 +624,7 @@ struct proto {
        void                    (*shutdown)(struct sock *sk, int how);
        int                     (*setsockopt)(struct sock *sk, int level, 
                                        int optname, char __user *optval,
-                                       int optlen);
+                                       unsigned int optlen);
        int                     (*getsockopt)(struct sock *sk, int level, 
                                        int optname, char __user *optval, 
                                        int __user *option);     
@@ -632,7 +632,7 @@ struct proto {
        int                     (*compat_setsockopt)(struct sock *sk,
                                        int level,
                                        int optname, char __user *optval,
-                                       int optlen);
+                                       unsigned int optlen);
        int                     (*compat_getsockopt)(struct sock *sk,
                                        int level,
                                        int optname, char __user *optval,
@@ -951,7 +951,7 @@ extern void                 sock_rfree(struct sk_buff *skb);
 
 extern int                     sock_setsockopt(struct socket *sock, int level,
                                                int op, char __user *optval,
-                                               int optlen);
+                                               unsigned int optlen);
 
 extern int                     sock_getsockopt(struct socket *sock, int level,
                                                int op, char __user *optval, 
@@ -993,7 +993,7 @@ extern int                      sock_no_shutdown(struct socket *, int);
 extern int                     sock_no_getsockopt(struct socket *, int , int,
                                                   char __user *, int __user *);
 extern int                     sock_no_setsockopt(struct socket *, int, int,
-                                                  char __user *, int);
+                                                  char __user *, unsigned int);
 extern int                      sock_no_sendmsg(struct kiocb *, struct socket *,
                                                struct msghdr *, size_t);
 extern int                      sock_no_recvmsg(struct kiocb *, struct socket *,
@@ -1015,11 +1015,11 @@ extern int sock_common_getsockopt(struct socket *sock, int level, int optname,
 extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
                               struct msghdr *msg, size_t size, int flags);
 extern int sock_common_setsockopt(struct socket *sock, int level, int optname,
-                                 char __user *optval, int optlen);
+                                 char __user *optval, unsigned int optlen);
 extern int compat_sock_common_getsockopt(struct socket *sock, int level,
                int optname, char __user *optval, int __user *optlen);
 extern int compat_sock_common_setsockopt(struct socket *sock, int level,
-               int optname, char __user *optval, int optlen);
+               int optname, char __user *optval, unsigned int optlen);
 
 extern void sk_common_release(struct sock *sk);
 
index 56b76027b85eeb4c7e4de930750e9584f6326489..03a49c7033774c9769921e69cd233d55882ad667 100644 (file)
@@ -394,13 +394,13 @@ extern int                        tcp_getsockopt(struct sock *sk, int level,
                                               int __user *optlen);
 extern int                     tcp_setsockopt(struct sock *sk, int level, 
                                               int optname, char __user *optval, 
-                                              int optlen);
+                                              unsigned int optlen);
 extern int                     compat_tcp_getsockopt(struct sock *sk,
                                        int level, int optname,
                                        char __user *optval, int __user *optlen);
 extern int                     compat_tcp_setsockopt(struct sock *sk,
                                        int level, int optname,
-                                       char __user *optval, int optlen);
+                                       char __user *optval, unsigned int optlen);
 extern void                    tcp_set_keepalive(struct sock *sk, int val);
 extern int                     tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
                                            struct msghdr *msg,
index 5fb029f817a3574fb8b7648dbb793d2ff29248b5..f98abd2ce709bd5e784aa0ca79cd483a8ebbbbd5 100644 (file)
@@ -144,7 +144,7 @@ extern unsigned int udp_poll(struct file *file, struct socket *sock,
 extern int     udp_lib_getsockopt(struct sock *sk, int level, int optname,
                                   char __user *optval, int __user *optlen);
 extern int     udp_lib_setsockopt(struct sock *sk, int level, int optname,
-                                  char __user *optval, int optlen,
+                                  char __user *optval, unsigned int optlen,
                                   int (*push_pending_frames)(struct sock *));
 
 extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
index d86af94691c2c4148711f29880187b0587409581..00405b5f624a2d742a1d95d2a6fb59d530b6e369 100644 (file)
@@ -488,6 +488,39 @@ TRACE_EVENT(block_remap,
                  (unsigned long long)__entry->old_sector)
 );
 
+TRACE_EVENT(block_rq_remap,
+
+       TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
+                sector_t from),
+
+       TP_ARGS(q, rq, dev, from),
+
+       TP_STRUCT__entry(
+               __field( dev_t,         dev             )
+               __field( sector_t,      sector          )
+               __field( unsigned int,  nr_sector       )
+               __field( dev_t,         old_dev         )
+               __field( sector_t,      old_sector      )
+               __array( char,          rwbs,   6       )
+       ),
+
+       TP_fast_assign(
+               __entry->dev            = disk_devt(rq->rq_disk);
+               __entry->sector         = blk_rq_pos(rq);
+               __entry->nr_sector      = blk_rq_sectors(rq);
+               __entry->old_dev        = dev;
+               __entry->old_sector     = from;
+               blk_fill_rwbs_rq(__entry->rwbs, rq);
+       ),
+
+       TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
+                 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+                 (unsigned long long)__entry->sector,
+                 __entry->nr_sector,
+                 MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
+                 (unsigned long long)__entry->old_sector)
+);
+
 #endif /* _TRACE_BLOCK_H */
 
 /* This part must be outside protection */
index 7ccba4bc5e3b815a9ac9a9c5a0e40d8e70b5c780..ca83b73fba195ac643a594f9cae3abf4347c2f42 100644 (file)
@@ -703,7 +703,7 @@ static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
 static int cgroup_populate_dir(struct cgroup *cgrp);
 static const struct inode_operations cgroup_dir_inode_operations;
-static struct file_operations proc_cgroupstats_operations;
+static const struct file_operations proc_cgroupstats_operations;
 
 static struct backing_dev_info cgroup_backing_dev_info = {
        .name           = "cgroup",
@@ -1863,7 +1863,7 @@ static int cgroup_seqfile_release(struct inode *inode, struct file *file)
        return single_release(inode, file);
 }
 
-static struct file_operations cgroup_seqfile_operations = {
+static const struct file_operations cgroup_seqfile_operations = {
        .read = seq_read,
        .write = cgroup_file_write,
        .llseek = seq_lseek,
@@ -1922,7 +1922,7 @@ static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
        return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
 }
 
-static struct file_operations cgroup_file_operations = {
+static const struct file_operations cgroup_file_operations = {
        .read = cgroup_file_read,
        .write = cgroup_file_write,
        .llseek = generic_file_llseek,
@@ -3369,7 +3369,7 @@ static int cgroup_open(struct inode *inode, struct file *file)
        return single_open(file, proc_cgroup_show, pid);
 }
 
-struct file_operations proc_cgroup_operations = {
+const struct file_operations proc_cgroup_operations = {
        .open           = cgroup_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -3398,7 +3398,7 @@ static int cgroupstats_open(struct inode *inode, struct file *file)
        return single_open(file, proc_cgroupstats_show, NULL);
 }
 
-static struct file_operations proc_cgroupstats_operations = {
+static const struct file_operations proc_cgroupstats_operations = {
        .open = cgroupstats_open,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -3708,8 +3708,10 @@ static void check_for_release(struct cgroup *cgrp)
 void __css_put(struct cgroup_subsys_state *css)
 {
        struct cgroup *cgrp = css->cgroup;
+       int val;
        rcu_read_lock();
-       if (atomic_dec_return(&css->refcnt) == 1) {
+       val = atomic_dec_return(&css->refcnt);
+       if (val == 1) {
                if (notify_on_release(cgrp)) {
                        set_bit(CGRP_RELEASABLE, &cgrp->flags);
                        check_for_release(cgrp);
@@ -3717,6 +3719,7 @@ void __css_put(struct cgroup_subsys_state *css)
                cgroup_wakeup_rmdir_waiter(cgrp);
        }
        rcu_read_unlock();
+       WARN_ON_ONCE(val < 1);
 }
 
 /*
index cfadc1291d0badb247275feacb720fa3408b9c44..5240d75f4c60e95f95eb55e0cc46b448e2d6eb7c 100644 (file)
@@ -1333,7 +1333,7 @@ static int __kprobes kprobes_open(struct inode *inode, struct file *filp)
        return seq_open(filp, &kprobes_seq_ops);
 }
 
-static struct file_operations debugfs_kprobes_operations = {
+static const struct file_operations debugfs_kprobes_operations = {
        .open           = kprobes_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -1515,7 +1515,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
        return count;
 }
 
-static struct file_operations fops_kp = {
+static const struct file_operations fops_kp = {
        .read =         read_enabled_file_bool,
        .write =        write_enabled_file_bool,
 };
index fe748a86d452030b8d44fcb7731c1badeb93c33c..8b7d8805819d07d998467db967c777c04021ec9e 100644 (file)
@@ -1992,12 +1992,14 @@ static inline unsigned long layout_symtab(struct module *mod,
                                          Elf_Shdr *sechdrs,
                                          unsigned int symindex,
                                          unsigned int strindex,
-                                         const Elf_Hdr *hdr,
+                                         const Elf_Ehdr *hdr,
                                          const char *secstrings,
                                          unsigned long *pstroffs,
                                          unsigned long *strmap)
 {
+       return 0;
 }
+
 static inline void add_kallsyms(struct module *mod,
                                Elf_Shdr *sechdrs,
                                unsigned int shnum,
@@ -2081,9 +2083,8 @@ static noinline struct module *load_module(void __user *umod,
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
-#ifdef CONFIG_KALLSYMS
        unsigned long symoffs, stroffs, *strmap;
-#endif
+
        mm_segment_t old_fs;
 
        DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
index c89f5e9fd17397130836e77f9c178d7f2e280f0b..179e6ad80dc03a44a853641175a547c6153f360e 100644 (file)
@@ -93,7 +93,7 @@ static int rcudata_open(struct inode *inode, struct file *file)
        return single_open(file, show_rcudata, NULL);
 }
 
-static struct file_operations rcudata_fops = {
+static const struct file_operations rcudata_fops = {
        .owner = THIS_MODULE,
        .open = rcudata_open,
        .read = seq_read,
@@ -145,7 +145,7 @@ static int rcudata_csv_open(struct inode *inode, struct file *file)
        return single_open(file, show_rcudata_csv, NULL);
 }
 
-static struct file_operations rcudata_csv_fops = {
+static const struct file_operations rcudata_csv_fops = {
        .owner = THIS_MODULE,
        .open = rcudata_csv_open,
        .read = seq_read,
@@ -196,7 +196,7 @@ static int rcuhier_open(struct inode *inode, struct file *file)
        return single_open(file, show_rcuhier, NULL);
 }
 
-static struct file_operations rcuhier_fops = {
+static const struct file_operations rcuhier_fops = {
        .owner = THIS_MODULE,
        .open = rcuhier_open,
        .read = seq_read,
@@ -222,7 +222,7 @@ static int rcugp_open(struct inode *inode, struct file *file)
        return single_open(file, show_rcugp, NULL);
 }
 
-static struct file_operations rcugp_fops = {
+static const struct file_operations rcugp_fops = {
        .owner = THIS_MODULE,
        .open = rcugp_open,
        .read = seq_read,
@@ -276,7 +276,7 @@ static int rcu_pending_open(struct inode *inode, struct file *file)
        return single_open(file, show_rcu_pending, NULL);
 }
 
-static struct file_operations rcu_pending_fops = {
+static const struct file_operations rcu_pending_fops = {
        .owner = THIS_MODULE,
        .open = rcu_pending_open,
        .read = seq_read,
index 88faec23e83301e5b64490318aba2ac722dfb00c..bcdabf37c40b58165d29a2e7dc33b41ef9a6d547 100644 (file)
@@ -37,27 +37,17 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
 }
 
 int res_counter_charge(struct res_counter *counter, unsigned long val,
-                       struct res_counter **limit_fail_at,
-                       struct res_counter **soft_limit_fail_at)
+                       struct res_counter **limit_fail_at)
 {
        int ret;
        unsigned long flags;
        struct res_counter *c, *u;
 
        *limit_fail_at = NULL;
-       if (soft_limit_fail_at)
-               *soft_limit_fail_at = NULL;
        local_irq_save(flags);
        for (c = counter; c != NULL; c = c->parent) {
                spin_lock(&c->lock);
                ret = res_counter_charge_locked(c, val);
-               /*
-                * With soft limits, we return the highest ancestor
-                * that exceeds its soft limit
-                */
-               if (soft_limit_fail_at &&
-                       !res_counter_soft_limit_check_locked(c))
-                       *soft_limit_fail_at = c;
                spin_unlock(&c->lock);
                if (ret < 0) {
                        *limit_fail_at = c;
@@ -85,8 +75,7 @@ void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
        counter->usage -= val;
 }
 
-void res_counter_uncharge(struct res_counter *counter, unsigned long val,
-                               bool *was_soft_limit_excess)
+void res_counter_uncharge(struct res_counter *counter, unsigned long val)
 {
        unsigned long flags;
        struct res_counter *c;
@@ -94,9 +83,6 @@ void res_counter_uncharge(struct res_counter *counter, unsigned long val,
        local_irq_save(flags);
        for (c = counter; c != NULL; c = c->parent) {
                spin_lock(&c->lock);
-               if (was_soft_limit_excess)
-                       *was_soft_limit_excess =
-                               !res_counter_soft_limit_check_locked(c);
                res_counter_uncharge_locked(c, val);
                spin_unlock(&c->lock);
        }
index ee61f454a98b9005ed7055b6f3e4bba5f2036ebe..1535f3884b88ebd7c33bff7c0e5970a96980a29d 100644 (file)
@@ -780,7 +780,7 @@ static int sched_feat_open(struct inode *inode, struct file *filp)
        return single_open(filp, sched_feat_show, NULL);
 }
 
-static struct file_operations sched_feat_fops = {
+static const struct file_operations sched_feat_fops = {
        .open           = sched_feat_open,
        .write          = sched_feat_write,
        .read           = seq_read,
index fddd69d16e039a5d75f9093856d4abec8c6d10b6..1b5b7aa2fdfd094fec018efbc533b65a686b1339 100644 (file)
@@ -275,7 +275,7 @@ static int timer_list_open(struct inode *inode, struct file *filp)
        return single_open(filp, timer_list_show, NULL);
 }
 
-static struct file_operations timer_list_fops = {
+static const struct file_operations timer_list_fops = {
        .open           = timer_list_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
index 4cde8b9c716f39b778ab7dfe5ead8985c0eb2c97..ee5681f8d7ecd2f1429d5455ea2839f12921b42f 100644 (file)
@@ -395,7 +395,7 @@ static int tstats_open(struct inode *inode, struct file *filp)
        return single_open(filp, tstats_show, NULL);
 }
 
-static struct file_operations tstats_fops = {
+static const struct file_operations tstats_fops = {
        .open           = tstats_open,
        .read           = seq_read,
        .write          = tstats_write,
index 3eb159c277c85a7a9d30f3b94d1a68bfa52661b0..d9d6206e0b148f5c67e5ecda22a7c7992eec76d7 100644 (file)
@@ -855,6 +855,37 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
                        sizeof(r), &r);
 }
 
+/**
+ * blk_add_trace_rq_remap - Add a trace for a request-remap operation
+ * @q:         queue the io is for
+ * @rq:                the source request
+ * @dev:       target device
+ * @from:      source sector
+ *
+ * Description:
+ *     Device mapper remaps request to other devices.
+ *     Add a trace for that action.
+ *
+ **/
+static void blk_add_trace_rq_remap(struct request_queue *q,
+                                  struct request *rq, dev_t dev,
+                                  sector_t from)
+{
+       struct blk_trace *bt = q->blk_trace;
+       struct blk_io_trace_remap r;
+
+       if (likely(!bt))
+               return;
+
+       r.device_from = cpu_to_be32(dev);
+       r.device_to   = cpu_to_be32(disk_devt(rq->rq_disk));
+       r.sector_from = cpu_to_be64(from);
+
+       __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
+                       rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors,
+                       sizeof(r), &r);
+}
+
 /**
  * blk_add_driver_data - Add binary message with driver-specific data
  * @q:         queue the io is for
@@ -922,10 +953,13 @@ static void blk_register_tracepoints(void)
        WARN_ON(ret);
        ret = register_trace_block_remap(blk_add_trace_remap);
        WARN_ON(ret);
+       ret = register_trace_block_rq_remap(blk_add_trace_rq_remap);
+       WARN_ON(ret);
 }
 
 static void blk_unregister_tracepoints(void)
 {
+       unregister_trace_block_rq_remap(blk_add_trace_rq_remap);
        unregister_trace_block_remap(blk_add_trace_remap);
        unregister_trace_block_split(blk_add_trace_split);
        unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
@@ -1657,6 +1691,11 @@ int blk_trace_init_sysfs(struct device *dev)
        return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
 }
 
+void blk_trace_remove_sysfs(struct device *dev)
+{
+       sysfs_remove_group(&dev->kobj, &blk_trace_attr_group);
+}
+
 #endif /* CONFIG_BLK_DEV_IO_TRACE */
 
 #ifdef CONFIG_EVENT_TRACING
index b91839e9e892a08eb7726dc7b668d289c16f09ad..33bed5e67a2110b2201856b8828b457110147728 100644 (file)
@@ -1771,7 +1771,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
                 * advance both strings to next white space
                 */
                if (*fmt == '*') {
-                       while (!isspace(*fmt) && *fmt)
+                       while (!isspace(*fmt) && *fmt != '%' && *fmt)
                                fmt++;
                        while (!isspace(*str) && *str)
                                str++;
index e2b98a6875c079b36f103b724130462591094735..f99f5991d6bba1b5ec224f0631124144a6c0a8bb 100644 (file)
@@ -313,7 +313,8 @@ soft_limit_tree_from_page(struct page *page)
 static void
 __mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
                                struct mem_cgroup_per_zone *mz,
-                               struct mem_cgroup_tree_per_zone *mctz)
+                               struct mem_cgroup_tree_per_zone *mctz,
+                               unsigned long long new_usage_in_excess)
 {
        struct rb_node **p = &mctz->rb_root.rb_node;
        struct rb_node *parent = NULL;
@@ -322,7 +323,9 @@ __mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
        if (mz->on_tree)
                return;
 
-       mz->usage_in_excess = res_counter_soft_limit_excess(&mem->res);
+       mz->usage_in_excess = new_usage_in_excess;
+       if (!mz->usage_in_excess)
+               return;
        while (*p) {
                parent = *p;
                mz_node = rb_entry(parent, struct mem_cgroup_per_zone,
@@ -352,16 +355,6 @@ __mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
        mz->on_tree = false;
 }
 
-static void
-mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
-                               struct mem_cgroup_per_zone *mz,
-                               struct mem_cgroup_tree_per_zone *mctz)
-{
-       spin_lock(&mctz->lock);
-       __mem_cgroup_insert_exceeded(mem, mz, mctz);
-       spin_unlock(&mctz->lock);
-}
-
 static void
 mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
                                struct mem_cgroup_per_zone *mz,
@@ -392,34 +385,36 @@ static bool mem_cgroup_soft_limit_check(struct mem_cgroup *mem)
 
 static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page)
 {
-       unsigned long long prev_usage_in_excess, new_usage_in_excess;
-       bool updated_tree = false;
+       unsigned long long excess;
        struct mem_cgroup_per_zone *mz;
        struct mem_cgroup_tree_per_zone *mctz;
-
-       mz = mem_cgroup_zoneinfo(mem, page_to_nid(page), page_zonenum(page));
+       int nid = page_to_nid(page);
+       int zid = page_zonenum(page);
        mctz = soft_limit_tree_from_page(page);
 
        /*
-        * We do updates in lazy mode, mem's are removed
-        * lazily from the per-zone, per-node rb tree
+        * Necessary to update all ancestors when hierarchy is used.
+        * because their event counter is not touched.
         */
-       prev_usage_in_excess = mz->usage_in_excess;
-
-       new_usage_in_excess = res_counter_soft_limit_excess(&mem->res);
-       if (prev_usage_in_excess) {
-               mem_cgroup_remove_exceeded(mem, mz, mctz);
-               updated_tree = true;
-       }
-       if (!new_usage_in_excess)
-               goto done;
-       mem_cgroup_insert_exceeded(mem, mz, mctz);
-
-done:
-       if (updated_tree) {
-               spin_lock(&mctz->lock);
-               mz->usage_in_excess = new_usage_in_excess;
-               spin_unlock(&mctz->lock);
+       for (; mem; mem = parent_mem_cgroup(mem)) {
+               mz = mem_cgroup_zoneinfo(mem, nid, zid);
+               excess = res_counter_soft_limit_excess(&mem->res);
+               /*
+                * We have to update the tree if mz is on RB-tree or
+                * mem is over its softlimit.
+                */
+               if (excess || mz->on_tree) {
+                       spin_lock(&mctz->lock);
+                       /* if on-tree, remove it */
+                       if (mz->on_tree)
+                               __mem_cgroup_remove_exceeded(mem, mz, mctz);
+                       /*
+                        * Insert again. mz->usage_in_excess will be updated.
+                        * If excess is 0, no tree ops.
+                        */
+                       __mem_cgroup_insert_exceeded(mem, mz, mctz, excess);
+                       spin_unlock(&mctz->lock);
+               }
        }
 }
 
@@ -447,9 +442,10 @@ static struct mem_cgroup_per_zone *
 __mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz)
 {
        struct rb_node *rightmost = NULL;
-       struct mem_cgroup_per_zone *mz = NULL;
+       struct mem_cgroup_per_zone *mz;
 
 retry:
+       mz = NULL;
        rightmost = rb_last(&mctz->rb_root);
        if (!rightmost)
                goto done;              /* Nothing to reclaim from */
@@ -1270,9 +1266,9 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                        gfp_t gfp_mask, struct mem_cgroup **memcg,
                        bool oom, struct page *page)
 {
-       struct mem_cgroup *mem, *mem_over_limit, *mem_over_soft_limit;
+       struct mem_cgroup *mem, *mem_over_limit;
        int nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
-       struct res_counter *fail_res, *soft_fail_res = NULL;
+       struct res_counter *fail_res;
 
        if (unlikely(test_thread_flag(TIF_MEMDIE))) {
                /* Don't account this! */
@@ -1304,17 +1300,16 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
 
                if (mem_cgroup_is_root(mem))
                        goto done;
-               ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res,
-                                               &soft_fail_res);
+               ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res);
                if (likely(!ret)) {
                        if (!do_swap_account)
                                break;
                        ret = res_counter_charge(&mem->memsw, PAGE_SIZE,
-                                                       &fail_res, NULL);
+                                                       &fail_res);
                        if (likely(!ret))
                                break;
                        /* mem+swap counter fails */
-                       res_counter_uncharge(&mem->res, PAGE_SIZE, NULL);
+                       res_counter_uncharge(&mem->res, PAGE_SIZE);
                        flags |= MEM_CGROUP_RECLAIM_NOSWAP;
                        mem_over_limit = mem_cgroup_from_res_counter(fail_res,
                                                                        memsw);
@@ -1353,16 +1348,11 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                }
        }
        /*
-        * Insert just the ancestor, we should trickle down to the correct
-        * cgroup for reclaim, since the other nodes will be below their
-        * soft limit
+        * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree.
+        * if they exceeds softlimit.
         */
-       if (soft_fail_res) {
-               mem_over_soft_limit =
-                       mem_cgroup_from_res_counter(soft_fail_res, res);
-               if (mem_cgroup_soft_limit_check(mem_over_soft_limit))
-                       mem_cgroup_update_tree(mem_over_soft_limit, page);
-       }
+       if (mem_cgroup_soft_limit_check(mem))
+               mem_cgroup_update_tree(mem, page);
 done:
        return 0;
 nomem:
@@ -1437,10 +1427,9 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
        if (unlikely(PageCgroupUsed(pc))) {
                unlock_page_cgroup(pc);
                if (!mem_cgroup_is_root(mem)) {
-                       res_counter_uncharge(&mem->res, PAGE_SIZE, NULL);
+                       res_counter_uncharge(&mem->res, PAGE_SIZE);
                        if (do_swap_account)
-                               res_counter_uncharge(&mem->memsw, PAGE_SIZE,
-                                                       NULL);
+                               res_counter_uncharge(&mem->memsw, PAGE_SIZE);
                }
                css_put(&mem->css);
                return;
@@ -1519,7 +1508,7 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
                goto out;
 
        if (!mem_cgroup_is_root(from))
-               res_counter_uncharge(&from->res, PAGE_SIZE, NULL);
+               res_counter_uncharge(&from->res, PAGE_SIZE);
        mem_cgroup_charge_statistics(from, pc, false);
 
        page = pc->page;
@@ -1539,7 +1528,7 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
        }
 
        if (do_swap_account && !mem_cgroup_is_root(from))
-               res_counter_uncharge(&from->memsw, PAGE_SIZE, NULL);
+               res_counter_uncharge(&from->memsw, PAGE_SIZE);
        css_put(&from->css);
 
        css_get(&to->css);
@@ -1610,9 +1599,9 @@ uncharge:
        css_put(&parent->css);
        /* uncharge if move fails */
        if (!mem_cgroup_is_root(parent)) {
-               res_counter_uncharge(&parent->res, PAGE_SIZE, NULL);
+               res_counter_uncharge(&parent->res, PAGE_SIZE);
                if (do_swap_account)
-                       res_counter_uncharge(&parent->memsw, PAGE_SIZE, NULL);
+                       res_counter_uncharge(&parent->memsw, PAGE_SIZE);
        }
        return ret;
 }
@@ -1803,8 +1792,7 @@ __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr,
                         * calling css_tryget
                         */
                        if (!mem_cgroup_is_root(memcg))
-                               res_counter_uncharge(&memcg->memsw, PAGE_SIZE,
-                                                       NULL);
+                               res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
                        mem_cgroup_swap_statistics(memcg, false);
                        mem_cgroup_put(memcg);
                }
@@ -1831,9 +1819,9 @@ void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *mem)
        if (!mem)
                return;
        if (!mem_cgroup_is_root(mem)) {
-               res_counter_uncharge(&mem->res, PAGE_SIZE, NULL);
+               res_counter_uncharge(&mem->res, PAGE_SIZE);
                if (do_swap_account)
-                       res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL);
+                       res_counter_uncharge(&mem->memsw, PAGE_SIZE);
        }
        css_put(&mem->css);
 }
@@ -1848,7 +1836,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
        struct page_cgroup *pc;
        struct mem_cgroup *mem = NULL;
        struct mem_cgroup_per_zone *mz;
-       bool soft_limit_excess = false;
 
        if (mem_cgroup_disabled())
                return NULL;
@@ -1888,10 +1875,10 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
        }
 
        if (!mem_cgroup_is_root(mem)) {
-               res_counter_uncharge(&mem->res, PAGE_SIZE, &soft_limit_excess);
+               res_counter_uncharge(&mem->res, PAGE_SIZE);
                if (do_swap_account &&
                                (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT))
-                       res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL);
+                       res_counter_uncharge(&mem->memsw, PAGE_SIZE);
        }
        if (ctype == MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
                mem_cgroup_swap_statistics(mem, true);
@@ -1908,7 +1895,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
        mz = page_cgroup_zoneinfo(pc);
        unlock_page_cgroup(pc);
 
-       if (soft_limit_excess && mem_cgroup_soft_limit_check(mem))
+       if (mem_cgroup_soft_limit_check(mem))
                mem_cgroup_update_tree(mem, page);
        /* at swapout, this memcg will be accessed to record to swap */
        if (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
@@ -1986,7 +1973,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t ent)
                 * This memcg can be obsolete one. We avoid calling css_tryget
                 */
                if (!mem_cgroup_is_root(memcg))
-                       res_counter_uncharge(&memcg->memsw, PAGE_SIZE, NULL);
+                       res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
                mem_cgroup_swap_statistics(memcg, false);
                mem_cgroup_put(memcg);
        }
@@ -2233,6 +2220,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
        unsigned long reclaimed;
        int loop = 0;
        struct mem_cgroup_tree_per_zone *mctz;
+       unsigned long long excess;
 
        if (order > 0)
                return 0;
@@ -2284,9 +2272,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
                                        break;
                        } while (1);
                }
-               mz->usage_in_excess =
-                       res_counter_soft_limit_excess(&mz->mem->res);
                __mem_cgroup_remove_exceeded(mz->mem, mz, mctz);
+               excess = res_counter_soft_limit_excess(&mz->mem->res);
                /*
                 * One school of thought says that we should not add
                 * back the node to the tree if reclaim returns 0.
@@ -2295,8 +2282,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
                 * memory to reclaim from. Consider this as a longer
                 * term TODO.
                 */
-               if (mz->usage_in_excess)
-                       __mem_cgroup_insert_exceeded(mz->mem, mz, mctz);
+               /* If excess == 0, no tree ops */
+               __mem_cgroup_insert_exceeded(mz->mem, mz, mctz, excess);
                spin_unlock(&mctz->lock);
                css_put(&mz->mem->css);
                loop++;
index 28aafe2b530668b03c766619a83873ee2a91087e..dd43373a483fa764ce35a3bdc541ea4148653af4 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -242,8 +242,8 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 }
 
 /*
- * At what user virtual address is page expected in vma? checking that the
- * page matches the vma: currently only used on anon pages, by unuse_vma;
+ * At what user virtual address is page expected in vma?
+ * checking that the page matches the vma.
  */
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
index 4de7f02f820b03bfcf36b5fc8d6827b5eecd38cb..a1bc6b9af9a23634f4185e85775d94a6500bbb0e 100644 (file)
@@ -1974,12 +1974,14 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
                goto bad_swap;
        }
 
-       if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
-               p->flags |= SWP_SOLIDSTATE;
-               p->cluster_next = 1 + (random32() % p->highest_bit);
+       if (p->bdev) {
+               if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
+                       p->flags |= SWP_SOLIDSTATE;
+                       p->cluster_next = 1 + (random32() % p->highest_bit);
+               }
+               if (discard_swap(p) == 0)
+                       p->flags |= SWP_DISCARDABLE;
        }
-       if (discard_swap(p) == 0)
-               p->flags |= SWP_DISCARDABLE;
 
        mutex_lock(&swapon_mutex);
        spin_lock(&swap_lock);
index 8c4d843eb17f46bbec50847aa1352580adcd1c26..950bd16d2383463851c1f3f919c254ac8f89fdae 100644 (file)
@@ -679,7 +679,7 @@ static int check_qos(const struct atm_qos *qos)
 }
 
 int vcc_setsockopt(struct socket *sock, int level, int optname,
-                  char __user *optval, int optlen)
+                  char __user *optval, unsigned int optlen)
 {
        struct atm_vcc *vcc;
        unsigned long value;
index 92e2981f479f920f0dfe3815cd9c5734af81a3aa..f48a76b6cdf48845a5834800f6716113c9c95914 100644 (file)
@@ -21,7 +21,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
 int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int vcc_setsockopt(struct socket *sock, int level, int optname,
-                  char __user *optval, int optlen);
+                  char __user *optval, unsigned int optlen);
 int vcc_getsockopt(struct socket *sock, int level, int optname,
                   char __user *optval, int __user *optlen);
 
index e1d22d9430dd2c0b40469d134b82ab7ad5942bc8..d4c024504f998b719d7cdb47a52abaa8830be44d 100644 (file)
@@ -59,7 +59,7 @@ static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr,
 }
 
 static int pvc_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int error;
index 7b831b526d0bce4fccb9204a4c9ee7adc3c3bafc..f90d143c4b2592d6ed2145724d580911b9839c28 100644 (file)
@@ -446,7 +446,7 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
 
 
 static int svc_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct atm_vcc *vcc = ATM_SD(sock);
index 4102de1022eece06825ea8fa70e101b006f6e67c..f454607303717d2f1339cfd901e6b2ae5ec8437f 100644 (file)
@@ -534,7 +534,7 @@ ax25_cb *ax25_create_cb(void)
  */
 
 static int ax25_setsockopt(struct socket *sock, int level, int optname,
-       char __user *optval, int optlen)
+       char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        ax25_cb *ax25;
@@ -901,7 +901,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
 
        sock_init_data(NULL, sk);
 
-       sk->sk_destruct = ax25_free_sock;
        sk->sk_type     = osk->sk_type;
        sk->sk_priority = osk->sk_priority;
        sk->sk_protocol = osk->sk_protocol;
@@ -939,6 +938,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
        }
 
        sk->sk_protinfo = ax25;
+       sk->sk_destruct = ax25_free_sock;
        ax25->sk    = sk;
 
        return sk;
index 4f9621f759a010d7e2403660103a780341f77e14..75302a986067daebc76e4fba40c9c6a92d6de3bf 100644 (file)
@@ -466,7 +466,7 @@ drop:
        goto done;
 }
 
-static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
+static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
 {
        struct hci_ufilter uf = { .opcode = 0 };
        struct sock *sk = sock->sk;
index b03012564647dc21216059e4ffbcacb78da7389a..555d9da1869b2fa3daca87eef3f88974a6edb0c8 100644 (file)
@@ -1698,7 +1698,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
        return bt_sock_recvmsg(iocb, sock, msg, len, flags);
 }
 
-static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
+static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct l2cap_options opts;
@@ -1755,7 +1755,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
        return err;
 }
 
-static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct bt_security sec;
index 0b85e8116859b21592d52d09f32e1ceb1bdad1f7..8a20aaf1f2316676564501c49bb59c3fe56c898b 100644 (file)
@@ -730,7 +730,7 @@ out:
        return copied ? : err;
 }
 
-static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
+static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int err = 0;
@@ -766,7 +766,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
        return err;
 }
 
-static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct bt_security sec;
index 13c27f17192c6f3aa4fe1bee6c1a12643497b850..77f4153bdb5e5ebe434487497d1e8d3ed0253cbf 100644 (file)
@@ -644,7 +644,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        return err;
 }
 
-static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int err = 0;
index db3152df7d2b627fd2484c14734e9a084d3e93a0..b5e897922d32e85986e5a2ea949f43fca3d32884 100644 (file)
@@ -411,7 +411,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
 }
 
 static int raw_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct raw_sock *ro = raw_sk(sk);
index 12728b17a226ebfc6e76351dd131f09e3d1de2e4..a407c3addbae432913a20dce2560d2bab1d248f2 100644 (file)
@@ -331,7 +331,7 @@ struct compat_sock_fprog {
 };
 
 static int do_set_attach_filter(struct socket *sock, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
        struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
@@ -351,7 +351,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname,
 }
 
 static int do_set_sock_timeout(struct socket *sock, int level,
-               int optname, char __user *optval, int optlen)
+               int optname, char __user *optval, unsigned int optlen)
 {
        struct compat_timeval __user *up = (struct compat_timeval __user *) optval;
        struct timeval ktime;
@@ -373,7 +373,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
 }
 
 static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        if (optname == SO_ATTACH_FILTER)
                return do_set_attach_filter(sock, level, optname,
@@ -385,7 +385,7 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
 }
 
 asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        int err;
        struct socket *sock;
@@ -558,8 +558,8 @@ struct compat_group_filter {
 
 
 int compat_mc_setsockopt(struct sock *sock, int level, int optname,
-       char __user *optval, int optlen,
-       int (*setsockopt)(struct sock *,int,int,char __user *,int))
+       char __user *optval, unsigned int optlen,
+       int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int))
 {
        char __user     *koptval = optval;
        int             koptlen = optlen;
index 560c8c9c03ab3ccfef96bfd1eed5fc195c4b1a75..b8f74cfb1bfdf1365494e87a1b712834f936f287 100644 (file)
@@ -2288,6 +2288,9 @@ int netif_receive_skb(struct sk_buff *skb)
        int ret = NET_RX_DROP;
        __be16 type;
 
+       if (!skb->tstamp.tv64)
+               net_timestamp(skb);
+
        if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
                return NET_RX_SUCCESS;
 
@@ -2295,9 +2298,6 @@ int netif_receive_skb(struct sk_buff *skb)
        if (netpoll_receive_skb(skb))
                return NET_RX_DROP;
 
-       if (!skb->tstamp.tv64)
-               net_timestamp(skb);
-
        if (!skb->iif)
                skb->iif = skb->dev->ifindex;
 
index 4d11c28ca8ca0f1b2dbbedb3a9e569a983087f40..b69455217ed6270fae1b3d6c4b011cf53b7a7f95 100644 (file)
@@ -2105,15 +2105,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
 static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 {
        ktime_t start_time, end_time;
-       s32 remaining;
+       s64 remaining;
        struct hrtimer_sleeper t;
 
        hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
        hrtimer_set_expires(&t.timer, spin_until);
 
        remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer));
-       if (remaining <= 0)
+       if (remaining <= 0) {
+               pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);
                return;
+       }
 
        start_time = ktime_now();
        if (remaining < 100)
index 524712a7b154c4627df17c1a6655eb941711cce4..7626b6aacd685551cf13bf5fe8fbbbbc6105e56f 100644 (file)
@@ -446,7 +446,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
  */
 
 int sock_setsockopt(struct socket *sock, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int val;
@@ -1228,17 +1228,22 @@ void __init sk_init(void)
 void sock_wfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
-       int res;
+       unsigned int len = skb->truesize;
 
-       /* In case it might be waiting for more memory. */
-       res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc);
-       if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE))
+       if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
+               /*
+                * Keep a reference on sk_wmem_alloc, this will be released
+                * after sk_write_space() call
+                */
+               atomic_sub(len - 1, &sk->sk_wmem_alloc);
                sk->sk_write_space(sk);
+               len = 1;
+       }
        /*
-        * if sk_wmem_alloc reached 0, we are last user and should
-        * free this sock, as sk_free() call could not do it.
+        * if sk_wmem_alloc reaches 0, we must finish what sk_free()
+        * could not do because of in-flight packets
         */
-       if (res == 0)
+       if (atomic_sub_and_test(len, &sk->sk_wmem_alloc))
                __sk_free(sk);
 }
 EXPORT_SYMBOL(sock_wfree);
@@ -1697,7 +1702,7 @@ int sock_no_shutdown(struct socket *sock, int how)
 EXPORT_SYMBOL(sock_no_shutdown);
 
 int sock_no_setsockopt(struct socket *sock, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        return -EOPNOTSUPP;
 }
@@ -2018,7 +2023,7 @@ EXPORT_SYMBOL(sock_common_recvmsg);
  *     Set socket options on an inet socket.
  */
 int sock_common_setsockopt(struct socket *sock, int level, int optname,
-                          char __user *optval, int optlen)
+                          char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
 
@@ -2028,7 +2033,7 @@ EXPORT_SYMBOL(sock_common_setsockopt);
 
 #ifdef CONFIG_COMPAT
 int compat_sock_common_setsockopt(struct socket *sock, int level, int optname,
-                                 char __user *optval, int optlen)
+                                 char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
 
index d6bc47363b1c0b75006b4fc95556515d90e3088c..5ef32c2f0d6a964a9ab35e813798adbe209b71a6 100644 (file)
@@ -290,14 +290,14 @@ extern int           dccp_disconnect(struct sock *sk, int flags);
 extern int        dccp_getsockopt(struct sock *sk, int level, int optname,
                                   char __user *optval, int __user *optlen);
 extern int        dccp_setsockopt(struct sock *sk, int level, int optname,
-                                  char __user *optval, int optlen);
+                                  char __user *optval, unsigned int optlen);
 #ifdef CONFIG_COMPAT
 extern int        compat_dccp_getsockopt(struct sock *sk,
                                int level, int optname,
                                char __user *optval, int __user *optlen);
 extern int        compat_dccp_setsockopt(struct sock *sk,
                                int level, int optname,
-                               char __user *optval, int optlen);
+                               char __user *optval, unsigned int optlen);
 #endif
 extern int        dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern int        dccp_sendmsg(struct kiocb *iocb, struct sock *sk,
index bc4467082a00830f98fdd0c3f0c6b4738a4c0590..a156319fd0acd53a65cfae08992d97c27c9a1058 100644 (file)
@@ -393,7 +393,7 @@ out:
 EXPORT_SYMBOL_GPL(dccp_ioctl);
 
 static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
-                                  char __user *optval, int optlen)
+                                  char __user *optval, unsigned int optlen)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        struct dccp_service_list *sl = NULL;
@@ -464,7 +464,7 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx)
 }
 
 static int dccp_setsockopt_ccid(struct sock *sk, int type,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        u8 *val;
        int rc = 0;
@@ -494,7 +494,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type,
 }
 
 static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
-               char __user *optval, int optlen)
+               char __user *optval, unsigned int optlen)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        int val, err = 0;
@@ -546,7 +546,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
 }
 
 int dccp_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        if (level != SOL_DCCP)
                return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
@@ -559,7 +559,7 @@ EXPORT_SYMBOL_GPL(dccp_setsockopt);
 
 #ifdef CONFIG_COMPAT
 int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
-                          char __user *optval, int optlen)
+                          char __user *optval, unsigned int optlen)
 {
        if (level != SOL_DCCP)
                return inet_csk_compat_setsockopt(sk, level, optname,
index 77d40289653cf0e739e5893e0e053c2145d6156a..7a58c87baf172f9384fab475f8243eab58716e58 100644 (file)
@@ -157,7 +157,7 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
 static atomic_t decnet_memory_allocated;
 
-static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags);
+static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
 static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
 
 static struct hlist_head *dn_find_list(struct sock *sk)
@@ -1325,7 +1325,7 @@ out:
        return err;
 }
 
-static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int err;
@@ -1337,7 +1337,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
        return err;
 }
 
-static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags)
+static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags)
 {
        struct  sock *sk = sock->sk;
        struct dn_scp *scp = DN_SK(sk);
index 51593a48f2ddae396a97395239ca7f7c1aad5859..a413b1bf4465828860d9052d7fad828330edce89 100644 (file)
@@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
 }
 
 static int dgram_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        struct dgram_sock *ro = dgram_sk(sk);
        int val;
index 13198859982e64baf80b97463af6e0b70bc75a50..30e74eee07d664755882ef4f16b4ecf901baf7c2 100644 (file)
@@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
 }
 
 static int raw_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        return -EOPNOTSUPP;
 }
index 58c4b0f7c4aae333e5767e331b84bebbe4845bd0..57737b8d1711a9348ca7000963eb4e65f3680db7 100644 (file)
@@ -1119,6 +1119,7 @@ int inet_sk_rebuild_header(struct sock *sk)
 {
        struct flowi fl = {
                .oif = sk->sk_bound_dev_if,
+               .mark = sk->sk_mark,
                .nl_u = {
                        .ip4_u = {
                                .daddr  = daddr,
index 22cd19ee44e52f5b94788e37dd6b5dc02f018eae..4351ca2cf0b8554eadd258295d44a93455f3e506 100644 (file)
@@ -714,7 +714,7 @@ int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
 EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt);
 
 int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
-                              char __user *optval, int optlen)
+                              char __user *optval, unsigned int optlen)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
 
index 9fe5d7b81580fe8b8768b03e4fff05f9059d14c6..f9895180f4818cf73f55bd1183c07dfbf852477e 100644 (file)
@@ -335,6 +335,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
 
                {
                        struct flowi fl = { .oif = sk->sk_bound_dev_if,
+                                           .mark = sk->sk_mark,
                                            .nl_u = { .ip4_u =
                                                      { .daddr = daddr,
                                                        .saddr = inet->saddr,
index 5a0693576e821c628edfb3f436243a0f8b107d4a..0c0b6e363a20a9ac2e16b0ba22e816b7327ee6bc 100644 (file)
@@ -440,7 +440,7 @@ out:
  */
 
 static int do_ip_setsockopt(struct sock *sk, int level,
-                           int optname, char __user *optval, int optlen)
+                           int optname, char __user *optval, unsigned int optlen)
 {
        struct inet_sock *inet = inet_sk(sk);
        int val = 0, err;
@@ -950,7 +950,7 @@ e_inval:
 }
 
 int ip_setsockopt(struct sock *sk, int level,
-               int optname, char __user *optval, int optlen)
+               int optname, char __user *optval, unsigned int optlen)
 {
        int err;
 
@@ -975,7 +975,7 @@ EXPORT_SYMBOL(ip_setsockopt);
 
 #ifdef CONFIG_COMPAT
 int compat_ip_setsockopt(struct sock *sk, int level, int optname,
-                        char __user *optval, int optlen)
+                        char __user *optval, unsigned int optlen)
 {
        int err;
 
index c43ec2d51ce21dcb8666785f52bbd5417d868a0e..630a56df7b47ee80c9c77dcbb62048dc73ed9fc5 100644 (file)
@@ -931,7 +931,7 @@ static void mrtsock_destruct(struct sock *sk)
  *     MOSPF/PIM router set up we can clean this up.
  */
 
-int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
+int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
 {
        int ret;
        struct vifctl vif;
index ebb1e5848bc6639703d88029ea40231b343a06c1..757c9171e7c25b021c21d26a681d5238fa0017c1 100644 (file)
@@ -741,7 +741,7 @@ out:        return ret;
 }
 
 static int do_raw_setsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        if (optname == ICMP_FILTER) {
                if (inet_sk(sk)->num != IPPROTO_ICMP)
@@ -753,7 +753,7 @@ static int do_raw_setsockopt(struct sock *sk, int level, int optname,
 }
 
 static int raw_setsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        if (level != SOL_RAW)
                return ip_setsockopt(sk, level, optname, optval, optlen);
@@ -762,7 +762,7 @@ static int raw_setsockopt(struct sock *sk, int level, int optname,
 
 #ifdef CONFIG_COMPAT
 static int compat_raw_setsockopt(struct sock *sk, int level, int optname,
-                                char __user *optval, int optlen)
+                                char __user *optval, unsigned int optlen)
 {
        if (level != SOL_RAW)
                return compat_ip_setsockopt(sk, level, optname, optval, optlen);
index 21387ebabf00e491f428c11131a467c61c9150b9..64d0af675823c7fe18d15f53c8d48224105f7c1b 100644 (file)
@@ -580,7 +580,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
 
        lock_sock(sk);
 
-       timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK);
+       timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK);
        while (tss.len) {
                ret = __tcp_splice_read(sk, &tss);
                if (ret < 0)
@@ -2032,7 +2032,7 @@ int tcp_disconnect(struct sock *sk, int flags)
  *     Socket option code for TCP.
  */
 static int do_tcp_setsockopt(struct sock *sk, int level,
-               int optname, char __user *optval, int optlen)
+               int optname, char __user *optval, unsigned int optlen)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2047,7 +2047,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                        return -EINVAL;
 
                val = strncpy_from_user(name, optval,
-                                       min(TCP_CA_NAME_MAX-1, optlen));
+                                       min_t(long, TCP_CA_NAME_MAX-1, optlen));
                if (val < 0)
                        return -EFAULT;
                name[val] = 0;
@@ -2220,7 +2220,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
 }
 
 int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
-                  int optlen)
+                  unsigned int optlen)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -2232,7 +2232,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
 
 #ifdef CONFIG_COMPAT
 int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        if (level != SOL_TCP)
                return inet_csk_compat_setsockopt(sk, level, optname,
index 5200aab0ca978866de729079af5c640eee7473fb..fcd278a7080e1656060cd5f57e38764bec3bdb74 100644 (file)
@@ -361,6 +361,7 @@ static inline int tcp_urg_mode(const struct tcp_sock *tp)
 #define OPTION_SACK_ADVERTISE  (1 << 0)
 #define OPTION_TS              (1 << 1)
 #define OPTION_MD5             (1 << 2)
+#define OPTION_WSCALE          (1 << 3)
 
 struct tcp_out_options {
        u8 options;             /* bit field of OPTION_* */
@@ -427,7 +428,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
                               TCPOLEN_SACK_PERM);
        }
 
-       if (unlikely(opts->ws)) {
+       if (unlikely(OPTION_WSCALE & opts->options)) {
                *ptr++ = htonl((TCPOPT_NOP << 24) |
                               (TCPOPT_WINDOW << 16) |
                               (TCPOLEN_WINDOW << 8) |
@@ -494,8 +495,8 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
        }
        if (likely(sysctl_tcp_window_scaling)) {
                opts->ws = tp->rx_opt.rcv_wscale;
-               if (likely(opts->ws))
-                       size += TCPOLEN_WSCALE_ALIGNED;
+               opts->options |= OPTION_WSCALE;
+               size += TCPOLEN_WSCALE_ALIGNED;
        }
        if (likely(sysctl_tcp_sack)) {
                opts->options |= OPTION_SACK_ADVERTISE;
@@ -537,8 +538,8 @@ static unsigned tcp_synack_options(struct sock *sk,
 
        if (likely(ireq->wscale_ok)) {
                opts->ws = ireq->rcv_wscale;
-               if (likely(opts->ws))
-                       size += TCPOLEN_WSCALE_ALIGNED;
+               opts->options |= OPTION_WSCALE;
+               size += TCPOLEN_WSCALE_ALIGNED;
        }
        if (likely(doing_ts)) {
                opts->options |= OPTION_TS;
index ebaaa7f973d70a8dd4038b30c621adf01a4c6268..6ec6a8a4a224236acae5393d997727c7804c07cb 100644 (file)
@@ -696,6 +696,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
        if (rt == NULL) {
                struct flowi fl = { .oif = ipc.oif,
+                                   .mark = sk->sk_mark,
                                    .nl_u = { .ip4_u =
                                              { .daddr = faddr,
                                                .saddr = saddr,
@@ -1359,7 +1360,7 @@ void udp_destroy_sock(struct sock *sk)
  *     Socket option code for UDP
  */
 int udp_lib_setsockopt(struct sock *sk, int level, int optname,
-                      char __user *optval, int optlen,
+                      char __user *optval, unsigned int optlen,
                       int (*push_pending_frames)(struct sock *))
 {
        struct udp_sock *up = udp_sk(sk);
@@ -1441,7 +1442,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 EXPORT_SYMBOL(udp_lib_setsockopt);
 
 int udp_setsockopt(struct sock *sk, int level, int optname,
-                  char __user *optval, int optlen)
+                  char __user *optval, unsigned int optlen)
 {
        if (level == SOL_UDP  ||  level == SOL_UDPLITE)
                return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1451,7 +1452,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
 
 #ifdef CONFIG_COMPAT
 int compat_udp_setsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        if (level == SOL_UDP  ||  level == SOL_UDPLITE)
                return udp_lib_setsockopt(sk, level, optname, optval, optlen,
index 9f4a6165f7229ca68deaf98aeadae777a61437a0..aaad650d47d9ca38a703c368734cdf1f93ecf86a 100644 (file)
@@ -11,13 +11,13 @@ extern void         __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
 extern int     udp_v4_get_port(struct sock *sk, unsigned short snum);
 
 extern int     udp_setsockopt(struct sock *sk, int level, int optname,
-                              char __user *optval, int optlen);
+                              char __user *optval, unsigned int optlen);
 extern int     udp_getsockopt(struct sock *sk, int level, int optname,
                               char __user *optval, int __user *optlen);
 
 #ifdef CONFIG_COMPAT
 extern int     compat_udp_setsockopt(struct sock *sk, int level, int optname,
-                                     char __user *optval, int optlen);
+                                     char __user *optval, unsigned int optlen);
 extern int     compat_udp_getsockopt(struct sock *sk, int level, int optname,
                                      char __user *optval, int __user *optlen);
 #endif
index 090675e269ee7b62ffea095dd4c728de61853ab4..716153941fc47ef43fba2acede50b522806f020b 100644 (file)
@@ -1281,7 +1281,7 @@ int ip6mr_sk_done(struct sock *sk)
  *     MOSPF/PIM router set up we can clean this up.
  */
 
-int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
+int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
 {
        int ret;
        struct mif6ctl vif;
index f5e0682b402dd115eb4119c999f4b427b10a7970..14f54eb5a7fc89e1ab9b3d2c7a83e84a54378dbe 100644 (file)
@@ -123,7 +123,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
 }
 
 static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct net *net = sock_net(sk);
@@ -773,7 +773,7 @@ e_inval:
 }
 
 int ipv6_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int optlen)
+                   char __user *optval, unsigned int optlen)
 {
        int err;
 
@@ -801,7 +801,7 @@ EXPORT_SYMBOL(ipv6_setsockopt);
 
 #ifdef CONFIG_COMPAT
 int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
-                          char __user *optval, int optlen)
+                          char __user *optval, unsigned int optlen)
 {
        int err;
 
index 7d675b8d82d36813e2229d6abfe31ffdeec7d4be..4f24570b0869bd5093b18884866d4c67f20dcf41 100644 (file)
@@ -957,7 +957,7 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname,
 
 
 static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
-                           char __user *optval, int optlen)
+                           char __user *optval, unsigned int optlen)
 {
        struct raw6_sock *rp = raw6_sk(sk);
        int val;
@@ -1000,7 +1000,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
 }
 
 static int rawv6_setsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        switch(level) {
                case SOL_RAW:
@@ -1024,7 +1024,7 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
 
 #ifdef CONFIG_COMPAT
 static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
-                                  char __user *optval, int optlen)
+                                  char __user *optval, unsigned int optlen)
 {
        switch (level) {
        case SOL_RAW:
index d65e0c496cc0cd85d93652edd8f2a083029c2f73..dbd19a78ca73ad32b048b8e9c8b89f3600195c90 100644 (file)
@@ -274,7 +274,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
 
        c = 0;
        for (prl = t->prl; prl; prl = prl->next) {
-               if (c > cmax)
+               if (c >= cmax)
                        break;
                if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr)
                        continue;
index b265b7047d3e3b9795c348c92306c3b2b2970255..3a60f12b34ed053da8cf4261952d6d35ff879f28 100644 (file)
@@ -1044,7 +1044,7 @@ void udpv6_destroy_sock(struct sock *sk)
  *     Socket option code for UDP
  */
 int udpv6_setsockopt(struct sock *sk, int level, int optname,
-                    char __user *optval, int optlen)
+                    char __user *optval, unsigned int optlen)
 {
        if (level == SOL_UDP  ||  level == SOL_UDPLITE)
                return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1054,7 +1054,7 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname,
 
 #ifdef CONFIG_COMPAT
 int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
-                           char __user *optval, int optlen)
+                           char __user *optval, unsigned int optlen)
 {
        if (level == SOL_UDP  ||  level == SOL_UDPLITE)
                return udp_lib_setsockopt(sk, level, optname, optval, optlen,
index 6bb303471e204ade2e31d025cb9d3ec1b80fbd60..d7571046bfc440386a52b71bdb2c5295e4360001 100644 (file)
@@ -16,10 +16,10 @@ extern int  udp_v6_get_port(struct sock *sk, unsigned short snum);
 extern int     udpv6_getsockopt(struct sock *sk, int level, int optname,
                                 char __user *optval, int __user *optlen);
 extern int     udpv6_setsockopt(struct sock *sk, int level, int optname,
-                                char __user *optval, int optlen);
+                                char __user *optval, unsigned int optlen);
 #ifdef CONFIG_COMPAT
 extern int     compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
-                                       char __user *optval, int optlen);
+                                       char __user *optval, unsigned int optlen);
 extern int     compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
                                       char __user *optval, int __user *optlen);
 #endif
index f1118d92a191dc07acd9bfda34ce81c7df8613f0..66c7a20011f36b3147bb66c5169f5c292236f597 100644 (file)
@@ -1292,7 +1292,7 @@ const char *ipx_device_name(struct ipx_interface *intrfc)
  * socket object. */
 
 static int ipx_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int opt;
index 50b43c57d5d8e01c94796b988fa6e98a7f4aee2b..dd35641835f408d161a7d1c70550a15f1a0309ac 100644 (file)
@@ -1826,7 +1826,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
  *
  */
 static int irda_setsockopt(struct socket *sock, int level, int optname,
-                          char __user *optval, int optlen)
+                          char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
index d985d163dcfc12590948cefcb5af50af3d08754e..bada1b9c670bd555fa10833165326492762b3d97 100644 (file)
@@ -1387,7 +1387,7 @@ static int iucv_sock_release(struct socket *sock)
 
 /* getsockopt and setsockopt */
 static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct iucv_sock *iucv = iucv_sk(sk);
index c45eee1c0e8d46719df66883caa4d874f806ec5f..7aa4fd170104452be2d9daa1194bc313dfd759eb 100644 (file)
@@ -973,7 +973,7 @@ static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
  *     Set various connection specific parameters.
  */
 static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
-                            char __user *optval, int optlen)
+                            char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct llc_sock *llc = llc_sk(sk);
index 5143d203256b06a9c6e418f3d7611d4b89352d49..fd40282966132d9c76719bda986732ce4d511bc5 100644 (file)
@@ -367,7 +367,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
        u32 staflags;
 
-       if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)))
+       if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)
+                       || ieee80211_is_auth(hdr->frame_control)
+                       || ieee80211_is_assoc_resp(hdr->frame_control)
+                       || ieee80211_is_reassoc_resp(hdr->frame_control)))
                return TX_CONTINUE;
 
        staflags = get_sta_flags(sta);
index 8ab829f865741c4a9f782f7dc793642528f13d95..f042ae521557b340be5252aa41ccdc67f5202a29 100644 (file)
@@ -113,7 +113,7 @@ static int nf_sockopt(struct sock *sk, u_int8_t pf, int val,
 }
 
 int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
-                 int len)
+                 unsigned int len)
 {
        return nf_sockopt(sk, pf, val, opt, &len, 0);
 }
@@ -154,7 +154,7 @@ static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
 }
 
 int compat_nf_setsockopt(struct sock *sk, u_int8_t pf,
-               int val, char __user *opt, int len)
+               int val, char __user *opt, unsigned int len)
 {
        return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
 }
index dd85320907cb6f765346f12bd34335825287a743..19e98007691cce17b68e3fc29896b7dc3626a526 100644 (file)
@@ -1150,7 +1150,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk,
 }
 
 static int netlink_setsockopt(struct socket *sock, int level, int optname,
-                             char __user *optval, int optlen)
+                             char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
index ce1a34b99c2328f16648d5cf96cb8ff5edc25ed6..7a834952f67fe75f72558b7e3c8477bc8ac259a6 100644 (file)
@@ -301,7 +301,7 @@ void nr_destroy_socket(struct sock *sk)
  */
 
 static int nr_setsockopt(struct socket *sock, int level, int optname,
-       char __user *optval, int optlen)
+       char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct nr_sock *nr = nr_sk(sk);
index 103d5611b8181dba6f3cb523dae9af20b17257e6..d7ecca0a0c0787d674cc3e28bfab7ed4cc4534a4 100644 (file)
@@ -1701,7 +1701,7 @@ static void packet_flush_mclist(struct sock *sk)
 }
 
 static int
-packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct packet_sock *po = pkt_sk(sk);
index b8252d289cd70475d16ce661d4c120b722ff3cc6..5f32d217535b4695667dc3e75ea3e0bcaab9a15e 100644 (file)
@@ -742,7 +742,7 @@ static int pep_init(struct sock *sk)
 }
 
 static int pep_setsockopt(struct sock *sk, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        struct pep_sock *pn = pep_sk(sk);
        int val = 0, err = 0;
index 07aa9f08d5fbdd0a66eb4713103b2f687089a8ea..aa5b5a972bff7a3e40700b8969e3b145bca428eb 100644 (file)
@@ -407,7 +407,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
        return -EADDRINUSE;
 
 found:
-       mutex_unlock(&port_mutex);
        pn->sobject = pn_object(pn_addr(pn->sobject), sport);
        return 0;
 }
index 6b58aeff4c7ab72b4072799b63e2f0dd8d466a5c..98e05382fd3cf19e01fe2315674e0e84ff8da145 100644 (file)
@@ -248,7 +248,7 @@ static int rds_cong_monitor(struct rds_sock *rs, char __user *optval,
 }
 
 static int rds_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        struct rds_sock *rs = rds_sk_to_rs(sock->sk);
        int ret;
index dbeaf2983822e99a36377017b16e33e1fae32a03..ba2efb960c6007ecbd9b5b0a49372d21d32ed68a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/rfkill.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/miscdevice.h>
 #include <linux/wait.h>
index 1e166c9685aac9c479eb7720a28f7dff4ecaa6f2..502cce76621d07abdd624798c5c76e3802db63aa 100644 (file)
@@ -370,7 +370,7 @@ void rose_destroy_socket(struct sock *sk)
  */
 
 static int rose_setsockopt(struct socket *sock, int level, int optname,
-       char __user *optval, int optlen)
+       char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct rose_sock *rose = rose_sk(sk);
index bfe493ebf27c36a7a82974af5a596ee8f75528c9..a86afceaa94fadd8a1137c7688a03cb5714cf18e 100644 (file)
@@ -507,7 +507,7 @@ out:
  * set RxRPC socket options
  */
 static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
-                           char __user *optval, int optlen)
+                           char __user *optval, unsigned int optlen)
 {
        struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
        unsigned min_sec_level;
index 89af37a6c87168a4b68f60e5211b57882fb9c25c..c8d05758661d96cf09c41f3babb983c4f2194ce9 100644 (file)
@@ -2027,7 +2027,8 @@ out:
  * instead a error will be indicated to the user.
  */
 static int sctp_setsockopt_disable_fragments(struct sock *sk,
-                                           char __user *optval, int optlen)
+                                            char __user *optval,
+                                            unsigned int optlen)
 {
        int val;
 
@@ -2043,7 +2044,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk,
 }
 
 static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
-                                       int optlen)
+                                 unsigned int optlen)
 {
        if (optlen > sizeof(struct sctp_event_subscribe))
                return -EINVAL;
@@ -2064,7 +2065,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
  * association is closed.
  */
 static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
-                                           int optlen)
+                                    unsigned int optlen)
 {
        struct sctp_sock *sp = sctp_sk(sk);
 
@@ -2318,7 +2319,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
 }
 
 static int sctp_setsockopt_peer_addr_params(struct sock *sk,
-                                           char __user *optval, int optlen)
+                                           char __user *optval,
+                                           unsigned int optlen)
 {
        struct sctp_paddrparams  params;
        struct sctp_transport   *trans = NULL;
@@ -2430,7 +2432,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
  */
 
 static int sctp_setsockopt_delayed_ack(struct sock *sk,
-                                           char __user *optval, int optlen)
+                                      char __user *optval, unsigned int optlen)
 {
        struct sctp_sack_info    params;
        struct sctp_transport   *trans = NULL;
@@ -2546,7 +2548,7 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
  * by the change).  With TCP-style sockets, this option is inherited by
  * sockets derived from a listener socket.
  */
-static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen)
 {
        struct sctp_initmsg sinit;
        struct sctp_sock *sp = sctp_sk(sk);
@@ -2583,7 +2585,8 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int opt
  *   to this call if the caller is using the UDP model.
  */
 static int sctp_setsockopt_default_send_param(struct sock *sk,
-                                               char __user *optval, int optlen)
+                                             char __user *optval,
+                                             unsigned int optlen)
 {
        struct sctp_sndrcvinfo info;
        struct sctp_association *asoc;
@@ -2622,7 +2625,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
  * association peer's addresses.
  */
 static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
-                                       int optlen)
+                                       unsigned int optlen)
 {
        struct sctp_prim prim;
        struct sctp_transport *trans;
@@ -2651,7 +2654,7 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
  *  integer boolean flag.
  */
 static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
-                                       int optlen)
+                                  unsigned int optlen)
 {
        int val;
 
@@ -2676,7 +2679,8 @@ static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
  * be changed.
  *
  */
-static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int optlen) {
+static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen)
+{
        struct sctp_rtoinfo rtoinfo;
        struct sctp_association *asoc;
 
@@ -2728,7 +2732,7 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int opt
  * See [SCTP] for more information.
  *
  */
-static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen)
 {
 
        struct sctp_assocparams assocparams;
@@ -2800,7 +2804,7 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o
  * addresses and a user will receive both PF_INET6 and PF_INET type
  * addresses on the socket.
  */
-static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen)
 {
        int val;
        struct sctp_sock *sp = sctp_sk(sk);
@@ -2844,7 +2848,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op
  *    changed (effecting future associations only).
  * assoc_value:  This parameter specifies the maximum size in bytes.
  */
-static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
 {
        struct sctp_assoc_value params;
        struct sctp_association *asoc;
@@ -2899,7 +2903,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl
  *   set primary request:
  */
 static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval,
-                                            int optlen)
+                                            unsigned int optlen)
 {
        struct sctp_sock        *sp;
        struct sctp_endpoint    *ep;
@@ -2950,7 +2954,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
 }
 
 static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
-                                         int optlen)
+                                           unsigned int optlen)
 {
        struct sctp_setadaptation adaptation;
 
@@ -2979,7 +2983,7 @@ static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval
  * saved with outbound messages.
  */
 static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
-                                  int optlen)
+                                  unsigned int optlen)
 {
        struct sctp_assoc_value params;
        struct sctp_sock *sp;
@@ -3030,7 +3034,7 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
  */
 static int sctp_setsockopt_fragment_interleave(struct sock *sk,
                                               char __user *optval,
-                                              int optlen)
+                                              unsigned int optlen)
 {
        int val;
 
@@ -3063,7 +3067,7 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk,
  */
 static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
                                                  char __user *optval,
-                                                 int optlen)
+                                                 unsigned int optlen)
 {
        u32 val;
 
@@ -3096,7 +3100,7 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
  */
 static int sctp_setsockopt_maxburst(struct sock *sk,
                                    char __user *optval,
-                                   int optlen)
+                                   unsigned int optlen)
 {
        struct sctp_assoc_value params;
        struct sctp_sock *sp;
@@ -3140,8 +3144,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
  * will only effect future associations on the socket.
  */
 static int sctp_setsockopt_auth_chunk(struct sock *sk,
-                                   char __user *optval,
-                                   int optlen)
+                                     char __user *optval,
+                                     unsigned int optlen)
 {
        struct sctp_authchunk val;
 
@@ -3172,8 +3176,8 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
  * endpoint requires the peer to use.
  */
 static int sctp_setsockopt_hmac_ident(struct sock *sk,
-                                   char __user *optval,
-                                   int optlen)
+                                     char __user *optval,
+                                     unsigned int optlen)
 {
        struct sctp_hmacalgo *hmacs;
        u32 idents;
@@ -3215,7 +3219,7 @@ out:
  */
 static int sctp_setsockopt_auth_key(struct sock *sk,
                                    char __user *optval,
-                                   int optlen)
+                                   unsigned int optlen)
 {
        struct sctp_authkey *authkey;
        struct sctp_association *asoc;
@@ -3260,8 +3264,8 @@ out:
  * the association shared key.
  */
 static int sctp_setsockopt_active_key(struct sock *sk,
-                                       char __user *optval,
-                                       int optlen)
+                                     char __user *optval,
+                                     unsigned int optlen)
 {
        struct sctp_authkeyid val;
        struct sctp_association *asoc;
@@ -3288,8 +3292,8 @@ static int sctp_setsockopt_active_key(struct sock *sk,
  * This set option will delete a shared secret key from use.
  */
 static int sctp_setsockopt_del_key(struct sock *sk,
-                                       char __user *optval,
-                                       int optlen)
+                                  char __user *optval,
+                                  unsigned int optlen)
 {
        struct sctp_authkeyid val;
        struct sctp_association *asoc;
@@ -3332,7 +3336,7 @@ static int sctp_setsockopt_del_key(struct sock *sk,
  *   optlen  - the size of the buffer.
  */
 SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        int retval = 0;
 
index 41e8847508aad85a22f1ba61e4999daa5ca46342..75655365b5fd2041d9bdf97d936275b1f74b217e 100644 (file)
@@ -2391,7 +2391,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
 }
 
 int kernel_setsockopt(struct socket *sock, int level, int optname,
-                       char *optval, int optlen)
+                       char *optval, unsigned int optlen)
 {
        mm_segment_t oldfs = get_fs();
        int err;
index e8254e809b790a76267fddeabd36995daeb80412..e6d9abf7440e09dac80152770f6a22b83a1c8201 100644 (file)
@@ -1658,7 +1658,7 @@ restart:
  */
 
 static int setsockopt(struct socket *sock,
-                     int lvl, int opt, char __user *ov, int ol)
+                     int lvl, int opt, char __user *ov, unsigned int ol)
 {
        struct sock *sk = sock->sk;
        struct tipc_port *tport = tipc_sk_port(sk);
index 5e6c072c64d3d8b3380cc68247565fa291237952..7fa9c7ad3d3b5b7efbe4c612511425628900a138 100644 (file)
@@ -409,7 +409,7 @@ static void x25_destroy_socket(struct sock *sk)
  */
 
 static int x25_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        int opt;
        struct sock *sk = sock->sk;
index 9cf80a11e8b68aa23d6b744e3cdb0da81e438981..26fab33ffa8cccc13a02e9d3b4573c974f71e86e 100644 (file)
@@ -28,7 +28,7 @@ static int my_open(struct inode *inode, struct file *file)
        return -EPERM;
 }
 
-static struct file_operations mark_ops = {
+static const struct file_operations mark_ops = {
        .open = my_open,
 };
 
index 8e9777b764052a1088d38fc3385c4dd1dfb25107..0c72c9c38956f1ac949f049db87fc17a3d8eed39 100644 (file)
@@ -43,7 +43,7 @@ static ssize_t ima_show_htable_violations(struct file *filp,
        return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
 }
 
-static struct file_operations ima_htable_violations_ops = {
+static const struct file_operations ima_htable_violations_ops = {
        .read = ima_show_htable_violations
 };
 
@@ -55,7 +55,7 @@ static ssize_t ima_show_measurements_count(struct file *filp,
 
 }
 
-static struct file_operations ima_measurements_count_ops = {
+static const struct file_operations ima_measurements_count_ops = {
        .read = ima_show_measurements_count
 };
 
@@ -158,7 +158,7 @@ static int ima_measurements_open(struct inode *inode, struct file *file)
        return seq_open(file, &ima_measurments_seqops);
 }
 
-static struct file_operations ima_measurements_ops = {
+static const struct file_operations ima_measurements_ops = {
        .open = ima_measurements_open,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -233,7 +233,7 @@ static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
        return seq_open(file, &ima_ascii_measurements_seqops);
 }
 
-static struct file_operations ima_ascii_measurements_ops = {
+static const struct file_operations ima_ascii_measurements_ops = {
        .open = ima_ascii_measurements_open,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -313,7 +313,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations ima_measure_policy_ops = {
+static const struct file_operations ima_measure_policy_ops = {
        .open = ima_open_policy,
        .write = ima_write_policy,
        .release = ima_release_policy
index f0ebc971c6865041855e27b9b3cc3423e20c1cfa..1dd66ddffcaf6b97cf46ef2fe2f055a7ca317d37 100644 (file)
@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter,
        client = i2c_new_device(adapter, &info);
        if (!client)
                return -ENODEV;
+       /*
+        * We know the driver is already loaded, so the device should be
+        * already bound. If not it means binding failed, and then there
+        * is no point in keeping the device instantiated.
+        */
+       if (!client->driver) {
+               i2c_unregister_device(client);
+               return -ENODEV;
+       }
 
        /*
         * Let i2c-core delete that device on driver removal.
index c52691c2fc46df746aee9136545f1c4ed6aa1447..9a88cdfd952a0c609847442b24da8746d8aee51e 100644 (file)
@@ -915,7 +915,7 @@ static int __devinit hal2_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __exit hal2_remove(struct platform_device *pdev)
+static int __devexit hal2_remove(struct platform_device *pdev)
 {
        struct snd_card *card = platform_get_drvdata(pdev);
 
index e497525bc11bcf50612c071bdfc3c5ba186bacf1..8691f4cf6191fc8500d4995c42e227bd8680a6c6 100644 (file)
@@ -973,7 +973,7 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __exit snd_sgio2audio_remove(struct platform_device *pdev)
+static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
 {
        struct snd_card *card = platform_get_drvdata(pdev);
 
index b1b3a644f73804a186263df3241f5c49650c5f48..75454648d50c6efb10d79357804c322c6f7aa80e 100644 (file)
@@ -1037,7 +1037,7 @@ static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
 
 static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
 {
-       return atc_daio_unmute(atc, state, LINEO4);
+       return atc_daio_unmute(atc, state, LINEO2);
 }
 
 static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
@@ -1047,7 +1047,7 @@ static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
 
 static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
 {
-       return atc_daio_unmute(atc, state, LINEO2);
+       return atc_daio_unmute(atc, state, LINEO4);
 }
 
 static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
index da2065cd2c0d5c3ffd5783b98c90ebfbc4ee244c..1305f7ca02c3c2726049dc448dec6b7fa36a63cd 100644 (file)
@@ -950,7 +950,7 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
        Control interface
 ******************************************************************************/
 
-#ifndef ECHOCARD_HAS_VMIXER
+#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
 
 /******************* PCM output volume *******************/
 static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
@@ -1003,6 +1003,19 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
        return changed;
 }
 
+#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
+/* On the Mia this one controls the line-out volume */
+static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
+       .name = "Line Playback Volume",
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+       .info = snd_echo_output_gain_info,
+       .get = snd_echo_output_gain_get,
+       .put = snd_echo_output_gain_put,
+       .tlv = {.p = db_scale_output_gain},
+};
+#else
 static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
        .name = "PCM Playback Volume",
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1012,9 +1025,10 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
        .put = snd_echo_output_gain_put,
        .tlv = {.p = db_scale_output_gain},
 };
-
 #endif
 
+#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
+
 
 
 #ifdef ECHOCARD_HAS_INPUT_GAIN
@@ -2030,10 +2044,18 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
        snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
        if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
                goto ctl_error;
-#else
-       if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0)
+#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
+       err = snd_ctl_add(chip->card,
+                         snd_ctl_new1(&snd_echo_line_output_gain, chip));
+       if (err < 0)
                goto ctl_error;
 #endif
+#else /* ECHOCARD_HAS_VMIXER */
+       err = snd_ctl_add(chip->card,
+                         snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
+       if (err < 0)
+               goto ctl_error;
+#endif /* ECHOCARD_HAS_VMIXER */
 
 #ifdef ECHOCARD_HAS_INPUT_GAIN
        if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
index f3b9b45c9c1be7ad82b3c9249e66dfe84ef15833..f05c8c097aa8196de2f9fe0a62e6e45e2efbd66c 100644 (file)
@@ -29,6 +29,7 @@
 #define ECHOCARD_HAS_ADAT      FALSE
 #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
 #define ECHOCARD_HAS_MIDI
+#define ECHOCARD_HAS_LINE_OUT_GAIN
 
 /* Pipe indexes */
 #define PX_ANALOG_OUT  0       /* 8 */
index 20a66f85f0a4247b317d8bbd9e68dafe107e892e..c9ad182e1b4b6a3ddd23b422f2e4f821bde90604 100644 (file)
@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
  * white-list for enable_msi
  */
 static struct snd_pci_quirk msi_white_list[] __devinitdata = {
+       SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1),
        SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
        {}
 };
index 215e72a8711306567bf3c898b5ef02caeb5ef5a4..2d603f6aba6319bbf149a8dc5b966aec328aba8e 100644 (file)
@@ -4031,6 +4031,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
        return 0;
 }
 
+/*
+ * HP Touchsmart
+ * port-A (0x11)      - front hp-out
+ * port-B (0x14)      - unused
+ * port-C (0x15)      - unused
+ * port-D (0x12)      - rear line out
+ * port-E (0x1c)      - front mic-in
+ * port-F (0x16)      - Internal speakers
+ * digital-mic (0x17) - Internal mic
+ */
+
+static struct hda_verb ad1984a_touchsmart_verbs[] = {
+       /* DACs; unmute as default */
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+       /* Port-A (HP) mixer - route only from analog mixer */
+       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       /* Port-A pin */
+       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       /* Port-A (HP) pin - always unmuted */
+       {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       /* Port-E (int speaker) mixer - route only from analog mixer */
+       {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
+       /* Port-E pin */
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+       /* Port-F (int speaker) mixer - route only from analog mixer */
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       /* Port-F pin */
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* Analog mixer; mute as default */
+       {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+       {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+       {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+       {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+       /* Analog Mix output amp */
+       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* capture sources */
+       /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
+       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* unsolicited event for pin-sense */
+       {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
+       {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
+       /* allow to touch GPIO1 (for mute control) */
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
+       /* internal mic - dmic */
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       /* set magic COEFs for dmic */
+       {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
+       {0x01, AC_VERB_SET_PROC_COEF, 0x08},
+       { } /* end */
+};
+
+static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
+       HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
+/*     HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Master Playback Switch",
+               .info = snd_hda_mixer_amp_switch_info,
+               .get = snd_hda_mixer_amp_switch_get,
+               .put = ad1884a_mobile_master_sw_put,
+               .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
+       },
+       HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
+       HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+/* switch to external mic if plugged */
+static void ad1984a_touchsmart_automic(struct hda_codec *codec)
+{
+       if (snd_hda_codec_read(codec, 0x1c, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
+               snd_hda_codec_write(codec, 0x0c, 0,
+                                    AC_VERB_SET_CONNECT_SEL, 0x4);
+       } else {
+               snd_hda_codec_write(codec, 0x0c, 0,
+                                    AC_VERB_SET_CONNECT_SEL, 0x5);
+       }
+}
+
+
+/* unsolicited event for HP jack sensing */
+static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
+       unsigned int res)
+{
+       switch (res >> 26) {
+       case AD1884A_HP_EVENT:
+               ad1884a_hp_automute(codec);
+               break;
+       case AD1884A_MIC_EVENT:
+               ad1984a_touchsmart_automic(codec);
+               break;
+       }
+}
+
+/* initialize jack-sensing, too */
+static int ad1984a_touchsmart_init(struct hda_codec *codec)
+{
+       ad198x_init(codec);
+       ad1884a_hp_automute(codec);
+       ad1984a_touchsmart_automic(codec);
+       return 0;
+}
+
+
 /*
  */
 
@@ -4039,6 +4160,7 @@ enum {
        AD1884A_LAPTOP,
        AD1884A_MOBILE,
        AD1884A_THINKPAD,
+       AD1984A_TOUCHSMART,
        AD1884A_MODELS
 };
 
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
        [AD1884A_LAPTOP]        = "laptop",
        [AD1884A_MOBILE]        = "mobile",
        [AD1884A_THINKPAD]      = "thinkpad",
+       [AD1984A_TOUCHSMART]    = "touchsmart",
 };
 
 static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
        SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
        SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
+       SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
        {}
 };
 
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
                codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
                codec->patch_ops.init = ad1984a_thinkpad_init;
                break;
+       case AD1984A_TOUCHSMART:
+               spec->mixers[0] = ad1984a_touchsmart_mixers;
+               spec->init_verbs[0] = ad1984a_touchsmart_verbs;
+               spec->multiout.dig_out_nid = 0;
+               codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
+               codec->patch_ops.init = ad1984a_touchsmart_init;
+               /* set the upper-limit for mixer amp to 0dB for avoiding the
+                * possible damage by overloading
+                */
+               snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
+                                         (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+                                         (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+                                         (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+                                         (1 << AC_AMPCAP_MUTE_SHIFT));
+               break;
        }
 
        return 0;
index 9d899eda44d779695a1506598f8d5662d8a4a0f1..3fbbc8c01e703845e590345ca0f564cd02499d12 100644 (file)
@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = {
 };
 
 static struct hda_input_mux cxt5045_capture_source_benq = {
-       .num_items = 3,
+       .num_items = 5,
        .items = {
                { "IntMic", 0x1 },
                { "ExtMic", 0x2 },
                { "LineIn", 0x3 },
+               { "CD",     0x4 },
+               { "Mixer",  0x0 },
        }
 };
 
@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
 };
 
 static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
+       HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
+
        HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
        HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
        HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
 
+       HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
+
        {}
 };
 
index 129605819560073d542de35b1b265d4cd0696ae0..7810d3dcad833011a1676399be7d07daf998a21e 100644 (file)
@@ -12660,7 +12660,7 @@ static struct alc_config_preset alc268_presets[] = {
                .init_hook = alc268_toshiba_automute,
        },
        [ALC268_ACER] = {
-               .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer,
+               .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
                            alc268_beep_mixer },
                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
                                alc268_acer_verbs },
@@ -16852,6 +16852,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
        SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
                      ALC662_3ST_6ch_DIG),
+       SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
        SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
                      ALC662_3ST_6ch_DIG),
@@ -17145,70 +17146,145 @@ static struct alc_config_preset alc662_presets[] = {
  * BIOS auto configuration
  */
 
+/* convert from MIX nid to DAC */
+static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
+{
+       if (nid == 0x0f)
+               return 0x02;
+       else if (nid >= 0x0c && nid <= 0x0e)
+               return nid - 0x0c + 0x02;
+       else
+               return 0;
+}
+
+/* get MIX nid connected to the given pin targeted to DAC */
+static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
+                                  hda_nid_t dac)
+{
+       hda_nid_t mix[4];
+       int i, num;
+
+       num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
+       for (i = 0; i < num; i++) {
+               if (alc662_mix_to_dac(mix[i]) == dac)
+                       return mix[i];
+       }
+       return 0;
+}
+
+/* look for an empty DAC slot */
+static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
+{
+       struct alc_spec *spec = codec->spec;
+       hda_nid_t srcs[5];
+       int i, j, num;
+
+       num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
+       if (num < 0)
+               return 0;
+       for (i = 0; i < num; i++) {
+               hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
+               if (!nid)
+                       continue;
+               for (j = 0; j < spec->multiout.num_dacs; j++)
+                       if (spec->multiout.dac_nids[j] == nid)
+                               break;
+               if (j >= spec->multiout.num_dacs)
+                       return nid;
+       }
+       return 0;
+}
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
+                                    const struct auto_pin_cfg *cfg)
+{
+       struct alc_spec *spec = codec->spec;
+       int i;
+       hda_nid_t dac;
+
+       spec->multiout.dac_nids = spec->private_dac_nids;
+       for (i = 0; i < cfg->line_outs; i++) {
+               dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
+               if (!dac)
+                       continue;
+               spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
+       }
+       return 0;
+}
+
+static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
+                             hda_nid_t nid, unsigned int chs)
+{
+       char name[32];
+       sprintf(name, "%s Playback Volume", pfx);
+       return add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                          HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
+}
+
+static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
+                            hda_nid_t nid, unsigned int chs)
+{
+       char name[32];
+       sprintf(name, "%s Playback Switch", pfx);
+       return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                          HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
+}
+
+#define alc662_add_stereo_vol(spec, pfx, nid) \
+       alc662_add_vol_ctl(spec, pfx, nid, 3)
+#define alc662_add_stereo_sw(spec, pfx, nid) \
+       alc662_add_sw_ctl(spec, pfx, nid, 3)
+
 /* add playback controls from the parsed DAC table */
-static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
+static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
                                             const struct auto_pin_cfg *cfg)
 {
-       char name[32];
+       struct alc_spec *spec = codec->spec;
        static const char *chname[4] = {
                "Front", "Surround", NULL /*CLFE*/, "Side"
        };
-       hda_nid_t nid;
+       hda_nid_t nid, mix;
        int i, err;
 
        for (i = 0; i < cfg->line_outs; i++) {
-               if (!spec->multiout.dac_nids[i])
+               nid = spec->multiout.dac_nids[i];
+               if (!nid)
+                       continue;
+               mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
+               if (!mix)
                        continue;
-               nid = alc880_idx_to_dac(i);
                if (i == 2) {
                        /* Center/LFE */
-                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
-                                         "Center Playback Volume",
-                                         HDA_COMPOSE_AMP_VAL(nid, 1, 0,
-                                                             HDA_OUTPUT));
+                       err = alc662_add_vol_ctl(spec, "Center", nid, 1);
                        if (err < 0)
                                return err;
-                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
-                                         "LFE Playback Volume",
-                                         HDA_COMPOSE_AMP_VAL(nid, 2, 0,
-                                                             HDA_OUTPUT));
+                       err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
                        if (err < 0)
                                return err;
-                       err = add_control(spec, ALC_CTL_WIDGET_MUTE,
-                                         "Center Playback Switch",
-                                         HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
-                                                             HDA_INPUT));
+                       err = alc662_add_sw_ctl(spec, "Center", mix, 1);
                        if (err < 0)
                                return err;
-                       err = add_control(spec, ALC_CTL_WIDGET_MUTE,
-                                         "LFE Playback Switch",
-                                         HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
-                                                             HDA_INPUT));
+                       err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
                        if (err < 0)
                                return err;
                } else {
                        const char *pfx;
                        if (cfg->line_outs == 1 &&
                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
-                               if (!cfg->hp_pins)
+                               if (cfg->hp_outs)
                                        pfx = "Speaker";
                                else
                                        pfx = "PCM";
                        } else
                                pfx = chname[i];
-                       sprintf(name, "%s Playback Volume", pfx);
-                       err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                                         HDA_COMPOSE_AMP_VAL(nid, 3, 0,
-                                                             HDA_OUTPUT));
+                       err = alc662_add_vol_ctl(spec, pfx, nid, 3);
                        if (err < 0)
                                return err;
                        if (cfg->line_outs == 1 &&
                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
                                pfx = "Speaker";
-                       sprintf(name, "%s Playback Switch", pfx);
-                       err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-                               HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
-                                                   3, 0, HDA_INPUT));
+                       err = alc662_add_sw_ctl(spec, pfx, mix, 3);
                        if (err < 0)
                                return err;
                }
@@ -17217,54 +17293,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
 }
 
 /* add playback controls for speaker and HP outputs */
-static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+/* return DAC nid if any new DAC is assigned */
+static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
                                        const char *pfx)
 {
-       hda_nid_t nid;
+       struct alc_spec *spec = codec->spec;
+       hda_nid_t nid, mix;
        int err;
-       char name[32];
 
        if (!pin)
                return 0;
-
-       if (pin == 0x17) {
-               /* ALC663 has a mono output pin on 0x17 */
+       nid = alc662_look_for_dac(codec, pin);
+       if (!nid) {
+               char name[32];
+               /* the corresponding DAC is already occupied */
+               if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
+                       return 0; /* no way */
+               /* create a switch only */
                sprintf(name, "%s Playback Switch", pfx);
-               err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-                                 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
-               return err;
+               return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
        }
 
-       if (alc880_is_fixed_pin(pin)) {
-               nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
-               /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
-               /* specify the DAC as the extra output */
-               if (!spec->multiout.hp_nid)
-                       spec->multiout.hp_nid = nid;
-               else
-                       spec->multiout.extra_out_nid[0] = nid;
-               /* control HP volume/switch on the output mixer amp */
-               nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
-               sprintf(name, "%s Playback Volume", pfx);
-               err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                                 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
-               if (err < 0)
-                       return err;
-               sprintf(name, "%s Playback Switch", pfx);
-               err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                                 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
-               if (err < 0)
-                       return err;
-       } else if (alc880_is_multi_pin(pin)) {
-               /* set manual connection */
-               /* we have only a switch on HP-out PIN */
-               sprintf(name, "%s Playback Switch", pfx);
-               err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-                                 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
-               if (err < 0)
-                       return err;
-       }
-       return 0;
+       mix = alc662_dac_to_mix(codec, pin, nid);
+       if (!mix)
+               return 0;
+       err = alc662_add_vol_ctl(spec, pfx, nid, 3);
+       if (err < 0)
+               return err;
+       err = alc662_add_sw_ctl(spec, pfx, mix, 3);
+       if (err < 0)
+               return err;
+       return nid;
 }
 
 /* create playback/capture controls for input pins */
@@ -17273,30 +17333,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
 
 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
                                              hda_nid_t nid, int pin_type,
-                                             int dac_idx)
+                                             hda_nid_t dac)
 {
+       int i, num;
+       hda_nid_t srcs[4];
+
        alc_set_pin_output(codec, nid, pin_type);
        /* need the manual connection? */
-       if (alc880_is_multi_pin(nid)) {
-               struct alc_spec *spec = codec->spec;
-               int idx = alc880_multi_pin_idx(nid);
-               snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
-                                   AC_VERB_SET_CONNECT_SEL,
-                                   alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+       num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
+       if (num <= 1)
+               return;
+       for (i = 0; i < num; i++) {
+               if (alc662_mix_to_dac(srcs[i]) != dac)
+                       continue;
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
+               return;
        }
 }
 
 static void alc662_auto_init_multi_out(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
+       int pin_type = get_pin_type(spec->autocfg.line_out_type);
        int i;
 
        for (i = 0; i <= HDA_SIDE; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
-               int pin_type = get_pin_type(spec->autocfg.line_out_type);
                if (nid)
                        alc662_auto_set_output_and_unmute(codec, nid, pin_type,
-                                                         i);
+                                       spec->multiout.dac_nids[i]);
        }
 }
 
@@ -17306,12 +17371,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
        hda_nid_t pin;
 
        pin = spec->autocfg.hp_pins[0];
-       if (pin) /* connect to front */
-               /* use dac 0 */
-               alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+       if (pin)
+               alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
+                                                 spec->multiout.hp_nid);
        pin = spec->autocfg.speaker_pins[0];
        if (pin)
-               alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
+               alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
+                                       spec->multiout.extra_out_nid[0]);
 }
 
 #define ALC662_PIN_CD_NID              ALC880_PIN_CD_NID
@@ -17349,21 +17415,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
        if (!spec->autocfg.line_outs)
                return 0; /* can't find valid BIOS pin config */
 
-       err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+       err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
        if (err < 0)
                return err;
-       err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
        if (err < 0)
                return err;
-       err = alc662_auto_create_extra_out(spec,
+       err = alc662_auto_create_extra_out(codec,
                                           spec->autocfg.speaker_pins[0],
                                           "Speaker");
        if (err < 0)
                return err;
-       err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+       if (err)
+               spec->multiout.extra_out_nid[0] = err;
+       err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
                                           "Headphone");
        if (err < 0)
                return err;
+       if (err)
+               spec->multiout.hp_nid = err;
        err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
        if (err < 0)
                return err;
index 826137ec3002021dba56de29169f01740b3008e1..a9b26828a65168fdd9fee7aed1c6e4ae0033fc55 100644 (file)
@@ -182,8 +182,8 @@ struct sigmatel_jack {
 
 struct sigmatel_mic_route {
        hda_nid_t pin;
-       unsigned char mux_idx;
-       unsigned char dmux_idx;
+       signed char mux_idx;
+       signed char dmux_idx;
 };
 
 struct sigmatel_spec {
@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec,
                        break;
        if (i <= AUTO_PIN_FRONT_MIC) {
                /* analog pin */
-               mic->dmux_idx = 0;
                i = get_connection_index(codec, spec->mux_nids[0], pin);
                if (i < 0)
                        return -1;
                mic->mux_idx = i;
+               mic->dmux_idx = -1;
+               if (spec->dmux_nids)
+                       mic->dmux_idx = get_connection_index(codec,
+                                                            spec->dmux_nids[0],
+                                                            spec->mux_nids[0]);
        }  else if (spec->dmux_nids) {
                /* digital pin */
-               mic->mux_idx = 0;
                i = get_connection_index(codec, spec->dmux_nids[0], pin);
                if (i < 0)
                        return -1;
                mic->dmux_idx = i;
+               mic->mux_idx = -1;
+               if (spec->mux_nids)
+                       mic->mux_idx = get_connection_index(codec,
+                                                           spec->mux_nids[0],
+                                                           spec->dmux_nids[0]);
        }
        return 0;
 }
@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
                mic = &spec->ext_mic;
        else
                mic = &spec->int_mic;
-       if (mic->dmux_idx)
+       if (mic->dmux_idx >= 0)
                snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
                                          AC_VERB_SET_CONNECT_SEL,
                                          mic->dmux_idx);
-       else
+       if (mic->mux_idx >= 0)
                snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
                                          AC_VERB_SET_CONNECT_SEL,
                                          mic->mux_idx);
index 171ada535209a2974c8151597b0e1ceb4489736c..754867ed4785f248dc15f9d2680ba4e607932776 100644 (file)
@@ -1954,6 +1954,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .name = "Sony S1XP",
                .type = AC97_TUNE_INV_EAPD
        },
+       {
+               .subvendor = 0x104d,
+               .subdevice = 0x81c0,
+               .name = "Sony VAIO VGN-T350P", /*AD1981B*/
+               .type = AC97_TUNE_INV_EAPD
+       },
+       {
+               .subvendor = 0x104d,
+               .subdevice = 0x81c5,
+               .name = "Sony VAIO VGN-B1VP", /*AD1981B*/
+               .type = AC97_TUNE_INV_EAPD
+       },
        {
                .subvendor = 0x1043,
                .subdevice = 0x80f3,
index 835fa19ed461864018fb152aa3c41eb57261cb4b..d06f780bd7e84ad088163eb52e134c8c57188956 100644 (file)
@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
        strlcpy(info.type, "keywest", I2C_NAME_SIZE);
        info.addr = keywest_ctx->addr;
        keywest_ctx->client = i2c_new_device(adapter, &info);
+       if (!keywest_ctx->client)
+               return -ENODEV;
+       /*
+        * We know the driver is already loaded, so the device should be
+        * already bound. If not it means binding failed, and then there
+        * is no point in keeping the device instantiated.
+        */
+       if (!keywest_ctx->client->driver) {
+               i2c_unregister_device(keywest_ctx->client);
+               keywest_ctx->client = NULL;
+               return -ENODEV;
+       }
        
        /*
         * Let i2c-core delete that device on driver removal.
@@ -86,7 +98,7 @@ static const struct i2c_device_id keywest_i2c_id[] = {
        { }
 };
 
-struct i2c_driver keywest_driver = {
+static struct i2c_driver keywest_driver = {
        .driver = {
                .name = "PMac Keywest Audio",
        },
index ac927ffdc9614d59808f8aabcb22b17dcab9ceed..97f1a251e446e5329c31c7f155d0c76ad29436ba 100644 (file)
@@ -7,15 +7,6 @@ config SND_BF5XX_I2S
          mode (supports single stereo In/Out).
          You will also need to select the audio interfaces to support below.
 
-config SND_BF5XX_TDM
-       tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
-       depends on (BLACKFIN && SND_SOC)
-       help
-         Say Y or M if you want to add support for codecs attached to
-         the Blackfin SPORT (synchronous serial ports) interface in TDM
-         mode.
-         You will also need to select the audio interfaces to support below.
-
 config SND_BF5XX_SOC_SSM2602
        tristate "SoC SSM2602 Audio support for BF52x ezkit"
        depends on SND_BF5XX_I2S
@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE
          Enter the GPIO used to control AD73311's SE pin. Acceptable
          values are 0 to 7
 
+config SND_BF5XX_TDM
+       tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
+       depends on (BLACKFIN && SND_SOC)
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the Blackfin SPORT (synchronous serial ports) interface in TDM
+         mode.
+         You will also need to select the audio interfaces to support below.
+
+config SND_BF5XX_SOC_AD1836
+       tristate "SoC AD1836 Audio support for BF5xx"
+       depends on SND_BF5XX_TDM
+       select SND_BF5XX_SOC_TDM
+       select SND_SOC_AD1836
+       help
+         Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
+
+config SND_BF5XX_SOC_AD1938
+       tristate "SoC AD1938 Audio support for Blackfin"
+       depends on SND_BF5XX_TDM
+       select SND_BF5XX_SOC_TDM
+       select SND_SOC_AD1938
+       help
+         Say Y if you want to add support for AD1938 codec on Blackfin.
+
 config SND_BF5XX_AC97
        tristate "SoC AC97 Audio for the ADI BF5xx chip"
        depends on BLACKFIN
@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT
          Say y if you want AC97 driver to support up to 5.1 channel audio.
          this mode will consume much more memory for DMA.
 
+config SND_BF5XX_HAVE_COLD_RESET
+       bool "BOARD has COLD Reset GPIO"
+       depends on SND_BF5XX_AC97
+       default y if BFIN548_EZKIT
+       default n if !BFIN548_EZKIT
+
+config SND_BF5XX_RESET_GPIO_NUM
+       int "Set a GPIO for cold reset"
+       depends on SND_BF5XX_HAVE_COLD_RESET
+       range 0 159
+       default 19 if BFIN548_EZKIT
+       default 5 if BFIN537_STAMP
+       default 0
+       help
+         Set the correct GPIO for RESET the sound chip.
+
+config SND_BF5XX_SOC_AD1980
+       tristate "SoC AD1980/1 Audio support for BF5xx"
+       depends on SND_BF5XX_AC97
+       select SND_BF5XX_SOC_AC97
+       select SND_SOC_AD1980
+       help
+         Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
+
 config SND_BF5XX_SOC_SPORT
        tristate
 
@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97
        select SND_SOC_AC97_BUS
        select SND_BF5XX_SOC_SPORT
 
-config SND_BF5XX_SOC_AD1836
-       tristate "SoC AD1836 Audio support for BF5xx"
-       depends on SND_BF5XX_TDM
-       select SND_BF5XX_SOC_TDM
-       select SND_SOC_AD1836
-       help
-         Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD1980
-       tristate "SoC AD1980/1 Audio support for BF5xx"
-       depends on SND_BF5XX_AC97
-       select SND_BF5XX_SOC_AC97
-       select SND_SOC_AD1980
-       help
-         Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD1938
-        tristate "SoC AD1938 Audio support for Blackfin"
-        depends on SND_BF5XX_TDM
-        select SND_BF5XX_SOC_TDM
-        select SND_SOC_AD1938
-        help
-          Say Y if you want to add support for AD1938 codec on Blackfin.
-
 config SND_BF5XX_SPORT_NUM
        int "Set a SPORT for Sound chip"
        depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM
        default 0
        help
          Set the correct SPORT for sound chip.
-
-config SND_BF5XX_HAVE_COLD_RESET
-       bool "BOARD has COLD Reset GPIO"
-       depends on SND_BF5XX_AC97
-       default y if BFIN548_EZKIT
-       default n if !BFIN548_EZKIT
-
-config SND_BF5XX_RESET_GPIO_NUM
-       int "Set a GPIO for cold reset"
-       depends on SND_BF5XX_HAVE_COLD_RESET
-       range 0 159
-       default 19 if BFIN548_EZKIT
-       default 5 if BFIN537_STAMP
-       default 0
-       help
-         Set the correct GPIO for RESET the sound chip.
index 1e9d161c76c4ff9b74e8f34b6cb923db76378850..084b68884adaa7d407e0e67ded3aa07b41edd9ee 100644 (file)
@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = {
  * TFS. When Port G is selected and EMAC then there is a conflict between
  * the PHY interrupt line and TFS.  Current settings prevent the conflict
  * by ignoring the TFS pin when Port G is selected. This allows both
- * ssm2602 using Port G and EMAC concurrently.
+ * codecs and EMAC using Port G concurrently.
  */
-#ifdef CONFIG_BF527_SPORT0_PORTF
-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
-#else
+#ifdef CONFIG_BF527_SPORT0_PORTG
 #define LOCAL_SPORT0_TFS (0)
+#else
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
 #endif
 
 static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
index 3096badf09a565eb508f01d28579a1e48d4f7b87..ff546e91a22ef711484aaf07b155a23607667257 100644 (file)
@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = {
  * TFS. When Port G is selected and EMAC then there is a conflict between
  * the PHY interrupt line and TFS.  Current settings prevent the conflict
  * by ignoring the TFS pin when Port G is selected. This allows both
- * ssm2602 using Port G and EMAC concurrently.
+ * codecs and EMAC using Port G concurrently.
  */
-#ifdef CONFIG_BF527_SPORT0_PORTF
-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
-#else
+#ifdef CONFIG_BF527_SPORT0_PORTG
 #define LOCAL_SPORT0_TFS (0)
+#else
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
 #endif
 
 static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
index 12a6c549ee6e56857110204c1fbab964dbfbe2ea..4ae707048021886c45533ec6c5f6ca5cadf3999c 100644 (file)
@@ -97,22 +97,19 @@ enum {
        DAVINCI_MCBSP_WORD_32,
 };
 
-static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
-       .name = "I2S PCM Stereo out",
-};
-
-static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
-       .name = "I2S PCM Stereo in",
-};
-
 struct davinci_mcbsp_dev {
+       /*
+        * dma_params must be first because rtd->dai->cpu_dai->private_data
+        * is cast to a pointer of an array of struct davinci_pcm_dma_params in
+        * davinci_pcm_open.
+        */
+       struct davinci_pcm_dma_params   dma_params[2];
        void __iomem                    *base;
 #define MOD_DSP_A      0
 #define MOD_DSP_B      1
        int                             mode;
        u32                             pcr;
        struct clk                      *clk;
-       struct davinci_pcm_dma_params   *dma_params[2];
 };
 
 static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
        toggle_clock(dev, playback);
 }
 
-static int davinci_i2s_startup(struct snd_pcm_substream *substream,
-                              struct snd_soc_dai *cpu_dai)
-{
-       struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
-       cpu_dai->dma_data = dev->dma_params[substream->stream];
-       return 0;
-}
-
 #define DEFAULT_BITPERSAMPLE   16
 
 static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct davinci_pcm_dma_params *dma_params = dai->dma_data;
        struct davinci_mcbsp_dev *dev = dai->private_data;
+       struct davinci_pcm_dma_params *dma_params =
+                                       &dev->dma_params[substream->stream];
        struct snd_interval *i = NULL;
        int mcbsp_word_length;
        unsigned int rcr, xcr, srgr;
@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
 #define DAVINCI_I2S_RATES      SNDRV_PCM_RATE_8000_96000
 
 static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
-       .startup        = davinci_i2s_startup,
        .shutdown       = davinci_i2s_shutdown,
        .prepare        = davinci_i2s_prepare,
        .trigger        = davinci_i2s_trigger,
@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
 
        dev->base = (void __iomem *)IO_ADDRESS(mem->start);
 
-       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out;
-       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
+       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
            (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
 
-       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in;
-       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
+       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
            (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
 
        /* first TX, then RX */
@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
                ret = -ENXIO;
                goto err_free_mem;
        }
-       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start;
+       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
 
        res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
        if (!res) {
@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
                ret = -ENXIO;
                goto err_free_mem;
        }
-       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start;
+       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
 
        davinci_i2s_dai.private_data = dev;
        ret = snd_soc_register_dai(&davinci_i2s_dai);
index 7a06c0a86665a806e0dfbda55f3bb34b509e6f7a..5d1f98a4c97869fa41d446327a879f383b11136c 100644 (file)
@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
                printk(KERN_ERR "GBLCTL write error\n");
 }
 
-static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
-                                               struct snd_soc_dai *cpu_dai)
-{
-       struct davinci_audio_dev *dev = cpu_dai->private_data;
-       cpu_dai->dma_data = dev->dma_params[substream->stream];
-       return 0;
-}
-
 static void mcasp_start_rx(struct davinci_audio_dev *dev)
 {
        mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
 
 static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
 {
-       if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               if (dev->txnumevt)      /* enable FIFO */
+                       mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+                                                               FIFO_ENABLE);
                mcasp_start_tx(dev);
-       else
+       } else {
+               if (dev->rxnumevt)      /* enable FIFO */
+                       mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+                                                               FIFO_ENABLE);
                mcasp_start_rx(dev);
-
-       /* enable FIFO */
-       if (dev->txnumevt)
-               mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
-
-       if (dev->rxnumevt)
-               mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+       }
 }
 
 static void mcasp_stop_rx(struct davinci_audio_dev *dev)
@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
 
 static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
 {
-       if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               if (dev->txnumevt)      /* disable FIFO */
+                       mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+                                                               FIFO_ENABLE);
                mcasp_stop_tx(dev);
-       else
+       } else {
+               if (dev->rxnumevt)      /* disable FIFO */
+                       mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+                                                               FIFO_ENABLE);
                mcasp_stop_rx(dev);
-
-       /* disable FIFO */
-       if (dev->txnumevt)
-               mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
-
-       if (dev->rxnumevt)
-               mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+       }
 }
 
 static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -720,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
 {
        struct davinci_audio_dev *dev = cpu_dai->private_data;
        struct davinci_pcm_dma_params *dma_params =
-                                       dev->dma_params[substream->stream];
+                                       &dev->dma_params[substream->stream];
        int word_length;
        u8 numevt;
 
@@ -798,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
 }
 
 static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
-       .startup        = davinci_mcasp_startup,
        .trigger        = davinci_mcasp_trigger,
        .hw_params      = davinci_mcasp_hw_params,
        .set_fmt        = davinci_mcasp_set_dai_fmt,
@@ -849,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
        struct resource *mem, *ioarea, *res;
        struct snd_platform_data *pdata;
        struct davinci_audio_dev *dev;
-       int count = 0;
        int ret = 0;
 
        dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
        if (!dev)
                return  -ENOMEM;
 
-       dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
-                                                               GFP_KERNEL);
-       if (!dma_data) {
-               ret = -ENOMEM;
-               goto err_release_dev;
-       }
-
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mem) {
                dev_err(&pdev->dev, "no mem resource?\n");
@@ -897,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
        dev->txnumevt = pdata->txnumevt;
        dev->rxnumevt = pdata->rxnumevt;
 
-       dma_data[count].name = "I2S PCM Stereo out";
-       dma_data[count].eventq_no = pdata->eventq_no;
-       dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
+       dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
+       dma_data->eventq_no = pdata->eventq_no;
+       dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
                                                        io_v2p(dev->base));
-       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
 
        /* first TX, then RX */
        res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -910,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                goto err_release_region;
        }
 
-       dma_data[count].channel = res->start;
-       count++;
-       dma_data[count].name = "I2S PCM Stereo in";
-       dma_data[count].eventq_no = pdata->eventq_no;
-       dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
+       dma_data->channel = res->start;
+
+       dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
+       dma_data->eventq_no = pdata->eventq_no;
+       dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
                                                        io_v2p(dev->base));
-       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
 
        res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
        if (!res) {
@@ -924,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                goto err_release_region;
        }
 
-       dma_data[count].channel = res->start;
+       dma_data->channel = res->start;
        davinci_mcasp_dai[pdata->op_mode].private_data = dev;
        davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
        ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
@@ -936,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
 err_release_region:
        release_mem_region(mem->start, (mem->end - mem->start) + 1);
 err_release_data:
-       kfree(dma_data);
-err_release_dev:
        kfree(dev);
 
        return ret;
@@ -946,7 +925,6 @@ err_release_dev:
 static int davinci_mcasp_remove(struct platform_device *pdev)
 {
        struct snd_platform_data *pdata = pdev->dev.platform_data;
-       struct davinci_pcm_dma_params *dma_data;
        struct davinci_audio_dev *dev;
        struct resource *mem;
 
@@ -959,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(mem->start, (mem->end - mem->start) + 1);
 
-       dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
-       kfree(dma_data);
        kfree(dev);
 
        return 0;
index 554354c1cc2f1bf786bf006bdca62310a53c568b..9d179cc88f7b84a9614753c0af34aef28a16c74d 100644 (file)
@@ -39,10 +39,15 @@ enum {
 };
 
 struct davinci_audio_dev {
+       /*
+        * dma_params must be first because rtd->dai->cpu_dai->private_data
+        * is cast to a pointer of an array of struct davinci_pcm_dma_params in
+        * davinci_pcm_open.
+        */
+       struct davinci_pcm_dma_params dma_params[2];
        void __iomem *base;
        int sample_rate;
        struct clk *clk;
-       struct davinci_pcm_dma_params *dma_params[2];
        unsigned int codec_fmt;
 
        /* McASP specific data */
index 2f7da49ed34fd1cd6219ad634f55c224f25fa8a6..c73a915f233f3d397639bfcb669ffbd834f3aee1 100644 (file)
@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
 static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
 {
        struct davinci_runtime_data *prtd = substream->runtime->private_data;
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
        struct edmacc_param p_ram;
        int ret;
 
-       if (!dma_data)
-               return -ENODEV;
-
-       prtd->params = dma_data;
-
        /* Request master DMA channel */
        ret = edma_alloc_channel(prtd->params->channel,
                                  davinci_pcm_dma_irq, substream,
@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct davinci_runtime_data *prtd;
        int ret = 0;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data;
+       struct davinci_pcm_dma_params *params = &pa[substream->stream];
+       if (!params)
+               return -ENODEV;
 
        snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
        /* ensure that buffer size is a multiple of period size */
@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
                return -ENOMEM;
 
        spin_lock_init(&prtd->lock);
+       prtd->params = params;
 
        runtime->private_data = prtd;
 
index 63d96253c73a13dd6825245d6c34f6a669b1f291..8746606efc893114a10f4135fe2420006da96321 100644 (file)
@@ -17,7 +17,6 @@
 
 
 struct davinci_pcm_dma_params {
-       char *name;                     /* stream identifier */
        int channel;                    /* sync dma channel ID */
        unsigned short acnt;
        dma_addr_t dma_addr;            /* device physical address for DMA */
index 6375b4ea525dc572ca4feae6a8b69db703ecce1a..dcb3181bb3406a66fc1c5843a8b9be743a87fc78 100644 (file)
@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701
 
 config SND_PXA2XX_SOC_IMOTE2
        tristate "SoC Audio support for IMote 2"
-       depends on SND_PXA2XX_SOC && MACH_INTELMOTE2
+       depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_SOC_WM8940
        help
index ab5a3ac2ac47c5ee9aa086d87481e5446777438d..9efcfd08d747b1c430ae17f9429fda3b57974a0b 100644 (file)
@@ -898,6 +898,11 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
  * build a feature control
  */
 
+static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
+{
+       return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
+}
+
 static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
                              unsigned int ctl_mask, int control,
                              struct usb_audio_term *iterm, int unitid)
@@ -978,13 +983,13 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
                 */
                if (! mapped_name && ! (state->oterm.type >> 16)) {
                        if ((state->oterm.type & 0xff00) == 0x0100) {
-                               len = strlcat(kctl->id.name, " Capture", sizeof(kctl->id.name));
+                               len = append_ctl_name(kctl, " Capture");
                        } else {
-                               len = strlcat(kctl->id.name + len, " Playback", sizeof(kctl->id.name));
+                               len = append_ctl_name(kctl, " Playback");
                        }
                }
-               strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume",
-                       sizeof(kctl->id.name));
+               append_ctl_name(kctl, control == USB_FEATURE_MUTE ?
+                               " Switch" : " Volume");
                if (control == USB_FEATURE_VOLUME) {
                        kctl->tlv.c = mixer_vol_tlv;
                        kctl->vd[0].access |= 
@@ -1143,7 +1148,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
                len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
        if (! len)
                len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
-       strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name));
+       append_ctl_name(kctl, " Volume");
 
        snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
                    cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1400,8 +1405,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
                        if (! len)
                                strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
                }
-               strlcat(kctl->id.name, " ", sizeof(kctl->id.name));
-               strlcat(kctl->id.name, valinfo->suffix, sizeof(kctl->id.name));
+               append_ctl_name(kctl, " ");
+               append_ctl_name(kctl, valinfo->suffix);
 
                snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
                            cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1610,9 +1615,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
                        strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
 
                if ((state->oterm.type & 0xff00) == 0x0100)
-                       strlcat(kctl->id.name, " Capture Source", sizeof(kctl->id.name));
+                       append_ctl_name(kctl, " Capture Source");
                else
-                       strlcat(kctl->id.name, " Playback Source", sizeof(kctl->id.name));
+                       append_ctl_name(kctl, " Playback Source");
        }
 
        snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
index b5e7e3f1183f24236fcaef9d16c4cfad63326f83..e79c54034bcde0ea9ff278af1d5a6730948b0939 100644 (file)
@@ -2625,7 +2625,7 @@ static int vcpu_stat_get(void *_offset, u64 *val)
 
 DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n");
 
-static struct file_operations *stat_fops[] = {
+static const struct file_operations *stat_fops[] = {
        [KVM_STAT_VCPU] = &vcpu_stat_fops,
        [KVM_STAT_VM]   = &vm_stat_fops,
 };