Merge git://git.infradead.org/mtd-2.6
authorKaiGai Kohei <kaigai@ak.jp.nec.com>
Thu, 18 May 2006 15:43:53 +0000 (00:43 +0900)
committerKaiGai Kohei <kaigai@ak.jp.nec.com>
Thu, 18 May 2006 15:43:53 +0000 (00:43 +0900)
360 files changed:
CREDITS
Documentation/devices.txt
Documentation/memory-barriers.txt
Documentation/networking/operstates.txt [new file with mode: 0644]
Documentation/scsi/ChangeLog.megaraid
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/boot/compressed/misc.c
arch/arm/configs/collie_defconfig
arch/arm/configs/versatile_defconfig
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/head-nommu.S
arch/arm/kernel/head.S
arch/arm/kernel/process.c
arch/arm/mach-aaec2000/aaed2000.c
arch/arm/mach-aaec2000/core.c
arch/arm/mach-aaec2000/core.h
arch/arm/mach-imx/generic.c
arch/arm/mach-imx/mx1ads.c
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-ixp4xx/Makefile
arch/arm/mach-pxa/dma.c
arch/arm/mach-sa1100/irq.c
arch/arm/tools/mach-types
arch/arm/vfp/vfpmodule.c
arch/i386/Kconfig
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/mpparse.c
arch/i386/kernel/setup.c
arch/i386/oprofile/nmi_int.c
arch/ia64/lib/memcpy_mck.S
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/prom.c
arch/powerpc/platforms/pseries/eeh_event.c
arch/ppc/kernel/head_8xx.S
arch/ppc/platforms/mpc866ads_setup.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/syscalls.S
arch/s390/kernel/time.c
arch/sparc/kernel/ioport.c
arch/sparc/kernel/module.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/systbls.S
arch/sparc64/defconfig
arch/sparc64/kernel/module.c
arch/sparc64/kernel/sys32.S
arch/sparc64/kernel/systbls.S
arch/um/kernel/time_kern.c
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/traps.c
block/elevator.c
block/ll_rw_blk.c
drivers/base/class.c
drivers/block/ub.c
drivers/char/Kconfig
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/rio/host.h
drivers/char/rio/rioboot.c
drivers/char/rio/rioctrl.c
drivers/char/rio/rioioctl.h
drivers/char/tpm/Kconfig
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_tis.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/edac/e752x_edac.c
drivers/i2c/busses/scx200_acb.c
drivers/ide/legacy/ide-cs.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/mad_priv.h
drivers/infiniband/core/mad_rmpp.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/ucm.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_dev.h
drivers/infiniband/hw/mthca/mthca_mr.c
drivers/infiniband/hw/mthca/mthca_provider.h
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/input/touchscreen/corgi_ts.c
drivers/isdn/capi/capi.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/leds/Kconfig
drivers/leds/led-class.c
drivers/leds/ledtrig-timer.c
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptspi.c
drivers/mmc/at91_mci.c
drivers/mmc/au1xmmc.c
drivers/mmc/imxmmc.c
drivers/mmc/mmc.c
drivers/mmc/mmc_block.c
drivers/mmc/mmci.c
drivers/mmc/pxamci.c
drivers/mmc/sdhci.c
drivers/mmc/wbsd.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_probe.c
drivers/mtd/chips/gen_probe.c
drivers/mtd/devices/Kconfig
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/docprobe.c
drivers/mtd/devices/phram.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/cfi_flagadm.c
drivers/mtd/maps/dbox2-flash.c
drivers/mtd/maps/mtx-1_flash.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/physmap.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/autcpu12.c
drivers/mtd/nand/cs553x_nand.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/edb7312.c
drivers/mtd/nand/h1910.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_ecc.c
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/ppchameleonevb.c
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/sharpsl.c
drivers/mtd/nand/spia.c
drivers/mtd/nand/toto.c
drivers/mtd/nand/ts7250.c
drivers/mtd/redboot.c
drivers/mtd/rfd_ftl.c
drivers/net/au1000_eth.c
drivers/net/dl2k.c
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/scc.c
drivers/net/hamradio/yam.c
drivers/net/irda/Makefile
drivers/net/irda/irda-usb.c
drivers/net/irda/sir-dev.h
drivers/net/irda/sir_dev.c
drivers/net/irda/sir_kthread.c [deleted file]
drivers/net/irda/smsc-ircc2.c
drivers/net/ne.c
drivers/net/phy/mdio_bus.c
drivers/net/sis900.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/spider_net.c
drivers/net/spider_net.h
drivers/net/sungem_phy.c
drivers/net/sungem_phy.h
drivers/net/tg3.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_main.h
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
drivers/pci/quirks.c
drivers/pcmcia/pcmcia_ioctl.c
drivers/rtc/rtc-sa1100.c
drivers/s390/net/lcs.c
drivers/sbus/char/openprom.c
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
drivers/scsi/aic7xxx/aic7xxx_pci.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_disc.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/megaraid.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mbox.h
drivers/scsi/megaraid/megaraid_mm.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_lib.c
drivers/scsi/sim710.c
drivers/serial/8250.c
drivers/serial/8250_au1x00.c
drivers/serial/cpm_uart/cpm_uart.h
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/cpm_uart/cpm_uart_cpm1.c
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/imx.c
drivers/serial/serial_core.c
drivers/sn/ioc4.c
drivers/usb/atm/speedtch.c
drivers/usb/atm/usbatm.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/host/ohci-hcd.c
drivers/usb/input/hid-core.c
drivers/usb/misc/emi26.c
drivers/usb/misc/emi62.c
drivers/usb/net/pegasus.c
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/airprime.c
drivers/usb/serial/ark3116.c [new file with mode: 0644]
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/generic.c
drivers/usb/serial/omninet.c
drivers/usb/serial/usb-serial.c
drivers/video/backlight/backlight.c
drivers/video/backlight/lcd.c
drivers/video/logo/Makefile
fs/9p/fcall.c
fs/9p/mux.c
fs/9p/mux.h
fs/9p/vfs_file.c
fs/9p/vfs_inode.c
fs/autofs4/autofs_i.h
fs/autofs4/root.c
fs/autofs4/waitq.c
fs/compat.c
fs/ext3/inode.c
fs/jffs2/compr.c
fs/jffs2/compr_zlib.c
fs/jffs2/file.c
fs/jffs2/nodelist.c
fs/jffs2/scan.c
fs/jffs2/summary.c
fs/jffs2/super.c
fs/locks.c
fs/namespace.c
fs/open.c
fs/partitions/check.c
fs/smbfs/dir.c
fs/smbfs/request.c
fs/splice.c
fs/xfs/xfs_alloc.c
fs/xfs/xfs_rename.c
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vnodeops.c
include/asm-arm/arch-aaec2000/debug-macro.S
include/asm-arm/arch-aaec2000/entry-macro.S
include/asm-arm/arch-imx/debug-macro.S
include/asm-arm/arch-imx/imx-uart.h [new file with mode: 0644]
include/asm-arm/arch-ixp4xx/io.h
include/asm-arm/arch-ixp4xx/memory.h
include/asm-arm/arch-pxa/dma.h
include/asm-arm/bug.h
include/asm-arm/unistd.h
include/asm-i386/io_apic.h
include/asm-ia64/bitops.h
include/asm-powerpc/uaccess.h
include/asm-ppc/commproc.h
include/asm-ppc/cpm2.h
include/asm-ppc/page.h
include/asm-s390/unistd.h
include/asm-sparc/unistd.h
include/asm-sparc64/unistd.h
include/asm-x86_64/e820.h
include/asm-x86_64/io_apic.h
include/linux/device.h
include/linux/dma-mapping.h
include/linux/fs_uart_pd.h [new file with mode: 0644]
include/linux/jffs2.h
include/linux/kernel.h
include/linux/mmc/card.h
include/linux/mtd/mtd.h
include/linux/mtd/physmap.h
include/linux/netdevice.h
include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h
include/linux/pipe_fs_i.h
include/linux/rcupdate.h
include/linux/serial_core.h
include/linux/slab.h
include/linux/swap.h
include/net/ax25.h
include/net/ieee80211.h
include/net/ieee80211softmac.h
include/net/neighbour.h
include/net/netrom.h
include/net/rose.h
include/net/sctp/structs.h
include/scsi/srp.h
init/do_mounts.c
init/initramfs.c
kernel/extable.c
kernel/module.c
kernel/ptrace.c
kernel/rcupdate.c
lib/Kconfig.debug
mm/page_alloc.c
mm/slab.c
mm/sparse.c
net/atm/clip.c
net/ax25/af_ax25.c
net/ax25/ax25_addr.c
net/ax25/ax25_ds_timer.c
net/ax25/ax25_iface.c
net/ax25/ax25_ip.c
net/ax25/ax25_out.c
net/ax25/ax25_route.c
net/ax25/ax25_timer.c
net/ax25/ax25_uid.c
net/ax25/sysctl_net_ax25.c
net/bridge/br_if.c
net/bridge/br_input.c
net/core/dev.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net-sysfs.c
net/dccp/proto.c
net/decnet/dn_neigh.c
net/ieee80211/softmac/ieee80211softmac_assoc.c
net/ieee80211/softmac/ieee80211softmac_auth.c
net/ieee80211/softmac/ieee80211softmac_module.c
net/ieee80211/softmac/ieee80211softmac_scan.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/netfilter/ip_conntrack_helper_h323.c
net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/tcp.c
net/ipv4/tcp_highspeed.c
net/ipv6/inet6_connection_sock.c
net/irda/irias_object.c
net/netfilter/x_tables.c
net/netrom/af_netrom.c
net/netrom/nr_dev.c
net/rose/af_rose.c
net/rose/rose_dev.c
net/rose/rose_link.c
net/rose/rose_route.c
net/sched/sch_hfsc.c
net/sctp/inqueue.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/ulpqueue.c
scripts/gen_initramfs_list.sh
scripts/mkmakefile
scripts/mod/modpost.c
security/selinux/hooks.c
security/selinux/include/security.h
security/selinux/ss/services.c

diff --git a/CREDITS b/CREDITS
index 787564b..9bf714a 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1194,15 +1194,9 @@ S: Brecksville, OH  44141-1334
 S: USA
 
 N: Tristan Greaves
-E: Tristan.Greaves@icl.com
-E: tmg296@ecs.soton.ac.uk
-W: http://www.ecs.soton.ac.uk/~tmg296
+E: tristan@extricate.org
+W: http://www.extricate.org/
 D: Miscellaneous ipv4 sysctl patches
-S: 15 Little Mead
-S: Denmead
-S: Hampshire
-S: PO7 6HS
-S: United Kingdom
 
 N: Michael A. Griffith
 E: grif@cs.ucr.edu
@@ -3247,14 +3241,9 @@ S: 12725 SW Millikan Way, Suite 400
 S: Beaverton, Oregon 97005
 S: USA
 
-N: Marcelo W. Tosatti
-E: marcelo.tosatti@cyclades.com
-D: Miscellaneous kernel hacker
+N: Marcelo Tosatti
+E: marcelo@kvack.org
 D: v2.4 kernel maintainer
-D: Current pc300/cyclades maintainer
-S: Cyclades Corporation
-S: Av Cristovao Colombo, 462. Floresta.
-S: Porto Alegre
 S: Brazil
 
 N: Stefan Traby
index 3c406ac..b369a8c 100644 (file)
@@ -1721,11 +1721,6 @@ Your cooperation is appreciated.
                These devices support the same API as the generic SCSI
                devices.
 
- 97 block      Packet writing for CD/DVD devices
-                 0 = /dev/pktcdvd0     First packet-writing module
-                 1 = /dev/pktcdvd1     Second packet-writing module
-                   ...
-
  98 char       Control and Measurement Device (comedi)
                  0 = /dev/comedi0      First comedi device
                  1 = /dev/comedi1      Second comedi device
index 92f0056..c61d8b8 100644 (file)
@@ -1031,7 +1031,7 @@ conflict on any particular lock.
 LOCKS VS MEMORY ACCESSES
 ------------------------
 
-Consider the following: the system has a pair of spinlocks (N) and (Q), and
+Consider the following: the system has a pair of spinlocks (M) and (Q), and
 three CPUs; then should the following sequence of events occur:
 
        CPU 1                           CPU 2
@@ -1678,7 +1678,7 @@ CPU's caches by some other cache event:
        smp_wmb();
        <A:modify v=2>  <C:busy>
                        <C:queue v=2>
-       p = &b;         q = p;
+       p = &v;         q = p;
                        <D:request p>
        <B:modify p=&v> <D:commit p=&v>
                        <D:read p>
diff --git a/Documentation/networking/operstates.txt b/Documentation/networking/operstates.txt
new file mode 100644 (file)
index 0000000..4a21d9b
--- /dev/null
@@ -0,0 +1,161 @@
+
+1. Introduction
+
+Linux distinguishes between administrative and operational state of an
+interface. Admininstrative state is the result of "ip link set dev
+<dev> up or down" and reflects whether the administrator wants to use
+the device for traffic.
+
+However, an interface is not usable just because the admin enabled it
+- ethernet requires to be plugged into the switch and, depending on
+a site's networking policy and configuration, an 802.1X authentication
+to be performed before user data can be transferred. Operational state
+shows the ability of an interface to transmit this user data.
+
+Thanks to 802.1X, userspace must be granted the possibility to
+influence operational state. To accommodate this, operational state is
+split into two parts: Two flags that can be set by the driver only, and
+a RFC2863 compatible state that is derived from these flags, a policy,
+and changeable from userspace under certain rules.
+
+
+2. Querying from userspace
+
+Both admin and operational state can be queried via the netlink
+operation RTM_GETLINK. It is also possible to subscribe to RTMGRP_LINK
+to be notified of updates. This is important for setting from userspace.
+
+These values contain interface state:
+
+ifinfomsg::if_flags & IFF_UP:
+ Interface is admin up
+ifinfomsg::if_flags & IFF_RUNNING:
+ Interface is in RFC2863 operational state UP or UNKNOWN. This is for
+ backward compatibility, routing daemons, dhcp clients can use this
+ flag to determine whether they should use the interface.
+ifinfomsg::if_flags & IFF_LOWER_UP:
+ Driver has signaled netif_carrier_on()
+ifinfomsg::if_flags & IFF_DORMANT:
+ Driver has signaled netif_dormant_on()
+
+These interface flags can also be queried without netlink using the
+SIOCGIFFLAGS ioctl.
+
+TLV IFLA_OPERSTATE
+
+contains RFC2863 state of the interface in numeric representation:
+
+IF_OPER_UNKNOWN (0):
+ Interface is in unknown state, neither driver nor userspace has set
+ operational state. Interface must be considered for user data as
+ setting operational state has not been implemented in every driver.
+IF_OPER_NOTPRESENT (1):
+ Unused in current kernel (notpresent interfaces normally disappear),
+ just a numerical placeholder.
+IF_OPER_DOWN (2):
+ Interface is unable to transfer data on L1, f.e. ethernet is not
+ plugged or interface is ADMIN down.
+IF_OPER_LOWERLAYERDOWN (3):
+ Interfaces stacked on an interface that is IF_OPER_DOWN show this
+ state (f.e. VLAN).
+IF_OPER_TESTING (4):
+ Unused in current kernel.
+IF_OPER_DORMANT (5):
+ Interface is L1 up, but waiting for an external event, f.e. for a
+ protocol to establish. (802.1X)
+IF_OPER_UP (6):
+ Interface is operational up and can be used.
+
+This TLV can also be queried via sysfs.
+
+TLV IFLA_LINKMODE
+
+contains link policy. This is needed for userspace interaction
+described below.
+
+This TLV can also be queried via sysfs.
+
+
+3. Kernel driver API
+
+Kernel drivers have access to two flags that map to IFF_LOWER_UP and
+IFF_DORMANT. These flags can be set from everywhere, even from
+interrupts. It is guaranteed that only the driver has write access,
+however, if different layers of the driver manipulate the same flag,
+the driver has to provide the synchronisation needed.
+
+__LINK_STATE_NOCARRIER, maps to !IFF_LOWER_UP:
+
+The driver uses netif_carrier_on() to clear and netif_carrier_off() to
+set this flag. On netif_carrier_off(), the scheduler stops sending
+packets. The name 'carrier' and the inversion are historical, think of
+it as lower layer.
+
+netif_carrier_ok() can be used to query that bit.
+
+__LINK_STATE_DORMANT, maps to IFF_DORMANT:
+
+Set by the driver to express that the device cannot yet be used
+because some driver controlled protocol establishment has to
+complete. Corresponding functions are netif_dormant_on() to set the
+flag, netif_dormant_off() to clear it and netif_dormant() to query.
+
+On device allocation, networking core sets the flags equivalent to
+netif_carrier_ok() and !netif_dormant().
+
+
+Whenever the driver CHANGES one of these flags, a workqueue event is
+scheduled to translate the flag combination to IFLA_OPERSTATE as
+follows:
+
+!netif_carrier_ok():
+ IF_OPER_LOWERLAYERDOWN if the interface is stacked, IF_OPER_DOWN
+ otherwise. Kernel can recognise stacked interfaces because their
+ ifindex != iflink.
+
+netif_carrier_ok() && netif_dormant():
+ IF_OPER_DORMANT
+
+netif_carrier_ok() && !netif_dormant():
+ IF_OPER_UP if userspace interaction is disabled. Otherwise
+ IF_OPER_DORMANT with the possibility for userspace to initiate the
+ IF_OPER_UP transition afterwards.
+
+
+4. Setting from userspace
+
+Applications have to use the netlink interface to influence the
+RFC2863 operational state of an interface. Setting IFLA_LINKMODE to 1
+via RTM_SETLINK instructs the kernel that an interface should go to
+IF_OPER_DORMANT instead of IF_OPER_UP when the combination
+netif_carrier_ok() && !netif_dormant() is set by the
+driver. Afterwards, the userspace application can set IFLA_OPERSTATE
+to IF_OPER_DORMANT or IF_OPER_UP as long as the driver does not set
+netif_carrier_off() or netif_dormant_on(). Changes made by userspace
+are multicasted on the netlink group RTMGRP_LINK.
+
+So basically a 802.1X supplicant interacts with the kernel like this:
+
+-subscribe to RTMGRP_LINK
+-set IFLA_LINKMODE to 1 via RTM_SETLINK
+-query RTM_GETLINK once to get initial state
+-if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until
+ netlink multicast signals this state
+-do 802.1X, eventually abort if flags go down again
+-send RTM_SETLINK to set operstate to IF_OPER_UP if authentication
+ succeeds, IF_OPER_DORMANT otherwise
+-see how operstate and IFF_RUNNING is echoed via netlink multicast
+-set interface back to IF_OPER_DORMANT if 802.1X reauthentication
+ fails
+-restart if kernel changes IFF_LOWER_UP or IFF_DORMANT flag
+
+if supplicant goes down, bring back IFLA_LINKMODE to 0 and
+IFLA_OPERSTATE to a sane value.
+
+A routing daemon or dhcp client just needs to care for IFF_RUNNING or
+waiting for operstate to go IF_OPER_UP/IF_OPER_UNKNOWN before
+considering the interface / querying a DHCP address.
+
+
+For technical questions and/or comments please e-mail to Stefan Rompf
+(stefan at loplof.de).
index 09f6300..c173806 100644 (file)
@@ -1,3 +1,28 @@
+Release Date   : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)
+Older Version  : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
+
+1.     Fixed a bug in megaraid_reset_handler().
+       Customer reported "Unable to handle kernel NULL pointer dereference
+       at virtual address 00000000" when system goes to reset condition
+       for some reason. It happened randomly.
+       Root Cause: in the megaraid_reset_handler(), there is possibility not
+       returning pending packets in the pend_list if there are multiple
+       pending packets.
+       Fix: Made the change in the driver so that it will return all packets
+       in the pend_list.
+
+2.     Added change request.
+       As found in the following URL, rmb() only didn't help the
+       problem. I had to increase the loop counter to 0xFFFFFF. (6 F's)
+       http://marc.theaimsgroup.com/?l=linux-scsi&m=110971060502497&w=2
+
+       I attached a patch for your reference, too.
+       Could you check and get this fix in your driver?
+
+       Best Regards,
+       Jun'ichi Nomura
+
 Release Date   : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
 Older Version  : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
index 564cbfa..e564e4e 100644 (file)
@@ -1480,10 +1480,11 @@ L:      netdev@vger.kernel.org
 S:     Maintained
 
 IRDA SUBSYSTEM
-P:     Jean Tourrilhes
+P:     Samuel Ortiz
+M:     samuel@sortiz.org
 L:     irda-users@lists.sourceforge.net (subscribers-only)
 W:     http://irda.sourceforge.net/
-S:     Odd Fixes
+S:     Maintained
 
 ISAPNP
 P:     Jaroslav Kysela
@@ -1602,6 +1603,11 @@ M:       James.Bottomley@HansenPartnership.com
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 
+LED SUBSYSTEM
+P:     Richard Purdie
+M:     rpurdie@rpsys.net
+S:     Maintained
+
 LEGO USB Tower driver
 P:     Juergen Stuber
 M:     starblue@users.sourceforge.net
@@ -1661,7 +1667,7 @@ S:        Maintained
 
 LINUX FOR POWERPC EMBEDDED PPC8XX
 P:     Marcelo Tosatti
-M:     marcelo.tosatti@cyclades.com
+M:     marcelo@kvack.org
 W:     http://www.penguinppc.org/
 L:     linuxppc-embedded@ozlabs.org
 S:     Maintained
index 6bf9962..3494c17 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 17
-EXTRAVERSION =-rc3
+EXTRAVERSION =-rc4
 NAME=Sliding Snow Leopard
 
 # *DOCUMENTATION*
@@ -344,16 +344,14 @@ scripts_basic:
 scripts/basic/%: scripts_basic ;
 
 PHONY += outputmakefile
-# outputmakefile generate a Makefile to be placed in output directory, if
-# using a seperate output directory. This allows convinient use
-# of make in output directory
+# outputmakefile generates a Makefile in the output directory, if using a
+# separate output directory. This allows convenient use of make in the
+# output directory.
 outputmakefile:
-       $(Q)if test ! $(srctree) -ef $(objtree); then \
-       $(CONFIG_SHELL) $(srctree)/scripts/mkmakefile              \
-           $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)         \
-           > $(objtree)/Makefile;                                 \
-           echo '  GEN    $(objtree)/Makefile';                   \
-       fi
+ifneq ($(KBUILD_SRC),)
+       $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
+           $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
+endif
 
 # To make sure we do not include .config for any of the *config targets
 # catch them early, and hand them over to scripts/kconfig/Makefile
@@ -796,8 +794,8 @@ prepare2: prepare3 outputmakefile
 prepare1: prepare2 include/linux/version.h include/asm \
                    include/config/MARKER
 ifneq ($(KBUILD_MODULES),)
-       $(Q)rm -rf $(MODVERDIR)
        $(Q)mkdir -p $(MODVERDIR)
+       $(Q)rm -f $(MODVERDIR)/*
 endif
 
 archprepare: prepare1 scripts_basic
@@ -1086,8 +1084,8 @@ else # KBUILD_EXTMOD
 KBUILD_MODULES := 1
 PHONY += crmodverdir
 crmodverdir:
-       $(Q)rm -rf $(MODVERDIR)
        $(Q)mkdir -p $(MODVERDIR)
+       $(Q)rm -f $(MODVERDIR)/*
 
 PHONY += $(objtree)/Module.symvers
 $(objtree)/Module.symvers:
index 1dbf6dd..08b7cc9 100644 (file)
@@ -150,8 +150,6 @@ config ARCH_IOP3XX
 
 config ARCH_IXP4XX
        bool "IXP4xx-based"
-       select DMABOUNCE
-       select PCI
        help
          Support for Intel's IXP4XX (XScale) family of processors.
 
index 0af3772..ace3fb5 100644 (file)
@@ -38,10 +38,10 @@ static void icedcc_putc(int ch)
                if (--i < 0)
                        return;
 
-               asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
+               asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
        } while (status & 2);
 
-       asm("mcr p15, 0, %0, c1, c0, 0" : : "r" (ch));
+       asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
 }
 
 #define putc(ch)       icedcc_putc(ch)
index c9aa878..074c47a 100644 (file)
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc3
-# Sun Oct  9 16:55:14 2005
+# Linux kernel version: 2.6.17-rc1
+# Fri Apr 14 19:09:52 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
@@ -23,45 +23,58 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 #
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
+# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
-CONFIG_BASE_FULL=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_EPOLL is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_SLAB is not set
+CONFIG_DOUBLEFAULT=y
 # CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+CONFIG_BASE_SMALL=1
+CONFIG_SLOB=y
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
 #
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
 
 #
 # System Type
@@ -70,11 +83,13 @@ CONFIG_KMOD=y
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -84,9 +99,11 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
 
 #
 # SA11x0 Implementations
@@ -128,20 +145,32 @@ CONFIG_SHARP_SCOOP=y
 # Bus support
 #
 CONFIG_ISA=y
-CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_DEBUG=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_SA1100=y
 
 #
 # Kernel Features
 #
-# CONFIG_SMP is not set
-CONFIG_PREEMPT=y
+# CONFIG_PREEMPT is not set
 # CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_NODES_SHIFT=2
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 CONFIG_DISCONTIGMEM_MANUAL=y
@@ -150,6 +179,7 @@ CONFIG_DISCONTIGMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
 
@@ -158,7 +188,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2   debug"
+CONFIG_CMDLINE="noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1"
 # CONFIG_XIP_KERNEL is not set
 
 #
@@ -181,14 +211,16 @@ CONFIG_FPE_NWFPE=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=m
-CONFIG_BINFMT_MISC=m
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
 # CONFIG_ARTHUR is not set
 
 #
 # Power management options
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
 CONFIG_APM=y
 
 #
@@ -199,6 +231,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -211,16 +244,19 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
+# CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -232,6 +268,11 @@ CONFIG_TCP_CONG_BIC=y
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -244,8 +285,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -265,10 +309,15 @@ CONFIG_TCP_CONG_BIC=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -287,32 +336,49 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
 
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
 # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
 # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
 # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I1 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_I4=y
 # CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 CONFIG_MTD_OBSOLETE_CHIPS=y
 CONFIG_MTD_SHARP=y
+# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_IMPA7 is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -321,7 +387,6 @@ CONFIG_MTD_SHARP=y
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -337,6 +402,11 @@ CONFIG_MTD_SHARP=y
 # CONFIG_MTD_NAND is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -349,7 +419,6 @@ CONFIG_MTD_SHARP=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -359,20 +428,35 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 
 #
-# IO Schedulers
+# ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
 
 #
-# ATA/ATAPI/MFM/RLL support
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
 #
-# CONFIG_IDE is not set
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -402,6 +486,39 @@ CONFIG_ATA_OVER_ETH=m
 # Network device support
 #
 # CONFIG_NETDEVICES is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 
@@ -424,7 +541,7 @@ CONFIG_INPUT_TSDEV=y
 CONFIG_INPUT_TSDEV_SCREEN_X=240
 CONFIG_INPUT_TSDEV_SCREEN_Y=320
 CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=y
+# CONFIG_INPUT_EVBUG is not set
 
 #
 # Input Device Drivers
@@ -438,7 +555,11 @@ CONFIG_KEYBOARD_LOCOMO=y
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -461,7 +582,16 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_CS=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -483,94 +613,48 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_RAW_DRIVER is not set
 
 #
-# TPM devices
+# PCMCIA character devices
 #
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
 
 #
-# I2C support
+# TPM devices
 #
-CONFIG_I2C=m
-# CONFIG_I2C_CHARDEV is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
-# I2C Algorithms
+# I2C support
 #
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
+# CONFIG_I2C is not set
 
 #
-# I2C Hardware Bus support
+# SPI support
 #
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
 
 #
-# Miscellaneous I2C Chip support
+# Dallas's 1-wire bus
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
-CONFIG_HWMON=y
+# CONFIG_HWMON is not set
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -579,42 +663,33 @@ CONFIG_HWMON=y
 #
 # Multimedia Capabilities Port drivers
 #
-# CONFIG_MCP_SA11X0 is not set
+CONFIG_MCP=y
+CONFIG_MCP_SA11X0=y
+CONFIG_MCP_UCB1200=y
+CONFIG_MCP_UCB1200_TS=y
 
 #
-# Multimedia devices
+# LED devices
 #
-CONFIG_VIDEO_DEV=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
 
 #
-# Video For Linux
+# LED drivers
 #
+CONFIG_LEDS_LOCOMO=y
 
 #
-# Video Adapters
+# LED Triggers
 #
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
 
 #
-# Radio Adapters
+# Multimedia devices
 #
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
+# CONFIG_VIDEO_DEV is not set
 
 #
 # Digital Video Broadcasting Devices
@@ -628,8 +703,8 @@ CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_FIRMWARE_EDID is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_SA1100=y
@@ -643,14 +718,15 @@ CONFIG_FB_SA1100=y
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x8 is not set
 # CONFIG_FONT_8x16 is not set
 # CONFIG_FONT_6x11 is not set
 # CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
+CONFIG_FONT_MINI_4x6=y
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
@@ -659,7 +735,11 @@ CONFIG_FONT_8x8=y
 # Logo configuration
 #
 # CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
 
 #
 # Sound
@@ -671,20 +751,17 @@ CONFIG_FONT_8x8=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
 
 #
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
 # USB Gadget Support
 #
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_GADGET is not set
 
 #
 # MMC/SD Card support
@@ -692,23 +769,24 @@ CONFIG_USB_GADGET=y
 # CONFIG_MMC is not set
 
 #
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
 # File systems
 #
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
-CONFIG_INOTIFY=y
+# CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
@@ -725,7 +803,7 @@ CONFIG_INOTIFY=y
 # DOS/FAT/NT Filesystems
 #
 CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+# CONFIG_MSDOS_FS is not set
 CONFIG_VFAT_FS=y
 CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
@@ -739,7 +817,7 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -755,11 +833,12 @@ CONFIG_RAMFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -789,7 +868,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="cp437"
-CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
 # CONFIG_NLS_CODEPAGE_850 is not set
@@ -813,7 +892,7 @@ CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
 # CONFIG_NLS_ISO8859_4 is not set
@@ -826,7 +905,7 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_ISO8859_15 is not set
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Profiling support
@@ -837,20 +916,23 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_WAITQ is not set
 CONFIG_DEBUG_ERRORS=y
@@ -874,7 +956,7 @@ CONFIG_DEBUG_ERRORS=y
 #
 # Library routines
 #
-# CONFIG_CRC_CCITT is not set
+CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
index 2687a22..96b7a77 100644 (file)
@@ -1,50 +1,55 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:20:50 2005
+# Linux kernel version: 2.6.17-rc3
+# Mon May  8 20:15:57 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_VECTORS_BASE=0xffff0000
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -52,23 +57,42 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System Type
 #
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -78,14 +102,17 @@ CONFIG_KMOD=y
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
 CONFIG_ARCH_VERSATILE=y
+# CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
 
 #
 # Versatile platform type
 #
 CONFIG_ARCH_VERSATILE_PB=y
-# CONFIG_MACH_VERSATILE_AB is not set
+CONFIG_MACH_VERSATILE_AB=y
 
 #
 # Processor Type
@@ -106,12 +133,14 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_VIC=y
 CONFIG_ICST307=y
 
 #
 # Bus support
 #
 CONFIG_ARM_AMBA=y
+# CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -122,6 +151,18 @@ CONFIG_ARM_AMBA=y
 # Kernel Features
 #
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -145,7 +186,7 @@ CONFIG_CMDLINE="root=1f03 mem=32M"
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_NWFPE_XP is not set
 # CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
+CONFIG_VFP=y
 
 #
 # Userspace binary formats
@@ -159,9 +200,92 @@ CONFIG_BINFMT_ELF=y
 # Power management options
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
 # CONFIG_APM is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
 # Device Drivers
 #
 
@@ -174,6 +298,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -192,6 +321,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -214,6 +344,7 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
@@ -221,7 +352,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -229,7 +360,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_ARM_INTEGRATOR=y
-# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -237,7 +368,6 @@ CONFIG_MTD_ARM_INTEGRATOR=y
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -253,6 +383,11 @@ CONFIG_MTD_ARM_INTEGRATOR=y
 # CONFIG_MTD_NAND is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -264,7 +399,6 @@ CONFIG_MTD_ARM_INTEGRATOR=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -272,21 +406,13 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -297,6 +423,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -307,71 +434,8 @@ CONFIG_IOSCHED_CFQ=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
 #
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -379,11 +443,17 @@ CONFIG_NETDEVICES=y
 # CONFIG_TUN is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -410,6 +480,8 @@ CONFIG_SMC91X=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -459,7 +531,6 @@ CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -474,17 +545,16 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 # CONFIG_SERIAL_8250_DETECT_IRQ is not set
-CONFIG_SERIAL_8250_MULTIPORT=y
 CONFIG_SERIAL_8250_RSA=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AMBA_PL010 is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_CORE=y
@@ -503,20 +573,19 @@ CONFIG_LEGACY_PTY_COUNT=16
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -534,60 +603,60 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C Hardware Bus support
 #
-# CONFIG_I2C_ISA is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
 
 #
-# Hardware Sensors Chip support
-#
-CONFIG_I2C_SENSOR=m
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=m
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
 # Misc devices
 #
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -604,27 +673,31 @@ CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_FIRMWARE_EDID is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_ARMCLCD=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 # CONFIG_FONT_8x8 is not set
 # CONFIG_FONT_8x16 is not set
 # CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 CONFIG_FONT_ACORN_8x8=y
 # CONFIG_FONT_MINI_4x6 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
 # Logo configuration
@@ -647,12 +720,18 @@ CONFIG_SND_PCM=m
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
 #
 # Generic devices
 #
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
@@ -661,6 +740,7 @@ CONFIG_SND_PCM_OSS=m
 #
 # ALSA ARM devices
 #
+CONFIG_SND_ARMAACI=m
 
 #
 # Open Sound System
@@ -672,9 +752,14 @@ CONFIG_SND_PCM_OSS=m
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
 
 #
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -688,25 +773,31 @@ CONFIG_MMC_BLOCK=y
 CONFIG_MMC_ARMMMCI=m
 
 #
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 CONFIG_ROMFS_FS=y
+# CONFIG_INOTIFY is not set
 # 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
 
 #
 # CD-ROM/DVD Filesystems
@@ -729,11 +820,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -748,8 +838,8 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -766,16 +856,19 @@ CONFIG_CRAMFS=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_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_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -784,6 +877,7 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -803,6 +897,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -858,18 +953,24 @@ CONFIG_NLS_ISO8859_1=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_WAITQ is not set
 CONFIG_DEBUG_ERRORS=y
@@ -895,6 +996,7 @@ CONFIG_DEBUG_LL=y
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
index b324dca..45fdf4a 100644 (file)
@@ -95,5 +95,11 @@ int main(void)
   DEFINE(SYS_ERROR0,           0x9f0000);
   BLANK();
   DEFINE(SIZEOF_MACHINE_DESC,  sizeof(struct machine_desc));
+  DEFINE(MACHINFO_TYPE,                offsetof(struct machine_desc, nr));
+  DEFINE(MACHINFO_NAME,                offsetof(struct machine_desc, name));
+  DEFINE(MACHINFO_PHYSIO,      offsetof(struct machine_desc, phys_io));
+  DEFINE(MACHINFO_PGOFFIO,     offsetof(struct machine_desc, io_pg_offst));
+  DEFINE(PROCINFO_INITFUNC,    offsetof(struct proc_info_list, __cpu_flush));
+  DEFINE(PROCINFO_MMUFLAGS,    offsetof(struct proc_info_list, __cpu_mmu_flags));
   return 0; 
 }
index 0bea658..adf62e5 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/procinfo.h>
 #include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/system.h>
 
-#define PROCINFO_INITFUNC       12
-#define MACHINFO_TYPE          0
-
 /*
  * Kernel startup entry point.
  * ---------------------------
index 04b66a9..04f7344 100644 (file)
 #include <asm/thread_info.h>
 #include <asm/system.h>
 
-#define PROCINFO_MMUFLAGS      8
-#define PROCINFO_INITFUNC      12
-
-#define MACHINFO_TYPE          0
-#define MACHINFO_PHYSIO                4
-#define MACHINFO_PGOFFIO       8
-#define MACHINFO_NAME          12
-
 #define KERNEL_RAM_ADDR        (PAGE_OFFSET + TEXT_OFFSET)
 
 /*
index 1ff75ce..1a1539e 100644 (file)
@@ -264,8 +264,12 @@ void show_fpregs(struct user_fp *regs)
 /*
  * Task structure and kernel stack allocation.
  */
-static unsigned long *thread_info_head;
-static unsigned int nr_thread_info;
+struct thread_info_list {
+       unsigned long *head;
+       unsigned int nr;
+};
+
+static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 };
 
 #define EXTRA_TASK_STRUCT      4
 
@@ -274,12 +278,15 @@ struct thread_info *alloc_thread_info(struct task_struct *task)
        struct thread_info *thread = NULL;
 
        if (EXTRA_TASK_STRUCT) {
-               unsigned long *p = thread_info_head;
+               struct thread_info_list *th = &get_cpu_var(thread_info_list);
+               unsigned long *p = th->head;
 
                if (p) {
-                       thread_info_head = (unsigned long *)p[0];
-                       nr_thread_info -= 1;
+                       th->head = (unsigned long *)p[0];
+                       th->nr -= 1;
                }
+               put_cpu_var(thread_info_list);
+
                thread = (struct thread_info *)p;
        }
 
@@ -300,13 +307,19 @@ struct thread_info *alloc_thread_info(struct task_struct *task)
 
 void free_thread_info(struct thread_info *thread)
 {
-       if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) {
-               unsigned long *p = (unsigned long *)thread;
-               p[0] = (unsigned long)thread_info_head;
-               thread_info_head = p;
-               nr_thread_info += 1;
-       } else
-               free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
+       if (EXTRA_TASK_STRUCT) {
+               struct thread_info_list *th = &get_cpu_var(thread_info_list);
+               if (th->nr < EXTRA_TASK_STRUCT) {
+                       unsigned long *p = (unsigned long *)thread;
+                       p[0] = th->head;
+                       th->head = p;
+                       th->nr += 1;
+                       put_cpu_var(thread_info_list);
+                       return;
+               }
+               put_cpu_var(thread_info_list);
+       }
+       free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
 }
 
 /*
index dc5fa8e..83f57da 100644 (file)
@@ -79,7 +79,12 @@ static void __init aaed2000_init(void)
 }
 
 static struct map_desc aaed2000_io_desc[] __initdata = {
-  { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */
+       {
+               .virtual        = EXT_GPIO_VBASE,
+               .pfn            = __phys_to_pfn(EXT_GPIO_PBASE),
+               .length         = EXT_GPIO_LENGTH,
+               .type           = MT_DEVICE
+       },
 };
 
 static void __init aaed2000_map_io(void)
index dce4815..65be5ef 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/signal.h>
-#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 static struct map_desc standard_io_desc[] __initdata = {
        {
                .virtual        = VIO_APB_BASE,
-               .physical       = __phys_to_pfn(PIO_APB_BASE),
+               .pfn            = __phys_to_pfn(PIO_APB_BASE),
                .length         = IO_APB_LENGTH,
                .type           = MT_DEVICE
        }, {
                .virtual        = VIO_AHB_BASE,
-               .physical       = __phys_to_pfn(PIO_AHB_BASE),
+               .pfn            = __phys_to_pfn(PIO_AHB_BASE),
                .length         = IO_AHB_LENGTH,
                .type           = MT_DEVICE
        }
index b6029a9..59501b5 100644 (file)
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 
 struct sys_timer;
index 9d8331b..12ea58a 100644 (file)
@@ -195,56 +195,6 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
 }
 EXPORT_SYMBOL(imx_set_mmc_info);
 
-static struct resource imx_uart1_resources[] = {
-       [0] = {
-               .start  = 0x00206000,
-               .end    = 0x002060FF,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = (UART1_MINT_RX),
-               .end    = (UART1_MINT_RX),
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = (UART1_MINT_TX),
-               .end    = (UART1_MINT_TX),
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device imx_uart1_device = {
-       .name           = "imx-uart",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(imx_uart1_resources),
-       .resource       = imx_uart1_resources,
-};
-
-static struct resource imx_uart2_resources[] = {
-       [0] = {
-               .start  = 0x00207000,
-               .end    = 0x002070FF,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = (UART2_MINT_RX),
-               .end    = (UART2_MINT_RX),
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = (UART2_MINT_TX),
-               .end    = (UART2_MINT_TX),
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device imx_uart2_device = {
-       .name           = "imx-uart",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(imx_uart2_resources),
-       .resource       = imx_uart2_resources,
-};
-
 static struct imxfb_mach_info imx_fb_info;
 
 void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info)
@@ -283,8 +233,6 @@ static struct platform_device imxfb_device = {
 static struct platform_device *devices[] __initdata = {
        &imx_mmc_device,
        &imxfb_device,
-       &imx_uart1_device,
-       &imx_uart2_device,
 };
 
 static struct map_desc imx_io_desc[] __initdata = {
index e34d0df..da893c8 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <asm/mach/arch.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/imx-uart.h>
 #include <linux/interrupt.h>
 #include "generic.h"
 
@@ -48,8 +49,70 @@ static struct platform_device cs89x0_device = {
        .resource       = cs89x0_resources,
 };
 
+static struct imxuart_platform_data uart_pdata = {
+       .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct resource imx_uart1_resources[] = {
+       [0] = {
+               .start  = 0x00206000,
+               .end    = 0x002060FF,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = (UART1_MINT_RX),
+               .end    = (UART1_MINT_RX),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = (UART1_MINT_TX),
+               .end    = (UART1_MINT_TX),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device imx_uart1_device = {
+       .name           = "imx-uart",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(imx_uart1_resources),
+       .resource       = imx_uart1_resources,
+       .dev = {
+               .platform_data = &uart_pdata,
+       }
+};
+
+static struct resource imx_uart2_resources[] = {
+       [0] = {
+               .start  = 0x00207000,
+               .end    = 0x002070FF,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = (UART2_MINT_RX),
+               .end    = (UART2_MINT_RX),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = (UART2_MINT_TX),
+               .end    = (UART2_MINT_TX),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device imx_uart2_device = {
+       .name           = "imx-uart",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(imx_uart2_resources),
+       .resource       = imx_uart2_resources,
+       .dev = {
+               .platform_data = &uart_pdata,
+       }
+};
+
 static struct platform_device *devices[] __initdata = {
        &cs89x0_device,
+       &imx_uart1_device,
+       &imx_uart2_device,
 };
 
 #ifdef CONFIG_MMC_IMX
@@ -75,6 +138,17 @@ mx1ads_init(void)
        imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20);
        imx_set_mmc_info(&mx1ads_mmc_info);
 #endif
+
+       imx_gpio_mode(PC9_PF_UART1_CTS);
+       imx_gpio_mode(PC10_PF_UART1_RTS);
+       imx_gpio_mode(PC11_PF_UART1_TXD);
+       imx_gpio_mode(PC12_PF_UART1_RXD);
+
+       imx_gpio_mode(PB28_PF_UART2_CTS);
+       imx_gpio_mode(PB29_PF_UART2_RTS);
+       imx_gpio_mode(PB30_PF_UART2_TXD);
+       imx_gpio_mode(PB31_PF_UART2_RXD);
+
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
@@ -87,7 +161,7 @@ mx1ads_map_io(void)
 MACHINE_START(MX1ADS, "Motorola MX1ADS")
        /* Maintainer: Sascha Hauer, Pengutronix */
        .phys_io        = 0x00200000,
-       .io_pg_offst    = ((0xe0200000) >> 18) & 0xfffc,
+       .io_pg_offst    = ((0xe0000000) >> 18) & 0xfffc,
        .boot_params    = 0x08000100,
        .map_io         = mx1ads_map_io,
        .init_irq       = imx_init_irq,
index 5bf50a2..2a39f9e 100644 (file)
@@ -11,6 +11,7 @@ comment "IXP4xx Platforms"
 config MACH_NSLU2
        bool
        prompt "Linksys NSLU2"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support Linksys's
          NSLU2 NAS device. For more information on this platform,
@@ -18,6 +19,7 @@ config MACH_NSLU2
 
 config ARCH_AVILA
        bool "Avila"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support the Gateworks
          Avila Network Platform. For more information on this platform,
@@ -25,6 +27,7 @@ config ARCH_AVILA
 
 config ARCH_ADI_COYOTE
        bool "Coyote"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support the ADI 
          Engineering Coyote Gateway Reference Platform. For more
@@ -32,6 +35,7 @@ config ARCH_ADI_COYOTE
 
 config ARCH_IXDP425
        bool "IXDP425"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support Intel's 
          IXDP425 Development Platform (Also known as Richfield).  
@@ -39,6 +43,7 @@ config ARCH_IXDP425
 
 config MACH_IXDPG425
        bool "IXDPG425"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support Intel's
          IXDPG425 Development Platform (Also known as Montajade).
@@ -46,6 +51,7 @@ config MACH_IXDPG425
 
 config MACH_IXDP465
        bool "IXDP465"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support Intel's
          IXDP465 Development Platform (Also known as BMP).
@@ -72,6 +78,7 @@ config ARCH_PRPMC1100
 config MACH_NAS100D
        bool
        prompt "NAS100D"
+       select PCI
        help
          Say 'Y' here if you want your kernel to support Iomega's
          NAS 100d device. For more information on this platform,
@@ -96,6 +103,7 @@ config CPU_IXP46X
 config MACH_GTWX5715
        bool "Gemtek WX5715 (Linksys WRV54G)"
        depends on ARCH_IXP4XX
+       select PCI
        help
                This board is currently inside the Linksys WRV54G Gateways.
 
@@ -110,11 +118,16 @@ config MACH_GTWX5715
                "High Speed" UART is n/c (as far as I can tell)
                20 Pin ARM/Xscale JTAG interface on J2
 
-
 comment "IXP4xx Options"
 
+config DMABOUNCE
+       bool
+       default y
+       depends on PCI
+
 config IXP4XX_INDIRECT_PCI
        bool "Use indirect PCI memory access"
+       depends on PCI
        help
           IXP4xx provides two methods of accessing PCI memory space:
 
index 0471044..5a4aaa0 100644 (file)
@@ -2,8 +2,9 @@
 # Makefile for the linux kernel.
 #
 
-obj-y  += common.o common-pci.o 
+obj-y  += common.o
 
+obj-$(CONFIG_PCI)              += common-pci.o
 obj-$(CONFIG_ARCH_IXDP4XX)     += ixdp425-pci.o ixdp425-setup.o
 obj-$(CONFIG_MACH_IXDPG425)    += ixdpg425-pci.o coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)  += coyote-pci.o coyote-setup.o
index 458112b..7d8c854 100644 (file)
@@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
 
        local_irq_save(flags);
 
-       /* try grabbing a DMA channel with the requested priority */
-       for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) {
-               if (!dma_channels[i].name) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (!found) {
-               /* requested prio group is full, try hier priorities */
-               for (i = prio-1; i >= 0; i--) {
+       do {
+               /* try grabbing a DMA channel with the requested priority */
+               pxa_for_each_dma_prio (i, prio) {
                        if (!dma_channels[i].name) {
                                found = 1;
                                break;
                        }
                }
-       }
+               /* if requested prio group is full, try a hier priority */
+       } while (!found && prio--);
 
        if (found) {
                DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
index c131a52..b3a5602 100644 (file)
@@ -199,10 +199,26 @@ static void sa1100_unmask_irq(unsigned int irq)
        ICMR |= (1 << irq);
 }
 
+/*
+ * Apart form GPIOs, only the RTC alarm can be a wakeup event.
+ */
+static int sa1100_set_wake(unsigned int irq, unsigned int on)
+{
+       if (irq == IRQ_RTCAlrm) {
+               if (on)
+                       PWER |= PWER_RTC;
+               else
+                       PWER &= ~PWER_RTC;
+               return 0;
+       }
+       return -EINVAL;
+}
+
 static struct irqchip sa1100_normal_chip = {
        .ack            = sa1100_mask_irq,
        .mask           = sa1100_mask_irq,
        .unmask         = sa1100_unmask_irq,
+       .set_wake       = sa1100_set_wake,
 };
 
 static struct resource irq_resource = {
index 8ab5300..6d7de9c 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Mon Feb 20 10:18:02 2006
+# Last update: Mon May 8 20:11:05 2006
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -566,8 +566,8 @@ switchgrass         MACH_SWITCHGRASS        SWITCHGRASS             549
 ens_cmu                        MACH_ENS_CMU            ENS_CMU                 550
 mm6_sdb                        MACH_MM6_SDB            MM6_SDB                 551
 saturn                 MACH_SATURN             SATURN                  552
-argonplusevb           MACH_ARGONPLUSEVB       ARGONPLUSEVB            553
-scma11evb              MACH_SCMA11EVB          SCMA11EVB               554
+i30030evb              MACH_ARGONPLUSEVB       ARGONPLUSEVB            553
+mxc27530evb            MACH_SCMA11EVB          SCMA11EVB               554
 smdk2800               MACH_SMDK2800           SMDK2800                555
 mtwilson               MACH_MTWILSON           MTWILSON                556
 ziti                   MACH_ZITI               ZITI                    557
@@ -647,7 +647,7 @@ sendt                       MACH_SENDT              SENDT                   630
 mx2jazz                        MACH_MX2JAZZ            MX2JAZZ                 631
 multiio                        MACH_MULTIIO            MULTIIO                 632
 hrdisplay              MACH_HRDISPLAY          HRDISPLAY               633
-scma11bb               MACH_SCMA11BB           SCMA11BB                634
+mxc27530ads            MACH_SCMA11BB           SCMA11BB                634
 trizeps3               MACH_TRIZEPS3           TRIZEPS3                635
 zefeerdza              MACH_ZEFEERDZA          ZEFEERDZA               636
 zefeerdzb              MACH_ZEFEERDZB          ZEFEERDZB               637
@@ -721,7 +721,7 @@ gp32                        MACH_GP32               GP32                    706
 gem                    MACH_GEM                GEM                     707
 i858                   MACH_I858               I858                    708
 hx2750                 MACH_HX2750             HX2750                  709
-zeusevb                        MACH_ZEUSEVB            ZEUSEVB                 710
+mxc91131evb            MACH_ZEUSEVB            ZEUSEVB                 710
 p700                   MACH_P700               P700                    711
 cpe                    MACH_CPE                CPE                     712
 spitz                  MACH_SPITZ              SPITZ                   713
@@ -802,7 +802,7 @@ cpuat91                     MACH_CPUAT91            CPUAT91                 787
 rea9200                        MACH_REA9200            REA9200                 788
 acts_pune_sa1110       MACH_ACTS_PUNE_SA1110   ACTS_PUNE_SA1110        789
 ixp425                 MACH_IXP425             IXP425                  790
-argonplusodyssey       MACH_ARGONPLUSODYSSEY   ARGONPLUSODYSSEY        791
+i30030ads              MACH_ARGONPLUSODYSSEY   ARGONPLUSODYSSEY        791
 perch                  MACH_PERCH              PERCH                   792
 eis05r1                        MACH_EIS05R1            EIS05R1                 793
 pepperpad              MACH_PEPPERPAD          PEPPERPAD               794
@@ -827,7 +827,7 @@ micro9l                     MACH_MICRO9L            MICRO9L                 812
 uc5471dsp              MACH_UC5471DSP          UC5471DSP               813
 sj5471eng              MACH_SJ5471ENG          SJ5471ENG               814
 none                   MACH_CMPXA26X           CMPXA26X                815
-nc                     MACH_NC                 NC                      816
+nc1                    MACH_NC                 NC                      816
 omap_palmte            MACH_OMAP_PALMTE        OMAP_PALMTE             817
 ajax52x                        MACH_AJAX52X            AJAX52X                 818
 siriustar              MACH_SIRIUSTAR          SIRIUSTAR               819
@@ -930,7 +930,7 @@ netclient           MACH_NETCLIENT          NETCLIENT               916
 xscale_palmtt5         MACH_XSCALE_PALMTT5     XSCALE_PALMTT5          917
 xscale_palmtc          MACH_OMAP_PALMTC        OMAP_PALMTC             918
 omap_apollon           MACH_OMAP_APOLLON       OMAP_APOLLON            919
-argonlvevb             MACH_ARGONLVEVB         ARGONLVEVB              920
+mxc30030evb            MACH_ARGONLVEVB         ARGONLVEVB              920
 rea_2d                 MACH_REA_2D             REA_2D                  921
 eti3e524               MACH_TI3E524            TI3E524                 922
 ateb9200               MACH_ATEB9200           ATEB9200                923
@@ -965,7 +965,78 @@ sisteron           MACH_SISTERON           SISTERON                951
 rx1950                 MACH_RX1950             RX1950                  952
 tsc_venus              MACH_TSC_VENUS          TSC_VENUS               953
 ds101j                 MACH_DS101J             DS101J                  954
-mxc300_30ads           MACH_MXC30030ADS        MXC30030ADS             955
+mxc30030ads            MACH_MXC30030ADS        MXC30030ADS             955
 fujitsu_wimaxsoc       MACH_FUJITSU_WIMAXSOC   FUJITSU_WIMAXSOC        956
 dualpcmodem            MACH_DUALPCMODEM        DUALPCMODEM             957
 gesbc9312              MACH_GESBC9312          GESBC9312               958
+htcapache              MACH_HTCAPACHE          HTCAPACHE               959
+ixdp435                        MACH_IXDP435            IXDP435                 960
+catprovt100            MACH_CATPROVT100        CATPROVT100             961
+picotux1xx             MACH_PICOTUX1XX         PICOTUX1XX              962
+picotux2xx             MACH_PICOTUX2XX         PICOTUX2XX              963
+dsmg600                        MACH_DSMG600            DSMG600                 964
+empc2                  MACH_EMPC2              EMPC2                   965
+ventura                        MACH_VENTURA            VENTURA                 966
+phidget_sbc            MACH_PHIDGET_SBC        PHIDGET_SBC             967
+ij3k                   MACH_IJ3K               IJ3K                    968
+pisgah                 MACH_PISGAH             PISGAH                  969
+omap_fsample           MACH_OMAP_FSAMPLE       OMAP_FSAMPLE            970
+sg720                  MACH_SG720              SG720                   971
+redfox                 MACH_REDFOX             REDFOX                  972
+mysh_ep9315_1          MACH_MYSH_EP9315_1      MYSH_EP9315_1           973
+tpf106                 MACH_TPF106             TPF106                  974
+at91rm9200kg           MACH_AT91RM9200KG       AT91RM9200KG            975
+racemt2                        MACH_SLEDB              SLEDB                   976
+ontrack                        MACH_ONTRACK            ONTRACK                 977
+pm1200                 MACH_PM1200             PM1200                  978
+ess24562               MACH_ESS24XXX           ESS24XXX                979
+coremp7                        MACH_COREMP7            COREMP7                 980
+nexcoder_6446          MACH_NEXCODER_6446      NEXCODER_6446           981
+stvc8380               MACH_STVC8380           STVC8380                982
+teklynx                        MACH_TEKLYNX            TEKLYNX                 983
+carbonado              MACH_CARBONADO          CARBONADO               984
+sysmos_mp730           MACH_SYSMOS_MP730       SYSMOS_MP730            985
+snapper_cl15           MACH_SNAPPER_CL15       SNAPPER_CL15            986
+pgigim                 MACH_PGIGIM             PGIGIM                  987
+ptx9160p2              MACH_PTX9160P2          PTX9160P2               988
+dcore1                 MACH_DCORE1             DCORE1                  989
+victorpxa              MACH_VICTORPXA          VICTORPXA               990
+mx2dtb                 MACH_MX2DTB             MX2DTB                  991
+pxa_irex_er0100                MACH_PXA_IREX_ER0100    PXA_IREX_ER0100         992
+omap_palmz71           MACH_OMAP_PALMZ71       OMAP_PALMZ71            993
+bartec_deg             MACH_BARTEC_DEG         BARTEC_DEG              994
+hw50251                        MACH_HW50251            HW50251                 995
+ibox                   MACH_IBOX               IBOX                    996
+atlaslh7a404           MACH_ATLASLH7A404       ATLASLH7A404            997
+pt2026                 MACH_PT2026             PT2026                  998
+htcalpine              MACH_HTCALPINE          HTCALPINE               999
+bartec_vtu             MACH_BARTEC_VTU         BARTEC_VTU              1000
+vcoreii                        MACH_VCOREII            VCOREII                 1001
+pdnb3                  MACH_PDNB3              PDNB3                   1002
+htcbeetles             MACH_HTCBEETLES         HTCBEETLES              1003
+s3c6400                        MACH_S3C6400            S3C6400                 1004
+s3c2443                        MACH_S3C2443            S3C2443                 1005
+omap_ldk               MACH_OMAP_LDK           OMAP_LDK                1006
+smdk2460               MACH_SMDK2460           SMDK2460                1007
+smdk2440               MACH_SMDK2440           SMDK2440                1008
+smdk2412               MACH_SMDK2412           SMDK2412                1009
+webbox                 MACH_WEBBOX             WEBBOX                  1010
+cwwndp                 MACH_CWWNDP             CWWNDP                  1011
+dragon                 MACH_DRAGON             DRAGON                  1012
+opendo_cpu_board       MACH_OPENDO_CPU_BOARD   OPENDO_CPU_BOARD        1013
+ccm2200                        MACH_CCM2200            CCM2200                 1014
+etwarm                 MACH_ETWARM             ETWARM                  1015
+m93030                 MACH_M93030             M93030                  1016
+cc7u                   MACH_CC7U               CC7U                    1017
+mtt_ranger             MACH_MTT_RANGER         MTT_RANGER              1018
+nexus                  MACH_NEXUS              NEXUS                   1019
+desman                 MACH_DESMAN             DESMAN                  1020
+bkde303                        MACH_BKDE303            BKDE303                 1021
+smdk2413               MACH_SMDK2413           SMDK2413                1022
+aml_m7200              MACH_AML_M7200          AML_M7200               1023
+aml_m5900              MACH_AML_M5900          AML_M5900               1024
+sg640                  MACH_SG640              SG640                   1025
+edg79524               MACH_EDG79524           EDG79524                1026
+ai2410                 MACH_AI2410             AI2410                  1027
+ixp465                 MACH_IXP465             IXP465                  1028
+balloon3               MACH_BALLOON3           BALLOON3                1029
index 37ff814..03486be 100644 (file)
@@ -245,7 +245,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
         */
        barrier();
        trigger = fmrx(FPINST2);
-       fpscr = fmrx(FPSCR);
+       orig_fpscr = fpscr = fmrx(FPSCR);
 
  emulate:
        exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
index c6fe99e..8dfa305 100644 (file)
@@ -758,10 +758,10 @@ config HOTPLUG_CPU
        bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
        depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
        ---help---
-         Say Y here to experiment with turning CPUs off and on.  CPUs
-         can be controlled through /sys/devices/system/cpu.
+         Say Y here to experiment with turning CPUs off and on, and to
+         enable suspend on SMP systems. CPUs can be controlled through
+         /sys/devices/system/cpu.
 
-         Say N.
 
 endmenu
 
index 4c785a6..40e5aba 100644 (file)
@@ -1102,9 +1102,6 @@ int __init acpi_boot_table_init(void)
        dmi_check_system(acpi_dmi_table);
 #endif
 
-       if (!cpu_has_apic)
-               return -ENODEV;
-
        /*
         * If acpi_disabled, bail out
         * One exception: acpi=ht continues far enough to enumerate LAPICs
@@ -1151,9 +1148,6 @@ int __init acpi_boot_init(void)
 
        acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
 
-       if (!cpu_has_apic)
-               return -ENODEV;
-
        /*
         * set sci_int and PM timer address
         */
index f8f132a..d70f2ad 100644 (file)
@@ -2238,6 +2238,8 @@ static inline void unlock_ExtINT_logic(void)
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
+int timer_uses_ioapic_pin_0;
+
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -2274,6 +2276,9 @@ static inline void check_timer(void)
        pin2  = ioapic_i8259.pin;
        apic2 = ioapic_i8259.apic;
 
+       if (pin1 == 0)
+               timer_uses_ioapic_pin_0 = 1;
+
        printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
                vector, apic1, pin1, apic2, pin2);
 
index 34d21e2..6b1392d 100644 (file)
@@ -1130,7 +1130,17 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity)
                 */
                int irq = gsi;
                if (gsi < MAX_GSI_NUM) {
-                       if (gsi > 15)
+                       /*
+                        * Retain the VIA chipset work-around (gsi > 15), but
+                        * avoid a problem where the 8254 timer (IRQ0) is setup
+                        * via an override (so it's not on pin 0 of the ioapic),
+                        * and at the same time, the pin 0 interrupt is a PCI
+                        * type.  The gsi > 15 test could cause these two pins
+                        * to be shared as IRQ0, and they are not shareable.
+                        * So test for this condition, and if necessary, avoid
+                        * the pin collision.
+                        */
+                       if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
                                gsi = pci_irq++;
                        /*
                         * Don't assign IRQ used by ACPI SCI
index d77e89a..846e163 100644 (file)
@@ -1320,6 +1320,8 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
        probe_roms();
        for (i = 0; i < e820.nr_map; i++) {
                struct resource *res;
+               if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
+                       continue;
                res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
                switch (e820.map[i].type) {
                case E820_RAM:  res->name = "System RAM"; break;
index 1a2076c..ec0fd3c 100644 (file)
@@ -332,10 +332,11 @@ static int __init ppro_init(char ** cpu_type)
 {
        __u8 cpu_model = boot_cpu_data.x86_model;
 
-       if (cpu_model > 0xd)
+       if (cpu_model == 14)
+               *cpu_type = "i386/core";
+       else if (cpu_model > 0xd)
                return 0;
-
-       if (cpu_model == 9) {
+       else if (cpu_model == 9) {
                *cpu_type = "i386/p6_mobile";
        } else if (cpu_model > 5) {
                *cpu_type = "i386/piii";
index 46c9331..9e534d5 100644 (file)
@@ -6,7 +6,9 @@
  *     in1:    source address
  *     in2:    number of bytes to copy
  * Output:
- *     0 if success, or number of byte NOT copied if error occurred.
+ *     for memcpy:    return dest
+ *     for copy_user: return 0 if success,
+ *                    or number of byte NOT copied if error occurred.
  *
  * Copyright (C) 2002 Intel Corp.
  * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
@@ -73,6 +75,7 @@ GLOBAL_ENTRY(memcpy)
        and     r28=0x7,in0
        and     r29=0x7,in1
        mov     f6=f0
+       mov     retval=in0
        br.cond.sptk .common_code
        ;;
 END(memcpy)
@@ -84,7 +87,7 @@ GLOBAL_ENTRY(__copy_user)
        mov     f6=f1
        mov     saved_in0=in0   // save dest pointer
        mov     saved_in1=in1   // save src pointer
-       mov     saved_in2=in2   // save len
+       mov     retval=r0       // initialize return value
        ;;
 .common_code:
        cmp.gt  p15,p0=8,in2    // check for small size
@@ -92,7 +95,7 @@ GLOBAL_ENTRY(__copy_user)
        cmp.ne  p14,p0=0,r29    // check src alignment
        add     src0=0,in1
        sub     r30=8,r28       // for .align_dest
-       mov     retval=r0       // initialize return value
+       mov     saved_in2=in2   // save len
        ;;
        add     dst0=0,in0
        add     dst1=1,in0      // dest odd index
index 856ef1a..f788663 100644 (file)
@@ -90,15 +90,15 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = *p->ainsn.insn;
-
        regs->msr |= MSR_SE;
 
-       /* single step inline if it is a trap variant */
-       if (is_trap(insn))
-               regs->nip = (unsigned long)p->addr;
-       else
-               regs->nip = (unsigned long)p->ainsn.insn;
+       /*
+        * On powerpc we should single step on the original
+        * instruction even if the probed insn is a trap
+        * variant as values in regs could play a part in
+        * if the trap is taken or not
+        */
+       regs->nip = (unsigned long)p->ainsn.insn;
 }
 
 static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
index 1cb69e8..9a07f97 100644 (file)
@@ -885,6 +885,74 @@ void __init unflatten_device_tree(void)
        DBG(" <- unflatten_device_tree()\n");
 }
 
+/*
+ * ibm,pa-features is a per-cpu property that contains a string of
+ * attribute descriptors, each of which has a 2 byte header plus up
+ * to 254 bytes worth of processor attribute bits.  First header
+ * byte specifies the number of bytes following the header.
+ * Second header byte is an "attribute-specifier" type, of which
+ * zero is the only currently-defined value.
+ * Implementation:  Pass in the byte and bit offset for the feature
+ * that we are interested in.  The function will return -1 if the
+ * pa-features property is missing, or a 1/0 to indicate if the feature
+ * is supported/not supported.  Note that the bit numbers are
+ * big-endian to match the definition in PAPR.
+ */
+static struct ibm_pa_feature {
+       unsigned long   cpu_features;   /* CPU_FTR_xxx bit */
+       unsigned int    cpu_user_ftrs;  /* PPC_FEATURE_xxx bit */
+       unsigned char   pabyte;         /* byte number in ibm,pa-features */
+       unsigned char   pabit;          /* bit number (big-endian) */
+       unsigned char   invert;         /* if 1, pa bit set => clear feature */
+} ibm_pa_features[] __initdata = {
+       {0, PPC_FEATURE_HAS_MMU,        0, 0, 0},
+       {0, PPC_FEATURE_HAS_FPU,        0, 1, 0},
+       {CPU_FTR_SLB, 0,                0, 2, 0},
+       {CPU_FTR_CTRL, 0,               0, 3, 0},
+       {CPU_FTR_NOEXECUTE, 0,          0, 6, 0},
+       {CPU_FTR_NODSISRALIGN, 0,       1, 1, 1},
+       {CPU_FTR_CI_LARGE_PAGE, 0,      1, 2, 0},
+};
+
+static void __init check_cpu_pa_features(unsigned long node)
+{
+       unsigned char *pa_ftrs;
+       unsigned long len, tablelen, i, bit;
+
+       pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
+       if (pa_ftrs == NULL)
+               return;
+
+       /* find descriptor with type == 0 */
+       for (;;) {
+               if (tablelen < 3)
+                       return;
+               len = 2 + pa_ftrs[0];
+               if (tablelen < len)
+                       return;         /* descriptor 0 not found */
+               if (pa_ftrs[1] == 0)
+                       break;
+               tablelen -= len;
+               pa_ftrs += len;
+       }
+
+       /* loop over bits we know about */
+       for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) {
+               struct ibm_pa_feature *fp = &ibm_pa_features[i];
+
+               if (fp->pabyte >= pa_ftrs[0])
+                       continue;
+               bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
+               if (bit ^ fp->invert) {
+                       cur_cpu_spec->cpu_features |= fp->cpu_features;
+                       cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
+               } else {
+                       cur_cpu_spec->cpu_features &= ~fp->cpu_features;
+                       cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
+               }
+       }
+}
+
 static int __init early_init_dt_scan_cpus(unsigned long node,
                                          const char *uname, int depth,
                                          void *data)
@@ -969,6 +1037,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
        }
 #endif /* CONFIG_ALTIVEC */
 
+       check_cpu_pa_features(node);
+
 #ifdef CONFIG_PPC_PSERIES
        if (nthreads > 1)
                cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
index a1bda6f..40020c6 100644 (file)
@@ -118,7 +118,15 @@ int eeh_send_failure_event (struct device_node *dn,
 {
        unsigned long flags;
        struct eeh_event *event;
+       char *location;
 
+       if (!mem_init_done) {
+               printk(KERN_ERR "EEH: event during early boot not handled\n");
+               location = (char *) get_property(dn, "ibm,loc-code", NULL);
+               printk(KERN_ERR "EEH: device node = %s\n", dn->full_name);
+               printk(KERN_ERR "EEH: PCI location = %s\n", location);
+               return 1;
+       }
        event = kmalloc(sizeof(*event), GFP_ATOMIC);
        if (event == NULL) {
                printk (KERN_ERR "EEH: out of memory, event not handled\n");
index ec53c7d..7a2f205 100644 (file)
@@ -355,9 +355,7 @@ InstructionTLBMiss:
 
        . = 0x1200
 DataStoreTLBMiss:
-#ifdef CONFIG_8xx_CPU6
        stw     r3, 8(r0)
-#endif
        DO_8xx_CPU6(0x3f80, r3)
        mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
        mfcr    r10
@@ -417,9 +415,7 @@ DataStoreTLBMiss:
        lwz     r11, 0(r0)
        mtcr    r11
        lwz     r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
-#endif
        rfi
 
 /* This is an instruction TLB error on the MPC8xx.  This could be due
index 6ce3b84..d919dab 100644 (file)
@@ -378,7 +378,7 @@ int __init mpc866ads_init(void)
        ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
 #endif
 
-#ifdef CONFIG_SERIAL_CPM_SMCer
+#ifdef CONFIG_SERIAL_CPM_SMC
        ppc_sys_device_enable(MPC8xx_CPM_SMC2);
        ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
 #endif
index ef5b9c4..4d53b27 100644 (file)
@@ -1650,3 +1650,11 @@ sys_tee_wrapper:
        llgfr   %r4,%r4                 # size_t
        llgfr   %r5,%r5                 # unsigned int
        jg      sys_tee
+
+       .globl compat_sys_vmsplice_wrapper
+compat_sys_vmsplice_wrapper:
+       lgfr    %r2,%r2                 # int
+       llgtr   %r3,%r3                 # compat_iovec *
+       llgfr   %r4,%r4                 # unsigned int
+       llgfr   %r5,%r5                 # unsigned int
+       jg      compat_sys_vmsplice
index fc2c076..93be1d5 100644 (file)
@@ -317,3 +317,4 @@ SYSCALL(sys_get_robust_list,sys_get_robust_list,compat_sys_get_robust_list_wrapp
 SYSCALL(sys_splice,sys_splice,sys_splice_wrapper)
 SYSCALL(sys_sync_file_range,sys_sync_file_range,sys_sync_file_range_wrapper)
 SYSCALL(sys_tee,sys_tee,sys_tee_wrapper)
+SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper)
index fea043b..029f099 100644 (file)
@@ -249,18 +249,19 @@ static inline void stop_hz_timer(void)
        unsigned long flags;
        unsigned long seq, next;
        __u64 timer, todval;
+       int cpu = smp_processor_id();
 
        if (sysctl_hz_timer != 0)
                return;
 
-       cpu_set(smp_processor_id(), nohz_cpu_mask);
+       cpu_set(cpu, nohz_cpu_mask);
 
        /*
         * Leave the clock comparator set up for the next timer
         * tick if either rcu or a softirq is pending.
         */
-       if (rcu_pending(smp_processor_id()) || local_softirq_pending()) {
-               cpu_clear(smp_processor_id(), nohz_cpu_mask);
+       if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
+               cpu_clear(cpu, nohz_cpu_mask);
                return;
        }
 
index 460f72e..f9ff297 100644 (file)
@@ -274,6 +274,11 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
        if (mmu_map_dma_area(dma_addrp, va, res->start, len_total) != 0)
                goto err_noiommu;
 
+       /* Set the resource name, if known. */
+       if (sdev) {
+               res->name = sdev->prom_name;
+       }
+
        return (void *)res->start;
 
 err_noiommu:
index 787d5f1..598682f 100644 (file)
@@ -113,6 +113,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
 
                switch (ELF32_R_TYPE(rel[i].r_info)) {
                case R_SPARC_32:
+               case R_SPARC_UA32:
                        location[0] = v >> 24;
                        location[1] = v >> 16;
                        location[2] = v >>  8;
index ec1c968..4b376fa 100644 (file)
@@ -251,19 +251,9 @@ EXPORT_SYMBOL(__prom_getchild);
 EXPORT_SYMBOL(__prom_getsibling);
 
 /* sparc library symbols */
-EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memscan);
 EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strcpy);
-EXPORT_SYMBOL(strncpy);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strcmp);
 EXPORT_SYMBOL(strncmp);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(page_kernel);
 
 /* Special internal versions of library functions. */
@@ -317,6 +307,3 @@ EXPORT_SYMBOL(do_BUG);
 
 /* Sun Power Management Idle Handler */
 EXPORT_SYMBOL(pm_idle);
-
-/* Binfmt_misc needs this */
-EXPORT_SYMBOL(sys_close);
index db8faa7..6e1135c 100644 (file)
@@ -23,7 +23,7 @@ sys_call_table:
 /*10*/  .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
 /*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
 /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
-/*25*/ .long sys_time, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
+/*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
 /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
 /*35*/ .long sys_chown, sys_sync, sys_kill, sys_newstat, sys_sendfile
 /*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_getuid
index 1317380..f09a70b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16
-# Sun Apr  2 19:31:04 2006
+# Linux kernel version: 2.6.17-rc3
+# Fri May 12 12:43:49 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -114,6 +114,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HUGETLB_PAGE_SIZE_4MB=y
 # CONFIG_HUGETLB_PAGE_SIZE_512K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64K is not set
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_LARGE_ALLOCS=y
@@ -430,7 +431,6 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLOGICPTI is not set
 # CONFIG_SCSI_QLA_FC is not set
@@ -1042,9 +1042,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
@@ -1115,6 +1113,14 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_NEW_LEDS is not set
 
 #
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
@@ -1303,6 +1309,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
index 6c83e37..5798715 100644 (file)
@@ -143,6 +143,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
                        location[3] = v >>  0;
                        break;
 
+               case R_SPARC_DISP32:
+                       v -= (Elf64_Addr) location;
+                       *loc32 = v;
+                       break;
+
                case R_SPARC_WDISP30:
                        v -= (Elf64_Addr) location;
                        *loc32 = (*loc32 & ~0x3fffffff) |
index f9b7576..bdf1f4d 100644 (file)
@@ -139,6 +139,7 @@ SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
 SIGN2(sys32_splice, sys_splice, %o0, %o1)
 SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
 SIGN2(sys32_tee, sys_tee, %o0, %o1)
+SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0)
 
        .globl          sys32_mmap2
 sys32_mmap2:
index 62672cd..d4b39cd 100644 (file)
@@ -25,7 +25,7 @@ sys_call_table32:
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek
 /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
-/*25*/ .word compat_sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
+/*25*/ .word sys32_vmsplice, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
 /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
        .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile
 /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid
@@ -94,7 +94,7 @@ sys_call_table:
 /*10*/  .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
 /*15*/ .word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek
 /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
-/*25*/ .word sys_nis_syscall, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
+/*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
 /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
        .word sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile64
 /*40*/ .word sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall
index 3c7626c..528cf62 100644 (file)
@@ -209,4 +209,4 @@ int __init timer_init(void)
        return(0);
 }
 
-__initcall(timer_init);
+arch_initcall(timer_init);
index 62776c0..222b5b4 100644 (file)
@@ -76,6 +76,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
                *addrp = __pa_symbol(&_end);
                return 1;
        }
+
+       if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
+               *addrp = ebda_addr + ebda_size;
+               return 1;
+       }
+
        /* XXX ramdisk image here? */ 
        return 0;
 } 
index 77b4c60..0de3ea9 100644 (file)
@@ -1777,6 +1777,8 @@ static inline void unlock_ExtINT_logic(void)
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
+int timer_uses_ioapic_pin_0;
+
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -1814,6 +1816,9 @@ static inline void check_timer(void)
        pin2  = ioapic_i8259.pin;
        apic2 = ioapic_i8259.apic;
 
+       if (pin1 == 0)
+               timer_uses_ioapic_pin_0 = 1;
+
        apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
                vector, apic1, pin1, apic2, pin2);
 
index b17cf3e..083da7e 100644 (file)
@@ -968,7 +968,17 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
                 */
                int irq = gsi;
                if (gsi < MAX_GSI_NUM) {
-                       if (gsi > 15)
+                       /*
+                        * Retain the VIA chipset work-around (gsi > 15), but
+                        * avoid a problem where the 8254 timer (IRQ0) is setup
+                        * via an override (so it's not on pin 0 of the ioapic),
+                        * and at the same time, the pin 0 interrupt is a PCI
+                        * type.  The gsi > 15 test could cause these two pins
+                        * to be shared as IRQ0, and they are not shareable.
+                        * So test for this condition, and if necessary, avoid
+                        * the pin collision.
+                        */
+                       if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
                                gsi = pci_irq++;
                        /*
                         * Don't assign IRQ used by ACPI SCI
index 9d3d76c..2480d3f 100644 (file)
@@ -639,6 +639,14 @@ static int __init pci_iommu_init(void)
                return -1;
        }
 
+       i = 0;
+       for_all_nb(dev)
+               i++;
+       if (i > MAX_NB) {
+               printk(KERN_ERR "PCI-GART: Too many northbridges (%ld). Disabled\n", i);
+               return -1;
+       }
+
        printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
        aper_size = info.aper_size * 1024 * 1024;       
        iommu_size = check_iommu_size(info.aper_base, aper_size); 
index ebc3c33..f0870be 100644 (file)
@@ -571,17 +571,28 @@ static inline void copy_edd(void)
 #endif
 
 #define EBDA_ADDR_POINTER 0x40E
-static void __init reserve_ebda_region(void)
+
+unsigned __initdata ebda_addr;
+unsigned __initdata ebda_size;
+
+static void discover_ebda(void)
 {
-       unsigned int addr;
-       /** 
+       /*
         * there is a real-mode segmented pointer pointing to the 
         * 4K EBDA area at 0x40E
         */
-       addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER);
-       addr <<= 4;
-       if (addr)
-               reserve_bootmem_generic(addr, PAGE_SIZE);
+       ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER;
+       ebda_addr <<= 4;
+
+       ebda_size = *(unsigned short *)(unsigned long)ebda_addr;
+
+       /* Round EBDA up to pages */
+       if (ebda_size == 0)
+               ebda_size = 1;
+       ebda_size <<= 10;
+       ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
+       if (ebda_size > 64*1024)
+               ebda_size = 64*1024;
 }
 
 void __init setup_arch(char **cmdline_p)
@@ -627,6 +638,8 @@ void __init setup_arch(char **cmdline_p)
 
        check_efer();
 
+       discover_ebda();
+
        init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
 
        dmi_scan_machine();
@@ -669,7 +682,8 @@ void __init setup_arch(char **cmdline_p)
        reserve_bootmem_generic(0, PAGE_SIZE);
 
        /* reserve ebda region */
-       reserve_ebda_region();
+       if (ebda_addr)
+               reserve_bootmem_generic(ebda_addr, ebda_size);
 
 #ifdef CONFIG_SMP
        /*
index 2700b13..6b87268 100644 (file)
@@ -385,6 +385,7 @@ void out_of_line_bug(void)
 
 static DEFINE_SPINLOCK(die_lock);
 static int die_owner = -1;
+static unsigned int die_nest_count;
 
 unsigned __kprobes long oops_begin(void)
 {
@@ -399,6 +400,7 @@ unsigned __kprobes long oops_begin(void)
                else
                        spin_lock(&die_lock);
        }
+       die_nest_count++;
        die_owner = cpu;
        console_verbose();
        bust_spinlocks(1);
@@ -409,7 +411,13 @@ void __kprobes oops_end(unsigned long flags)
 { 
        die_owner = -1;
        bust_spinlocks(0);
-       spin_unlock_irqrestore(&die_lock, flags);
+       die_nest_count--;
+       if (die_nest_count)
+               /* We still own the lock */
+               local_irq_restore(flags);
+       else
+               /* Nest count reaches zero, release the lock. */
+               spin_unlock_irqrestore(&die_lock, flags);
        if (panic_on_oops)
                panic("Oops");
 }
@@ -464,6 +472,8 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs)
                panic("nmi watchdog");
        printk("console shuts up ...\n");
        oops_end(flags);
+       nmi_exit();
+       local_irq_enable();
        do_exit(SIGSEGV);
 }
 
index 2982579..8768a36 100644 (file)
@@ -333,6 +333,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
 {
        struct list_head *pos;
        unsigned ordseq;
+       int unplug_it = 1;
 
        blk_add_trace_rq(q, rq, BLK_TA_INSERT);
 
@@ -399,6 +400,11 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
                }
 
                list_add_tail(&rq->queuelist, pos);
+               /*
+                * most requeues happen because of a busy condition, don't
+                * force unplug of the queue for that case.
+                */
+               unplug_it = 0;
                break;
 
        default:
@@ -407,7 +413,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
                BUG();
        }
 
-       if (blk_queue_plugged(q)) {
+       if (unplug_it && blk_queue_plugged(q)) {
                int nrq = q->rq.count[READ] + q->rq.count[WRITE]
                        - q->in_flight;
 
index e5041a0..eac48be 100644 (file)
@@ -1732,8 +1732,21 @@ void blk_run_queue(struct request_queue *q)
 
        spin_lock_irqsave(q->queue_lock, flags);
        blk_remove_plug(q);
-       if (!elv_queue_empty(q))
-               q->request_fn(q);
+
+       /*
+        * Only recurse once to avoid overrunning the stack, let the unplug
+        * handling reinvoke the handler shortly if we already got there.
+        */
+       if (!elv_queue_empty(q)) {
+               if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
+                       q->request_fn(q);
+                       clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
+               } else {
+                       blk_plug_device(q);
+                       kblockd_schedule_work(&q->unplug_work);
+               }
+       }
+
        spin_unlock_irqrestore(q->queue_lock, flags);
 }
 EXPORT_SYMBOL(blk_run_queue);
index 0e71dff..b1ea4df 100644 (file)
@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd)
        }
 }
 
+static int class_device_add_groups(struct class_device * cd)
+{
+       int i;
+       int error = 0;
+
+       if (cd->groups) {
+               for (i = 0; cd->groups[i]; i++) {
+                       error = sysfs_create_group(&cd->kobj, cd->groups[i]);
+                       if (error) {
+                               while (--i >= 0)
+                                       sysfs_remove_group(&cd->kobj, cd->groups[i]);
+                               goto out;
+                       }
+               }
+       }
+out:
+       return error;
+}
+
+static void class_device_remove_groups(struct class_device * cd)
+{
+       int i;
+       if (cd->groups) {
+               for (i = 0; cd->groups[i]; i++) {
+                       sysfs_remove_group(&cd->kobj, cd->groups[i]);
+               }
+       }
+}
+
 static ssize_t show_dev(struct class_device *class_dev, char *buf)
 {
        return print_dev_t(buf, class_dev->devt);
@@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev)
                                  class_name);
        }
 
+       class_device_add_groups(class_dev);
+
        kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 
        /* notify any interfaces this device is now here */
@@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev)
        if (class_dev->devt_attr)
                class_device_remove_file(class_dev, class_dev->devt_attr);
        class_device_remove_attrs(class_dev);
+       class_device_remove_groups(class_dev);
 
        kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
        kobject_del(&class_dev->kobj);
index f73446f..c688c25 100644 (file)
@@ -536,6 +536,9 @@ static void ub_cleanup(struct ub_dev *sc)
                kfree(lun);
        }
 
+       usb_set_intfdata(sc->intf, NULL);
+       usb_put_intf(sc->intf);
+       usb_put_dev(sc->dev);
        kfree(sc);
 }
 
@@ -2221,7 +2224,12 @@ static int ub_probe(struct usb_interface *intf,
        // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
        usb_set_intfdata(intf, sc);
        usb_get_dev(sc->dev);
-       // usb_get_intf(sc->intf);      /* Do we need this? */
+       /*
+        * Since we give the interface struct to the block level through
+        * disk->driverfs_dev, we have to pin it. Otherwise, block_uevent
+        * oopses on close after a disconnect (kernels 2.6.16 and up).
+        */
+       usb_get_intf(sc->intf);
 
        snprintf(sc->name, 12, DRV_NAME "(%d.%d)",
            sc->dev->bus->busnum, sc->dev->devnum);
@@ -2286,7 +2294,7 @@ static int ub_probe(struct usb_interface *intf,
 
 err_dev_desc:
        usb_set_intfdata(intf, NULL);
-       // usb_put_intf(sc->intf);
+       usb_put_intf(sc->intf);
        usb_put_dev(sc->dev);
        kfree(sc);
 err_core:
@@ -2461,12 +2469,6 @@ static void ub_disconnect(struct usb_interface *intf)
         * and no URBs left in transit.
         */
 
-       usb_set_intfdata(intf, NULL);
-       // usb_put_intf(sc->intf);
-       sc->intf = NULL;
-       usb_put_dev(sc->dev);
-       sc->dev = NULL;
-
        ub_put(sc);
 }
 
index 4022966..78d928f 100644 (file)
@@ -291,7 +291,7 @@ config SX
 
 config RIO
        tristate "Specialix RIO system support"
-       depends on SERIAL_NONSTANDARD && !64BIT
+       depends on SERIAL_NONSTANDARD
        help
          This is a driver for the Specialix RIO, a smart serial card which
          drives an outboard box that can support up to 128 ports.  Product
index 02114a0..128b263 100644 (file)
@@ -1981,10 +1981,6 @@ static int __init cmm_init(void)
        if (!cmm_class)
                return -1;
 
-       rc = pcmcia_register_driver(&cm4000_driver);
-       if (rc < 0)
-               return rc;
-
        major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
        if (major < 0) {
                printk(KERN_WARNING MODULE_NAME
@@ -1992,6 +1988,12 @@ static int __init cmm_init(void)
                return -1;
        }
 
+       rc = pcmcia_register_driver(&cm4000_driver);
+       if (rc < 0) {
+               unregister_chrdev(major, DEVICE_NAME);
+               return rc;
+       }
+
        return 0;
 }
 
index 29efa64..47a8465 100644 (file)
@@ -724,16 +724,19 @@ static int __init cm4040_init(void)
        if (!cmx_class)
                return -1;
 
-       rc = pcmcia_register_driver(&reader_driver);
-       if (rc < 0)
-               return rc;
-
        major = register_chrdev(0, DEVICE_NAME, &reader_fops);
        if (major < 0) {
                printk(KERN_WARNING MODULE_NAME
                        ": could not get major number\n");
                return -1;
        }
+
+       rc = pcmcia_register_driver(&reader_driver);
+       if (rc < 0) {
+               unregister_chrdev(major, DEVICE_NAME);
+               return rc;
+       }
+
        return 0;
 }
 
index 3ec73d1..179cdbe 100644 (file)
 #ifndef __rio_host_h__
 #define __rio_host_h__
 
-#ifdef SCCS_LABELS
-#ifndef lint
-static char *_host_h_sccs_ = "@(#)host.h       1.2";
-#endif
-#endif
-
 /*
 ** the host structure - one per host card in the system.
 */
@@ -77,9 +71,6 @@ struct Host {
 #define RC_STARTUP            1
 #define RC_RUNNING            2
 #define RC_STUFFED            3
-#define RC_SOMETHING          4
-#define RC_SOMETHING_NEW      5
-#define RC_SOMETHING_ELSE     6
 #define RC_READY              7
 #define RUN_STATE             7
 /*
index acda932..290143a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/termios.h>
 #include <linux/serial.h>
+#include <linux/vmalloc.h>
 #include <asm/semaphore.h>
 #include <linux/generic_serial.h>
 #include <linux/errno.h>
index d31aba6..75b2557 100644 (file)
@@ -1394,14 +1394,17 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd)
                return RIO_FAIL;
        }
 
-       if (((int) ((char) PortP->InUse) == -1) || !(CmdBlkP = RIOGetCmdBlk())) {
-               rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n", Cmd, PortP->PortNum);
+       if ((PortP->InUse == (typeof(PortP->InUse))-1) ||
+                       !(CmdBlkP = RIOGetCmdBlk())) {
+               rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block "
+                       "for command %d on port %d\n", Cmd, PortP->PortNum);
                return RIO_FAIL;
        }
 
-       rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", CmdBlkP, PortP->InUse);
+       rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n",
+                       CmdBlkP, PortP->InUse);
 
-       PktCmdP = (struct PktCmd_M *) &CmdBlkP->Packet.data[0];
+       PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
 
        CmdBlkP->Packet.src_unit = 0;
        if (PortP->SecondBlock)
@@ -1425,38 +1428,46 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd)
 
        switch (Cmd) {
        case MEMDUMP:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p (addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p "
+                               "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr);
                PktCmdP->SubCommand = MEMDUMP;
                PktCmdP->SubAddr = SubCmd.Addr;
                break;
        case FCLOSE:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n",
+                               CmdBlkP);
                break;
        case READ_REGISTER:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk %p\n", (int) SubCmd.Addr, CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) "
+                               "command blk %p\n", (int) SubCmd.Addr, CmdBlkP);
                PktCmdP->SubCommand = READ_REGISTER;
                PktCmdP->SubAddr = SubCmd.Addr;
                break;
        case RESUME:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n",
+                               CmdBlkP);
                break;
        case RFLUSH:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n",
+                               CmdBlkP);
                CmdBlkP->PostFuncP = RIORFlushEnable;
                break;
        case SUSPEND:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n",
+                               CmdBlkP);
                break;
 
        case MGET:
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n",
+                               CmdBlkP);
                break;
 
        case MSET:
        case MBIC:
        case MBIS:
                CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
-               rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk %p\n", CmdBlkP);
+               rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command "
+                               "blk %p\n", CmdBlkP);
                break;
 
        case WFLUSH:
@@ -1465,12 +1476,14 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd)
                 ** allowed then we should not bother sending any more to the
                 ** RTA.
                 */
-               if ((int) ((char) PortP->WflushFlag) == (int) -1) {
-                       rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
+               if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) {
+                       rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, "
+                                       "WflushFlag about to wrap!");
                        RIOFreeCmdBlk(CmdBlkP);
                        return (RIO_FAIL);
                } else {
-                       rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command blk %p\n", CmdBlkP);
+                       rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command "
+                                       "blk %p\n", CmdBlkP);
                        CmdBlkP->PostFuncP = RIOWFlushMark;
                }
                break;
index 14b83fa..e8af5b3 100644 (file)
 #ifndef        __rioioctl_h__
 #define        __rioioctl_h__
 
-#ifdef SCCS_LABELS
-static char *_rioioctl_h_sccs_ = "@(#)rioioctl.h       1.2";
-#endif
-
 /*
 ** RIO device driver - user ioctls and associated structures.
 */
@@ -44,55 +40,13 @@ static char *_rioioctl_h_sccs_ = "@(#)rioioctl.h    1.2";
 struct portStats {
        int port;
        int gather;
-       ulong txchars;
-       ulong rxchars;
-       ulong opens;
-       ulong closes;
-       ulong ioctls;
+       unsigned long txchars;
+       unsigned long rxchars;
+       unsigned long opens;
+       unsigned long closes;
+       unsigned long ioctls;
 };
 
-
-#define rIOC   ('r'<<8)
-#define        TCRIOSTATE      (rIOC | 1)
-#define        TCRIOXPON       (rIOC | 2)
-#define        TCRIOXPOFF      (rIOC | 3)
-#define        TCRIOXPCPS      (rIOC | 4)
-#define        TCRIOXPRINT     (rIOC | 5)
-#define TCRIOIXANYON   (rIOC | 6)
-#define        TCRIOIXANYOFF   (rIOC | 7)
-#define TCRIOIXONON    (rIOC | 8)
-#define        TCRIOIXONOFF    (rIOC | 9)
-#define        TCRIOMBIS       (rIOC | 10)
-#define        TCRIOMBIC       (rIOC | 11)
-#define        TCRIOTRIAD      (rIOC | 12)
-#define TCRIOTSTATE    (rIOC | 13)
-
-/*
-** 15.10.1998 ARG - ESIL 0761 part fix
-** Add RIO ioctls for manipulating RTS and CTS flow control, (as LynxOS
-** appears to not support hardware flow control).
-*/
-#define TCRIOCTSFLOWEN (rIOC | 14)     /* enable CTS flow control */
-#define TCRIOCTSFLOWDIS        (rIOC | 15)     /* disable CTS flow control */
-#define TCRIORTSFLOWEN (rIOC | 16)     /* enable RTS flow control */
-#define TCRIORTSFLOWDIS        (rIOC | 17)     /* disable RTS flow control */
-
-/*
-** 09.12.1998 ARG - ESIL 0776 part fix
-** Definition for 'RIOC' also appears in daemon.h, so we'd better do a
-** #ifndef here first.
-** 'RIO_QUICK_CHECK' also #define'd here as this ioctl is now
-** allowed to be used by customers.
-**
-** 05.02.1999 ARG -
-** This is what I've decied to do with ioctls etc., which are intended to be
-** invoked from users applications :
-** Anything that needs to be defined here will be removed from daemon.h, that
-** way it won't end up having to be defined/maintained in two places. The only
-** consequence of this is that this file should now be #include'd by daemon.h
-**
-** 'stats' ioctls now #define'd here as they are to be used by customers.
-*/
 #define        RIOC    ('R'<<8)|('i'<<16)|('o'<<24)
 
 #define        RIO_QUICK_CHECK         (RIOC | 105)
index 1efde3b..fe00c7d 100644 (file)
@@ -22,7 +22,7 @@ config TCG_TPM
 
 config TCG_TIS
        tristate "TPM Interface Specification 1.2 Interface"
-       depends on TCG_TPM
+       depends on TCG_TPM && PNPACPI
        ---help---
          If you have a TPM security chip that is compliant with the
          TCG TIS 1.2 TPM specification say Yes and it will be accessible
index 54a4c80..050ced2 100644 (file)
@@ -140,7 +140,7 @@ extern int tpm_pm_resume(struct device *);
 extern struct dentry ** tpm_bios_log_setup(char *);
 extern void tpm_bios_log_teardown(struct dentry **);
 #else
-static inline struct dentry* tpm_bios_log_setup(char *name)
+static inline struct dentry ** tpm_bios_log_setup(char *name)
 {
        return NULL;
 }
index b9cae9a..f621168 100644 (file)
@@ -55,7 +55,7 @@ enum tis_int_flags {
 };
 
 enum tis_defaults {
-       TIS_MEM_BASE = 0xFED4000,
+       TIS_MEM_BASE = 0xFED40000,
        TIS_MEM_LEN = 0x5000,
        TIS_SHORT_TIMEOUT = 750,        /* ms */
        TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
index 956d121..3e6ffca 100644 (file)
@@ -74,6 +74,8 @@ static unsigned int dbs_enable;       /* number of CPUs using this policy */
 static DEFINE_MUTEX (dbs_mutex);
 static DECLARE_WORK    (dbs_work, do_dbs_timer, NULL);
 
+static struct workqueue_struct *dbs_workq;
+
 struct dbs_tuners {
        unsigned int sampling_rate;
        unsigned int sampling_down_factor;
@@ -364,23 +366,29 @@ static void do_dbs_timer(void *data)
        mutex_lock(&dbs_mutex);
        for_each_online_cpu(i)
                dbs_check_cpu(i);
-       schedule_delayed_work(&dbs_work,
-                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+       queue_delayed_work(dbs_workq, &dbs_work,
+                          usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
        mutex_unlock(&dbs_mutex);
 }
 
 static inline void dbs_timer_init(void)
 {
        INIT_WORK(&dbs_work, do_dbs_timer, NULL);
-       schedule_delayed_work(&dbs_work,
-                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+       if (!dbs_workq)
+               dbs_workq = create_singlethread_workqueue("ondemand");
+       if (!dbs_workq) {
+               printk(KERN_ERR "ondemand: Cannot initialize kernel thread\n");
+               return;
+       }
+       queue_delayed_work(dbs_workq, &dbs_work,
+                          usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
        return;
 }
 
 static inline void dbs_timer_exit(void)
 {
-       cancel_delayed_work(&dbs_work);
-       return;
+       if (dbs_workq)
+               cancel_rearming_delayed_workqueue(dbs_workq, &dbs_work);
 }
 
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -489,8 +497,12 @@ static int __init cpufreq_gov_dbs_init(void)
 
 static void __exit cpufreq_gov_dbs_exit(void)
 {
-       /* Make sure that the scheduled work is indeed not running */
-       flush_scheduled_work();
+       /* Make sure that the scheduled work is indeed not running.
+          Assumes the timer has been cancelled first. */
+       if (dbs_workq) {
+               flush_workqueue(dbs_workq);
+               destroy_workqueue(dbs_workq);
+       }
 
        cpufreq_unregister_governor(&cpufreq_gov_dbs);
 }
index 66572c5..fce3193 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/slab.h>
 #include "edac_mc.h"
 
+static int force_function_unhide;
+
 #define e752x_printk(level, fmt, arg...) \
        edac_printk(level, "e752x", fmt, ##arg)
 
@@ -782,8 +784,16 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
        debugf0("%s(): mci\n", __func__);
        debugf0("Starting Probe1\n");
 
-       /* enable device 0 function 1 */
+       /* check to see if device 0 function 1 is enabled; if it isn't, we
+        * assume the BIOS has reserved it for a reason and is expecting
+        * exclusive access, we take care not to violate that assumption and
+        * fail the probe. */
        pci_read_config_byte(pdev, E752X_DEVPRES1, &stat8);
+       if (!force_function_unhide && !(stat8 & (1 << 5))) {
+               printk(KERN_INFO "Contact your BIOS vendor to see if the "
+                       "E752x error registers can be safely un-hidden\n");
+               goto fail;
+       }
        stat8 |= (1 << 5);
        pci_write_config_byte(pdev, E752X_DEVPRES1, stat8);
 
@@ -1063,3 +1073,8 @@ module_exit(e752x_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Linux Networx (http://lnxi.com) Tom Zimmerman\n");
 MODULE_DESCRIPTION("MC support for Intel e752x memory controllers");
+
+module_param(force_function_unhide, int, 0444);
+MODULE_PARM_DESC(force_function_unhide, "if BIOS sets Dev0:Fun1 up as hidden:"
+" 1=force unhide and hope BIOS doesn't fight driver for Dev0:Fun1 access");
+
index 8bd305e..a140e45 100644 (file)
@@ -133,6 +133,9 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
 
                outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
                outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
+
+               /* Reset the status register */
+               outb(0, ACBST);
                return;
        }
 
@@ -228,6 +231,10 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface)
        timeout = jiffies + POLL_TIMEOUT;
        while (time_before(jiffies, timeout)) {
                status = inb(ACBST);
+
+               /* Reset the status register to avoid the hang */
+               outb(0, ACBST);
+
                if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
                        scx200_acb_machine(iface, status);
                        return;
@@ -415,7 +422,6 @@ static int  __init scx200_acb_create(const char *text, int base, int index)
        struct scx200_acb_iface *iface;
        struct i2c_adapter *adapter;
        int rc;
-       char description[64];
 
        iface = kzalloc(sizeof(*iface), GFP_KERNEL);
        if (!iface) {
@@ -434,10 +440,7 @@ static int  __init scx200_acb_create(const char *text, int base, int index)
 
        mutex_init(&iface->mutex);
 
-       snprintf(description, sizeof(description), "%s ACCESS.bus [%s]",
-                text, adapter->name);
-
-       if (request_region(base, 8, description) == 0) {
+       if (!request_region(base, 8, adapter->name)) {
                printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n",
                        base, base + 8-1);
                rc = -EBUSY;
@@ -524,6 +527,9 @@ static int __init scx200_acb_init(void)
        } else if (pci_dev_present(divil_pci))
                rc = scx200_add_cs553x();
 
+       /* If at least one bus was created, init must succeed */
+       if (scx200_acb_list)
+               return 0;
        return rc;
 }
 
index 4961f1e..602797a 100644 (file)
@@ -392,6 +392,7 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
        PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
        PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
+       PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
        PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
index 7cfedb8..86fee43 100644 (file)
@@ -34,6 +34,8 @@
  *
  * $Id: cm.c 2821 2005-07-08 17:07:28Z sean.hefty $
  */
+
+#include <linux/completion.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/idr.h>
@@ -122,7 +124,7 @@ struct cm_id_private {
        struct rb_node service_node;
        struct rb_node sidr_id_node;
        spinlock_t lock;        /* Do not acquire inside cm.lock */
-       wait_queue_head_t wait;
+       struct completion comp;
        atomic_t refcount;
 
        struct ib_mad_send_buf *msg;
@@ -159,7 +161,7 @@ static void cm_work_handler(void *data);
 static inline void cm_deref_id(struct cm_id_private *cm_id_priv)
 {
        if (atomic_dec_and_test(&cm_id_priv->refcount))
-               wake_up(&cm_id_priv->wait);
+               complete(&cm_id_priv->comp);
 }
 
 static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
@@ -559,7 +561,7 @@ struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
                goto error;
 
        spin_lock_init(&cm_id_priv->lock);
-       init_waitqueue_head(&cm_id_priv->wait);
+       init_completion(&cm_id_priv->comp);
        INIT_LIST_HEAD(&cm_id_priv->work_list);
        atomic_set(&cm_id_priv->work_count, -1);
        atomic_set(&cm_id_priv->refcount, 1);
@@ -724,8 +726,8 @@ retest:
        }
 
        cm_free_id(cm_id->local_id);
-       atomic_dec(&cm_id_priv->refcount);
-       wait_event(cm_id_priv->wait, !atomic_read(&cm_id_priv->refcount));
+       cm_deref_id(cm_id_priv);
+       wait_for_completion(&cm_id_priv->comp);
        while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
                cm_free_work(work);
        if (cm_id_priv->private_data && cm_id_priv->private_data_len)
index 469b692..5ad41a6 100644 (file)
@@ -352,7 +352,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
        INIT_WORK(&mad_agent_priv->local_work, local_completions,
                   mad_agent_priv);
        atomic_set(&mad_agent_priv->refcount, 1);
-       init_waitqueue_head(&mad_agent_priv->wait);
+       init_completion(&mad_agent_priv->comp);
 
        return &mad_agent_priv->agent;
 
@@ -467,7 +467,7 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
        mad_snoop_priv->agent.qp = port_priv->qp_info[qpn].qp;
        mad_snoop_priv->agent.port_num = port_num;
        mad_snoop_priv->mad_snoop_flags = mad_snoop_flags;
-       init_waitqueue_head(&mad_snoop_priv->wait);
+       init_completion(&mad_snoop_priv->comp);
        mad_snoop_priv->snoop_index = register_snoop_agent(
                                                &port_priv->qp_info[qpn],
                                                mad_snoop_priv);
@@ -486,6 +486,18 @@ error1:
 }
 EXPORT_SYMBOL(ib_register_mad_snoop);
 
+static inline void deref_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
+{
+       if (atomic_dec_and_test(&mad_agent_priv->refcount))
+               complete(&mad_agent_priv->comp);
+}
+
+static inline void deref_snoop_agent(struct ib_mad_snoop_private *mad_snoop_priv)
+{
+       if (atomic_dec_and_test(&mad_snoop_priv->refcount))
+               complete(&mad_snoop_priv->comp);
+}
+
 static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
 {
        struct ib_mad_port_private *port_priv;
@@ -509,9 +521,8 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
        flush_workqueue(port_priv->wq);
        ib_cancel_rmpp_recvs(mad_agent_priv);
 
-       atomic_dec(&mad_agent_priv->refcount);
-       wait_event(mad_agent_priv->wait,
-                  !atomic_read(&mad_agent_priv->refcount));
+       deref_mad_agent(mad_agent_priv);
+       wait_for_completion(&mad_agent_priv->comp);
 
        kfree(mad_agent_priv->reg_req);
        ib_dereg_mr(mad_agent_priv->agent.mr);
@@ -529,9 +540,8 @@ static void unregister_mad_snoop(struct ib_mad_snoop_private *mad_snoop_priv)
        atomic_dec(&qp_info->snoop_count);
        spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
 
-       atomic_dec(&mad_snoop_priv->refcount);
-       wait_event(mad_snoop_priv->wait,
-                  !atomic_read(&mad_snoop_priv->refcount));
+       deref_snoop_agent(mad_snoop_priv);
+       wait_for_completion(&mad_snoop_priv->comp);
 
        kfree(mad_snoop_priv);
 }
@@ -600,8 +610,7 @@ static void snoop_send(struct ib_mad_qp_info *qp_info,
                spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
                mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent,
                                                    send_buf, mad_send_wc);
-               if (atomic_dec_and_test(&mad_snoop_priv->refcount))
-                       wake_up(&mad_snoop_priv->wait);
+               deref_snoop_agent(mad_snoop_priv);
                spin_lock_irqsave(&qp_info->snoop_lock, flags);
        }
        spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
@@ -626,8 +635,7 @@ static void snoop_recv(struct ib_mad_qp_info *qp_info,
                spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
                mad_snoop_priv->agent.recv_handler(&mad_snoop_priv->agent,
                                                   mad_recv_wc);
-               if (atomic_dec_and_test(&mad_snoop_priv->refcount))
-                       wake_up(&mad_snoop_priv->wait);
+               deref_snoop_agent(mad_snoop_priv);
                spin_lock_irqsave(&qp_info->snoop_lock, flags);
        }
        spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
@@ -968,8 +976,7 @@ void ib_free_send_mad(struct ib_mad_send_buf *send_buf)
 
        free_send_rmpp_list(mad_send_wr);
        kfree(send_buf->mad);
-       if (atomic_dec_and_test(&mad_agent_priv->refcount))
-               wake_up(&mad_agent_priv->wait);
+       deref_mad_agent(mad_agent_priv);
 }
 EXPORT_SYMBOL(ib_free_send_mad);
 
@@ -1757,8 +1764,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
                mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
                                                      mad_recv_wc);
                if (!mad_recv_wc) {
-                       if (atomic_dec_and_test(&mad_agent_priv->refcount))
-                               wake_up(&mad_agent_priv->wait);
+                       deref_mad_agent(mad_agent_priv);
                        return;
                }
        }
@@ -1770,8 +1776,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
                if (!mad_send_wr) {
                        spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
                        ib_free_recv_mad(mad_recv_wc);
-                       if (atomic_dec_and_test(&mad_agent_priv->refcount))
-                               wake_up(&mad_agent_priv->wait);
+                       deref_mad_agent(mad_agent_priv);
                        return;
                }
                ib_mark_mad_done(mad_send_wr);
@@ -1790,8 +1795,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
        } else {
                mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
                                                   mad_recv_wc);
-               if (atomic_dec_and_test(&mad_agent_priv->refcount))
-                       wake_up(&mad_agent_priv->wait);
+               deref_mad_agent(mad_agent_priv);
        }
 }
 
@@ -2021,8 +2025,7 @@ void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
                                                   mad_send_wc);
 
        /* Release reference on agent taken when sending */
-       if (atomic_dec_and_test(&mad_agent_priv->refcount))
-               wake_up(&mad_agent_priv->wait);
+       deref_mad_agent(mad_agent_priv);
        return;
 done:
        spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
index 6c9c133..b4fa28d 100644 (file)
@@ -37,6 +37,7 @@
 #ifndef __IB_MAD_PRIV_H__
 #define __IB_MAD_PRIV_H__
 
+#include <linux/completion.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/workqueue.h>
@@ -108,7 +109,7 @@ struct ib_mad_agent_private {
        struct list_head rmpp_list;
 
        atomic_t refcount;
-       wait_queue_head_t wait;
+       struct completion comp;
 };
 
 struct ib_mad_snoop_private {
@@ -117,7 +118,7 @@ struct ib_mad_snoop_private {
        int snoop_index;
        int mad_snoop_flags;
        atomic_t refcount;
-       wait_queue_head_t wait;
+       struct completion comp;
 };
 
 struct ib_mad_send_wr_private {
index dfd4e58..d4704e0 100644 (file)
@@ -49,7 +49,7 @@ struct mad_rmpp_recv {
        struct list_head list;
        struct work_struct timeout_work;
        struct work_struct cleanup_work;
-       wait_queue_head_t wait;
+       struct completion comp;
        enum rmpp_state state;
        spinlock_t lock;
        atomic_t refcount;
@@ -69,10 +69,16 @@ struct mad_rmpp_recv {
        u8 method;
 };
 
+static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
+{
+       if (atomic_dec_and_test(&rmpp_recv->refcount))
+               complete(&rmpp_recv->comp);
+}
+
 static void destroy_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
 {
-       atomic_dec(&rmpp_recv->refcount);
-       wait_event(rmpp_recv->wait, !atomic_read(&rmpp_recv->refcount));
+       deref_rmpp_recv(rmpp_recv);
+       wait_for_completion(&rmpp_recv->comp);
        ib_destroy_ah(rmpp_recv->ah);
        kfree(rmpp_recv);
 }
@@ -253,7 +259,7 @@ create_rmpp_recv(struct ib_mad_agent_private *agent,
                goto error;
 
        rmpp_recv->agent = agent;
-       init_waitqueue_head(&rmpp_recv->wait);
+       init_completion(&rmpp_recv->comp);
        INIT_WORK(&rmpp_recv->timeout_work, recv_timeout_handler, rmpp_recv);
        INIT_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler, rmpp_recv);
        spin_lock_init(&rmpp_recv->lock);
@@ -279,12 +285,6 @@ error:     kfree(rmpp_recv);
        return NULL;
 }
 
-static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
-{
-       if (atomic_dec_and_test(&rmpp_recv->refcount))
-               wake_up(&rmpp_recv->wait);
-}
-
 static struct mad_rmpp_recv *
 find_rmpp_recv(struct ib_mad_agent_private *agent,
               struct ib_mad_recv_wc *mad_recv_wc)
index 15121cb..21f9282 100644 (file)
@@ -336,7 +336,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
        switch (width) {
        case 4:
                ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >>
-                                           (offset % 4)) & 0xf);
+                                           (4 - (offset % 8))) & 0xf);
                break;
        case 8:
                ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]);
index f6a0596..9164a09 100644 (file)
@@ -32,6 +32,8 @@
  *
  * $Id: ucm.c 2594 2005-06-13 19:46:02Z libor $
  */
+
+#include <linux/completion.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/module.h>
@@ -72,7 +74,7 @@ struct ib_ucm_file {
 
 struct ib_ucm_context {
        int                 id;
-       wait_queue_head_t   wait;
+       struct completion   comp;
        atomic_t            ref;
        int                 events_reported;
 
@@ -138,7 +140,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
 static void ib_ucm_ctx_put(struct ib_ucm_context *ctx)
 {
        if (atomic_dec_and_test(&ctx->ref))
-               wake_up(&ctx->wait);
+               complete(&ctx->comp);
 }
 
 static inline int ib_ucm_new_cm_id(int event)
@@ -178,7 +180,7 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
                return NULL;
 
        atomic_set(&ctx->ref, 1);
-       init_waitqueue_head(&ctx->wait);
+       init_completion(&ctx->comp);
        ctx->file = file;
        INIT_LIST_HEAD(&ctx->events);
 
@@ -586,8 +588,8 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       atomic_dec(&ctx->ref);
-       wait_event(ctx->wait, !atomic_read(&ctx->ref));
+       ib_ucm_ctx_put(ctx);
+       wait_for_completion(&ctx->comp);
 
        /* No new events will be generated after destroying the cm_id. */
        ib_destroy_cm_id(ctx->cm_id);
index 398add4..3697eda 100644 (file)
@@ -116,10 +116,9 @@ static int __devinit ipath_init_one(struct pci_dev *,
 #define PCI_DEVICE_ID_INFINIPATH_PE800 0x10
 
 static const struct pci_device_id ipath_pci_tbl[] = {
-       {PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE,
-                   PCI_DEVICE_ID_INFINIPATH_HT)},
-       {PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE,
-                   PCI_DEVICE_ID_INFINIPATH_PE800)},
+       { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
+       { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
+       { 0, }
 };
 
 MODULE_DEVICE_TABLE(pci, ipath_pci_tbl);
index 312cf90..205854e 100644 (file)
@@ -238,9 +238,9 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
        spin_lock(&dev->cq_table.lock);
 
        cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
-
        if (cq)
-               atomic_inc(&cq->refcount);
+               ++cq->refcount;
+
        spin_unlock(&dev->cq_table.lock);
 
        if (!cq) {
@@ -254,8 +254,10 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
        if (cq->ibcq.event_handler)
                cq->ibcq.event_handler(&event, cq->ibcq.cq_context);
 
-       if (atomic_dec_and_test(&cq->refcount))
+       spin_lock(&dev->cq_table.lock);
+       if (!--cq->refcount)
                wake_up(&cq->wait);
+       spin_unlock(&dev->cq_table.lock);
 }
 
 static inline int is_recv_cqe(struct mthca_cqe *cqe)
@@ -267,23 +269,13 @@ static inline int is_recv_cqe(struct mthca_cqe *cqe)
                return !(cqe->is_send & 0x80);
 }
 
-void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
+void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn,
                    struct mthca_srq *srq)
 {
-       struct mthca_cq *cq;
        struct mthca_cqe *cqe;
        u32 prod_index;
        int nfreed = 0;
 
-       spin_lock_irq(&dev->cq_table.lock);
-       cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
-       if (cq)
-               atomic_inc(&cq->refcount);
-       spin_unlock_irq(&dev->cq_table.lock);
-
-       if (!cq)
-               return;
-
        spin_lock_irq(&cq->lock);
 
        /*
@@ -301,7 +293,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
 
        if (0)
                mthca_dbg(dev, "Cleaning QPN %06x from CQN %06x; ci %d, pi %d\n",
-                         qpn, cqn, cq->cons_index, prod_index);
+                         qpn, cq->cqn, cq->cons_index, prod_index);
 
        /*
         * Now sweep backwards through the CQ, removing CQ entries
@@ -325,8 +317,6 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
        }
 
        spin_unlock_irq(&cq->lock);
-       if (atomic_dec_and_test(&cq->refcount))
-               wake_up(&cq->wait);
 }
 
 void mthca_cq_resize_copy_cqes(struct mthca_cq *cq)
@@ -821,7 +811,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
        }
 
        spin_lock_init(&cq->lock);
-       atomic_set(&cq->refcount, 1);
+       cq->refcount = 1;
        init_waitqueue_head(&cq->wait);
 
        memset(cq_context, 0, sizeof *cq_context);
@@ -896,6 +886,17 @@ err_out:
        return err;
 }
 
+static inline int get_cq_refcount(struct mthca_dev *dev, struct mthca_cq *cq)
+{
+       int c;
+
+       spin_lock_irq(&dev->cq_table.lock);
+       c = cq->refcount;
+       spin_unlock_irq(&dev->cq_table.lock);
+
+       return c;
+}
+
 void mthca_free_cq(struct mthca_dev *dev,
                   struct mthca_cq *cq)
 {
@@ -929,6 +930,7 @@ void mthca_free_cq(struct mthca_dev *dev,
        spin_lock_irq(&dev->cq_table.lock);
        mthca_array_clear(&dev->cq_table.cq,
                          cq->cqn & (dev->limits.num_cqs - 1));
+       --cq->refcount;
        spin_unlock_irq(&dev->cq_table.lock);
 
        if (dev->mthca_flags & MTHCA_FLAG_MSI_X)
@@ -936,8 +938,7 @@ void mthca_free_cq(struct mthca_dev *dev,
        else
                synchronize_irq(dev->pdev->irq);
 
-       atomic_dec(&cq->refcount);
-       wait_event(cq->wait, !atomic_read(&cq->refcount));
+       wait_event(cq->wait, !get_cq_refcount(dev, cq));
 
        if (cq->is_kernel) {
                mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
index 4c1dcb4..f8160b8 100644 (file)
@@ -496,7 +496,7 @@ void mthca_free_cq(struct mthca_dev *dev,
 void mthca_cq_completion(struct mthca_dev *dev, u32 cqn);
 void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
                    enum ib_event_type event_type);
-void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
+void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn,
                    struct mthca_srq *srq);
 void mthca_cq_resize_copy_cqes(struct mthca_cq *cq);
 int mthca_alloc_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int nent);
index 25e1c1d..a486dec 100644 (file)
@@ -761,6 +761,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
 
 int __devinit mthca_init_mr_table(struct mthca_dev *dev)
 {
+       unsigned long addr;
        int err, i;
 
        err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
@@ -796,9 +797,12 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev)
                        goto err_fmr_mpt;
                }
 
+               addr = pci_resource_start(dev->pdev, 4) +
+                       ((pci_resource_len(dev->pdev, 4) - 1) &
+                        dev->mr_table.mpt_base);
+
                dev->mr_table.tavor_fmr.mpt_base =
-                       ioremap(dev->mr_table.mpt_base,
-                               (1 << i) * sizeof (struct mthca_mpt_entry));
+                       ioremap(addr, (1 << i) * sizeof(struct mthca_mpt_entry));
 
                if (!dev->mr_table.tavor_fmr.mpt_base) {
                        mthca_warn(dev, "MPT ioremap for FMR failed.\n");
@@ -806,9 +810,12 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev)
                        goto err_fmr_mpt;
                }
 
+               addr = pci_resource_start(dev->pdev, 4) +
+                       ((pci_resource_len(dev->pdev, 4) - 1) &
+                        dev->mr_table.mtt_base);
+
                dev->mr_table.tavor_fmr.mtt_base =
-                       ioremap(dev->mr_table.mtt_base,
-                               (1 << i) * MTHCA_MTT_SEG_SIZE);
+                       ioremap(addr, (1 << i) * MTHCA_MTT_SEG_SIZE);
                if (!dev->mr_table.tavor_fmr.mtt_base) {
                        mthca_warn(dev, "MTT ioremap for FMR failed.\n");
                        err = -ENOMEM;
index 6676a78..179a8f6 100644 (file)
@@ -139,11 +139,12 @@ struct mthca_ah {
  * a qp may be locked, with the send cq locked first.  No other
  * nesting should be done.
  *
- * Each struct mthca_cq/qp also has an atomic_t ref count.  The
- * pointer from the cq/qp_table to the struct counts as one reference.
- * This reference also is good for access through the consumer API, so
- * modifying the CQ/QP etc doesn't need to take another reference.
- * Access because of a completion being polled does need a reference.
+ * Each struct mthca_cq/qp also has an ref count, protected by the
+ * corresponding table lock.  The pointer from the cq/qp_table to the
+ * struct counts as one reference.  This reference also is good for
+ * access through the consumer API, so modifying the CQ/QP etc doesn't
+ * need to take another reference.  Access to a QP because of a
+ * completion being polled does not need a reference either.
  *
  * Finally, each struct mthca_cq/qp has a wait_queue_head_t for the
  * destroy function to sleep on.
@@ -159,8 +160,9 @@ struct mthca_ah {
  * - decrement ref count; if zero, wake up waiters
  *
  * To destroy a CQ/QP, we can do the following:
- * - lock cq/qp_table, remove pointer, unlock cq/qp_table lock
- * - decrement ref count
+ * - lock cq/qp_table
+ * - remove pointer and decrement ref count
+ * - unlock cq/qp_table lock
  * - wait_event until ref count is zero
  *
  * It is the consumer's responsibilty to make sure that no QP
@@ -197,7 +199,7 @@ struct mthca_cq_resize {
 struct mthca_cq {
        struct ib_cq            ibcq;
        spinlock_t              lock;
-       atomic_t                refcount;
+       int                     refcount;
        int                     cqn;
        u32                     cons_index;
        struct mthca_cq_buf     buf;
@@ -217,7 +219,7 @@ struct mthca_cq {
 struct mthca_srq {
        struct ib_srq           ibsrq;
        spinlock_t              lock;
-       atomic_t                refcount;
+       int                     refcount;
        int                     srqn;
        int                     max;
        int                     max_gs;
@@ -254,7 +256,7 @@ struct mthca_wq {
 
 struct mthca_qp {
        struct ib_qp           ibqp;
-       atomic_t               refcount;
+       int                    refcount;
        u32                    qpn;
        int                    is_direct;
        u8                     port; /* for SQP and memfree use only */
index f37b0e3..19765f6 100644 (file)
@@ -240,7 +240,7 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
        spin_lock(&dev->qp_table.lock);
        qp = mthca_array_get(&dev->qp_table.qp, qpn & (dev->limits.num_qps - 1));
        if (qp)
-               atomic_inc(&qp->refcount);
+               ++qp->refcount;
        spin_unlock(&dev->qp_table.lock);
 
        if (!qp) {
@@ -257,8 +257,10 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
        if (qp->ibqp.event_handler)
                qp->ibqp.event_handler(&event, qp->ibqp.qp_context);
 
-       if (atomic_dec_and_test(&qp->refcount))
+       spin_lock(&dev->qp_table.lock);
+       if (!--qp->refcount)
                wake_up(&qp->wait);
+       spin_unlock(&dev->qp_table.lock);
 }
 
 static int to_mthca_state(enum ib_qp_state ib_state)
@@ -833,10 +835,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
         * entries and reinitialize the QP.
         */
        if (new_state == IB_QPS_RESET && !qp->ibqp.uobject) {
-               mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn,
+               mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn,
                               qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
                if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
-                       mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn,
+                       mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn,
                                       qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
 
                mthca_wq_init(&qp->sq);
@@ -1096,7 +1098,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
        int ret;
        int i;
 
-       atomic_set(&qp->refcount, 1);
+       qp->refcount = 1;
        init_waitqueue_head(&qp->wait);
        qp->state        = IB_QPS_RESET;
        qp->atomic_rd_en = 0;
@@ -1318,6 +1320,17 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
        return err;
 }
 
+static inline int get_qp_refcount(struct mthca_dev *dev, struct mthca_qp *qp)
+{
+       int c;
+
+       spin_lock_irq(&dev->qp_table.lock);
+       c = qp->refcount;
+       spin_unlock_irq(&dev->qp_table.lock);
+
+       return c;
+}
+
 void mthca_free_qp(struct mthca_dev *dev,
                   struct mthca_qp *qp)
 {
@@ -1339,14 +1352,14 @@ void mthca_free_qp(struct mthca_dev *dev,
        spin_lock(&dev->qp_table.lock);
        mthca_array_clear(&dev->qp_table.qp,
                          qp->qpn & (dev->limits.num_qps - 1));
+       --qp->refcount;
        spin_unlock(&dev->qp_table.lock);
 
        if (send_cq != recv_cq)
                spin_unlock(&recv_cq->lock);
        spin_unlock_irq(&send_cq->lock);
 
-       atomic_dec(&qp->refcount);
-       wait_event(qp->wait, !atomic_read(&qp->refcount));
+       wait_event(qp->wait, !get_qp_refcount(dev, qp));
 
        if (qp->state != IB_QPS_RESET)
                mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0,
@@ -1358,10 +1371,10 @@ void mthca_free_qp(struct mthca_dev *dev,
         * unref the mem-free tables and free the QPN in our table.
         */
        if (!qp->ibqp.uobject) {
-               mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn,
+               mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn,
                               qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
                if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
-                       mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn,
+                       mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn,
                                       qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
 
                mthca_free_memfree(dev, qp);
index adcaf85..1ea4332 100644 (file)
@@ -241,7 +241,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
                goto err_out_mailbox;
 
        spin_lock_init(&srq->lock);
-       atomic_set(&srq->refcount, 1);
+       srq->refcount = 1;
        init_waitqueue_head(&srq->wait);
 
        if (mthca_is_memfree(dev))
@@ -308,6 +308,17 @@ err_out:
        return err;
 }
 
+static inline int get_srq_refcount(struct mthca_dev *dev, struct mthca_srq *srq)
+{
+       int c;
+
+       spin_lock_irq(&dev->srq_table.lock);
+       c = srq->refcount;
+       spin_unlock_irq(&dev->srq_table.lock);
+
+       return c;
+}
+
 void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq)
 {
        struct mthca_mailbox *mailbox;
@@ -329,10 +340,10 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq)
        spin_lock_irq(&dev->srq_table.lock);
        mthca_array_clear(&dev->srq_table.srq,
                          srq->srqn & (dev->limits.num_srqs - 1));
+       --srq->refcount;
        spin_unlock_irq(&dev->srq_table.lock);
 
-       atomic_dec(&srq->refcount);
-       wait_event(srq->wait, !atomic_read(&srq->refcount));
+       wait_event(srq->wait, !get_srq_refcount(dev, srq));
 
        if (!srq->ibsrq.uobject) {
                mthca_free_srq_buf(dev, srq);
@@ -414,7 +425,7 @@ void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
        spin_lock(&dev->srq_table.lock);
        srq = mthca_array_get(&dev->srq_table.srq, srqn & (dev->limits.num_srqs - 1));
        if (srq)
-               atomic_inc(&srq->refcount);
+               ++srq->refcount;
        spin_unlock(&dev->srq_table.lock);
 
        if (!srq) {
@@ -431,8 +442,10 @@ void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
        srq->ibsrq.event_handler(&event, srq->ibsrq.srq_context);
 
 out:
-       if (atomic_dec_and_test(&srq->refcount))
+       spin_lock(&dev->srq_table.lock);
+       if (!--srq->refcount)
                wake_up(&srq->wait);
+       spin_unlock(&dev->srq_table.lock);
 }
 
 /*
index 4ca1755..f887780 100644 (file)
@@ -158,10 +158,8 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
                if (priv->pkey == pkey) {
                        unregister_netdev(priv->dev);
                        ipoib_dev_cleanup(priv->dev);
-
                        list_del(&priv->list);
-
-                       kfree(priv);
+                       free_netdev(priv->dev);
 
                        ret = 0;
                        break;
index 5bb5574..c32ce43 100644 (file)
@@ -409,6 +409,34 @@ static int srp_connect_target(struct srp_target_port *target)
        }
 }
 
+static void srp_unmap_data(struct scsi_cmnd *scmnd,
+                          struct srp_target_port *target,
+                          struct srp_request *req)
+{
+       struct scatterlist *scat;
+       int nents;
+
+       if (!scmnd->request_buffer ||
+           (scmnd->sc_data_direction != DMA_TO_DEVICE &&
+            scmnd->sc_data_direction != DMA_FROM_DEVICE))
+               return;
+
+       /*
+        * This handling of non-SG commands can be killed when the
+        * SCSI midlayer no longer generates non-SG commands.
+        */
+       if (likely(scmnd->use_sg)) {
+               nents = scmnd->use_sg;
+               scat  = scmnd->request_buffer;
+       } else {
+               nents = 1;
+               scat  = &req->fake_sg;
+       }
+
+       dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents,
+                    scmnd->sc_data_direction);
+}
+
 static int srp_reconnect_target(struct srp_target_port *target)
 {
        struct ib_cm_id *new_cm_id;
@@ -455,16 +483,16 @@ static int srp_reconnect_target(struct srp_target_port *target)
        list_for_each_entry(req, &target->req_queue, list) {
                req->scmnd->result = DID_RESET << 16;
                req->scmnd->scsi_done(req->scmnd);
+               srp_unmap_data(req->scmnd, target, req);
        }
 
        target->rx_head  = 0;
        target->tx_head  = 0;
        target->tx_tail  = 0;
-       target->req_head = 0;
-       for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
-               target->req_ring[i].next = i + 1;
-       target->req_ring[SRP_SQ_SIZE - 1].next = -1;
+       INIT_LIST_HEAD(&target->free_reqs);
        INIT_LIST_HEAD(&target->req_queue);
+       for (i = 0; i < SRP_SQ_SIZE; ++i)
+               list_add_tail(&target->req_ring[i].list, &target->free_reqs);
 
        ret = srp_connect_target(target);
        if (ret)
@@ -589,40 +617,10 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
        return len;
 }
 
-static void srp_unmap_data(struct scsi_cmnd *scmnd,
-                          struct srp_target_port *target,
-                          struct srp_request *req)
-{
-       struct scatterlist *scat;
-       int nents;
-
-       if (!scmnd->request_buffer ||
-           (scmnd->sc_data_direction != DMA_TO_DEVICE &&
-            scmnd->sc_data_direction != DMA_FROM_DEVICE))
-               return;
-
-       /*
-        * This handling of non-SG commands can be killed when the
-        * SCSI midlayer no longer generates non-SG commands.
-        */
-       if (likely(scmnd->use_sg)) {
-               nents = scmnd->use_sg;
-               scat  = scmnd->request_buffer;
-       } else {
-               nents = 1;
-               scat  = &req->fake_sg;
-       }
-
-       dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents,
-                    scmnd->sc_data_direction);
-}
-
-static void srp_remove_req(struct srp_target_port *target, struct srp_request *req,
-                          int index)
+static void srp_remove_req(struct srp_target_port *target, struct srp_request *req)
 {
-       list_del(&req->list);
-       req->next = target->req_head;
-       target->req_head = index;
+       srp_unmap_data(req->scmnd, target, req);
+       list_move_tail(&req->list, &target->free_reqs);
 }
 
 static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
@@ -647,7 +645,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                        req->tsk_status = rsp->data[3];
                complete(&req->done);
        } else {
-               scmnd         = req->scmnd;
+               scmnd = req->scmnd;
                if (!scmnd)
                        printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n",
                               (unsigned long long) rsp->tag);
@@ -665,14 +663,11 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
                        scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);
 
-               srp_unmap_data(scmnd, target, req);
-
                if (!req->tsk_mgmt) {
-                       req->scmnd = NULL;
                        scmnd->host_scribble = (void *) -1L;
                        scmnd->scsi_done(scmnd);
 
-                       srp_remove_req(target, req, rsp->tag & ~SRP_TAG_TSK_MGMT);
+                       srp_remove_req(target, req);
                } else
                        req->cmd_done = 1;
        }
@@ -859,7 +854,6 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
        struct srp_request *req;
        struct srp_iu *iu;
        struct srp_cmd *cmd;
-       long req_index;
        int len;
 
        if (target->state == SRP_TARGET_CONNECTING)
@@ -879,22 +873,20 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
        dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma,
                                SRP_MAX_IU_LEN, DMA_TO_DEVICE);
 
-       req_index = target->req_head;
+       req = list_entry(target->free_reqs.next, struct srp_request, list);
 
        scmnd->scsi_done     = done;
        scmnd->result        = 0;
-       scmnd->host_scribble = (void *) req_index;
+       scmnd->host_scribble = (void *) (long) req->index;
 
        cmd = iu->buf;
        memset(cmd, 0, sizeof *cmd);
 
        cmd->opcode = SRP_CMD;
        cmd->lun    = cpu_to_be64((u64) scmnd->device->lun << 48);
-       cmd->tag    = req_index;
+       cmd->tag    = req->index;
        memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len);
 
-       req = &target->req_ring[req_index];
-
        req->scmnd    = scmnd;
        req->cmd      = iu;
        req->cmd_done = 0;
@@ -919,8 +911,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
                goto err_unmap;
        }
 
-       target->req_head = req->next;
-       list_add_tail(&req->list, &target->req_queue);
+       list_move_tail(&req->list, &target->req_queue);
 
        return 0;
 
@@ -1143,30 +1134,20 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
        return 0;
 }
 
-static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
+static int srp_send_tsk_mgmt(struct srp_target_port *target,
+                            struct srp_request *req, u8 func)
 {
-       struct srp_target_port *target = host_to_target(scmnd->device->host);
-       struct srp_request *req;
        struct srp_iu *iu;
        struct srp_tsk_mgmt *tsk_mgmt;
-       int req_index;
-       int ret = FAILED;
 
        spin_lock_irq(target->scsi_host->host_lock);
 
        if (target->state == SRP_TARGET_DEAD ||
            target->state == SRP_TARGET_REMOVED) {
-               scmnd->result = DID_BAD_TARGET << 16;
+               req->scmnd->result = DID_BAD_TARGET << 16;
                goto out;
        }
 
-       if (scmnd->host_scribble == (void *) -1L)
-               goto out;
-
-       req_index = (long) scmnd->host_scribble;
-       printk(KERN_ERR "Abort for req_index %d\n", req_index);
-
-       req = &target->req_ring[req_index];
        init_completion(&req->done);
 
        iu = __srp_get_tx_iu(target);
@@ -1177,10 +1158,10 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
        memset(tsk_mgmt, 0, sizeof *tsk_mgmt);
 
        tsk_mgmt->opcode        = SRP_TSK_MGMT;
-       tsk_mgmt->lun           = cpu_to_be64((u64) scmnd->device->lun << 48);
-       tsk_mgmt->tag           = req_index | SRP_TAG_TSK_MGMT;
+       tsk_mgmt->lun           = cpu_to_be64((u64) req->scmnd->device->lun << 48);
+       tsk_mgmt->tag           = req->index | SRP_TAG_TSK_MGMT;
        tsk_mgmt->tsk_mgmt_func = func;
-       tsk_mgmt->task_tag      = req_index;
+       tsk_mgmt->task_tag      = req->index;
 
        if (__srp_post_send(target, iu, sizeof *tsk_mgmt))
                goto out;
@@ -1188,37 +1169,85 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
        req->tsk_mgmt = iu;
 
        spin_unlock_irq(target->scsi_host->host_lock);
+
        if (!wait_for_completion_timeout(&req->done,
                                         msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)))
-               return FAILED;
-       spin_lock_irq(target->scsi_host->host_lock);
+               return -1;
 
-       if (req->cmd_done) {
-               srp_remove_req(target, req, req_index);
-               scmnd->scsi_done(scmnd);
-       } else if (!req->tsk_status) {
-               srp_remove_req(target, req, req_index);
-               scmnd->result = DID_ABORT << 16;
-               ret = SUCCESS;
-       }
+       return 0;
 
 out:
        spin_unlock_irq(target->scsi_host->host_lock);
-       return ret;
+       return -1;
+}
+
+static int srp_find_req(struct srp_target_port *target,
+                       struct scsi_cmnd *scmnd,
+                       struct srp_request **req)
+{
+       if (scmnd->host_scribble == (void *) -1L)
+               return -1;
+
+       *req = &target->req_ring[(long) scmnd->host_scribble];
+
+       return 0;
 }
 
 static int srp_abort(struct scsi_cmnd *scmnd)
 {
+       struct srp_target_port *target = host_to_target(scmnd->device->host);
+       struct srp_request *req;
+       int ret = SUCCESS;
+
        printk(KERN_ERR "SRP abort called\n");
 
-       return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK);
+       if (srp_find_req(target, scmnd, &req))
+               return FAILED;
+       if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK))
+               return FAILED;
+
+       spin_lock_irq(target->scsi_host->host_lock);
+
+       if (req->cmd_done) {
+               srp_remove_req(target, req);
+               scmnd->scsi_done(scmnd);
+       } else if (!req->tsk_status) {
+               srp_remove_req(target, req);
+               scmnd->result = DID_ABORT << 16;
+       } else
+               ret = FAILED;
+
+       spin_unlock_irq(target->scsi_host->host_lock);
+
+       return ret;
 }
 
 static int srp_reset_device(struct scsi_cmnd *scmnd)
 {
+       struct srp_target_port *target = host_to_target(scmnd->device->host);
+       struct srp_request *req, *tmp;
+
        printk(KERN_ERR "SRP reset_device called\n");
 
-       return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET);
+       if (srp_find_req(target, scmnd, &req))
+               return FAILED;
+       if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET))
+               return FAILED;
+       if (req->tsk_status)
+               return FAILED;
+
+       spin_lock_irq(target->scsi_host->host_lock);
+
+       list_for_each_entry_safe(req, tmp, &target->req_queue, list)
+               if (req->scmnd->device == scmnd->device) {
+                       req->scmnd->result = DID_RESET << 16;
+                       scmnd->scsi_done(scmnd);
+                       srp_remove_req(target, req);
+               }
+
+       spin_unlock_irq(target->scsi_host->host_lock);
+
+       return SUCCESS;
 }
 
 static int srp_reset_host(struct scsi_cmnd *scmnd)
@@ -1518,10 +1547,12 @@ static ssize_t srp_create_target(struct class_device *class_dev,
 
        INIT_WORK(&target->work, srp_reconnect_work, target);
 
-       for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
-               target->req_ring[i].next = i + 1;
-       target->req_ring[SRP_SQ_SIZE - 1].next = -1;
+       INIT_LIST_HEAD(&target->free_reqs);
        INIT_LIST_HEAD(&target->req_queue);
+       for (i = 0; i < SRP_SQ_SIZE; ++i) {
+               target->req_ring[i].index = i;
+               list_add_tail(&target->req_ring[i].list, &target->free_reqs);
+       }
 
        ret = srp_parse_options(buf, target);
        if (ret)
index bd7f7c3..c5cd43a 100644 (file)
@@ -101,7 +101,7 @@ struct srp_request {
         */
        struct scatterlist      fake_sg;
        struct completion       done;
-       short                   next;
+       short                   index;
        u8                      cmd_done;
        u8                      tsk_status;
 };
@@ -133,7 +133,7 @@ struct srp_target_port {
        unsigned                tx_tail;
        struct srp_iu          *tx_ring[SRP_SQ_SIZE + 1];
 
-       int                     req_head;
+       struct list_head        free_reqs;
        struct list_head        req_queue;
        struct srp_request      req_ring[SRP_SQ_SIZE];
 
index 1042987..5013703 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/irq.h>
+//#include <asm/irq.h>
 
 #include <asm/arch/sharpsl.h>
 #include <asm/arch/hardware.h>
index 9b493f0..173c899 100644 (file)
@@ -1499,7 +1499,6 @@ static int __init capi_init(void)
                printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
                return major_ret;
        }
-       capi_major = major_ret;
        capi_class = class_create(THIS_MODULE, "capi");
        if (IS_ERR(capi_class)) {
                unregister_chrdev(capi_major, "capi20");
index bfb73fd..d86ab68 100644 (file)
@@ -710,8 +710,8 @@ static int gigaset_probe(struct usb_interface *interface,
        retval = -ENODEV; //FIXME
 
        /* See if the device offered us matches what we can accept */
-       if ((le16_to_cpu(udev->descriptor.idVendor  != USB_M105_VENDOR_ID)) ||
-           (le16_to_cpu(udev->descriptor.idProduct != USB_M105_PRODUCT_ID)))
+       if ((le16_to_cpu(udev->descriptor.idVendor)  != USB_M105_VENDOR_ID) ||
+           (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID))
                return -ENODEV;
 
        /* this starts to become ascii art... */
index 3f5b647..6265062 100644 (file)
@@ -4,8 +4,11 @@ menu "LED devices"
 config NEW_LEDS
        bool "LED Support"
        help
-         Say Y to enable Linux LED support.  This is not related to standard
-         keyboard LEDs which are controlled via the input system.
+         Say Y to enable Linux LED support.  This allows control of supported
+         LEDs from both userspace and optionally, by kernel events (triggers).
+
+         This is not related to standard keyboard LEDs which are controlled
+         via the input system.
 
 config LEDS_CLASS
        tristate "LED Class Support"
index b0b5d05..c75d0ef 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sysdev.h>
 #include <linux/timer.h>
 #include <linux/err.h>
+#include <linux/ctype.h>
 #include <linux/leds.h>
 #include "leds.h"
 
@@ -43,9 +44,13 @@ static ssize_t led_brightness_store(struct class_device *dev,
        ssize_t ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
+       size_t count = after - buf;
 
-       if (after - buf > 0) {
-               ret = after - buf;
+       if (*after && isspace(*after))
+               count++;
+
+       if (count == size) {
+               ret = count;
                led_set_brightness(led_cdev, state);
        }
 
index f484b5d..fbf141e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/sysdev.h>
 #include <linux/timer.h>
+#include <linux/ctype.h>
 #include <linux/leds.h>
 #include "leds.h"
 
@@ -69,11 +70,15 @@ static ssize_t led_delay_on_store(struct class_device *dev, const char *buf,
        int ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
+       size_t count = after - buf;
 
-       if (after - buf > 0) {
+       if (*after && isspace(*after))
+               count++;
+
+       if (count == size) {
                timer_data->delay_on = state;
                mod_timer(&timer_data->timer, jiffies + 1);
-               ret = after - buf;
+               ret = count;
        }
 
        return ret;
@@ -97,11 +102,15 @@ static ssize_t led_delay_off_store(struct class_device *dev, const char *buf,
        int ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
+       size_t count = after - buf;
+
+       if (*after && isspace(*after))
+               count++;
 
-       if (after - buf > 0) {
+       if (count == size) {
                timer_data->delay_off = state;
                mod_timer(&timer_data->timer, jiffies + 1);
-               ret = after - buf;
+               ret = count;
        }
 
        return ret;
index 266414c..9080853 100644 (file)
@@ -1189,7 +1189,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        ioc->diagPending = 0;
        spin_lock_init(&ioc->diagLock);
        spin_lock_init(&ioc->fc_rescan_work_lock);
-       spin_lock_init(&ioc->fc_rport_lock);
        spin_lock_init(&ioc->initializing_hba_lock);
 
        /* Initialize the event logging.
@@ -5736,11 +5735,13 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
        return rc;
 }
 
+# define EVENT_DESCR_STR_SZ            100
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static void
 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
 {
-       char *ds;
+       char *ds = NULL;
 
        switch(event) {
        case MPI_EVENT_NONE:
@@ -5777,9 +5778,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
                        ds = "Loop State(LIP) Change";
                else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
-                       ds = "Loop State(LPE) Change";                  /* ??? */
+                       ds = "Loop State(LPE) Change";          /* ??? */
                else
-                       ds = "Loop State(LPB) Change";                  /* ??? */
+                       ds = "Loop State(LPB) Change";          /* ??? */
                break;
        case MPI_EVENT_LOGOUT:
                ds = "Logout";
@@ -5841,27 +5842,32 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                break;
        case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
        {
-               char buf[50];
                u8 id = (u8)(evData0);
                u8 ReasonCode = (u8)(evData0 >> 16);
                switch (ReasonCode) {
                case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
-                       sprintf(buf,"SAS Device Status Change: Added: id=%d", id);
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Added: id=%d", id);
                        break;
                case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
-                       sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id);
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Deleted: id=%d", id);
                        break;
                case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
-                       sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id);
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: SMART Data: id=%d",
+                           id);
                        break;
                case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
-                       sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id);
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: No Persistancy "
+                           "Added: id=%d", id);
                        break;
                default:
-                       sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id);
-               break;
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Unknown: id=%d", id);
+                       break;
                }
-               ds = buf;
                break;
        }
        case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
@@ -5878,41 +5884,46 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                break;
        case MPI_EVENT_SAS_PHY_LINK_STATUS:
        {
-               char buf[50];
                u8 LinkRates = (u8)(evData0 >> 8);
                u8 PhyNumber = (u8)(evData0);
                LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
                        MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
                switch (LinkRates) {
                case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d:"
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d:"
                           " Rate Unknown",PhyNumber);
                        break;
                case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d:"
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d:"
                           " Phy Disabled",PhyNumber);
                        break;
                case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d:"
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d:"
                           " Failed Speed Nego",PhyNumber);
                        break;
                case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d:"
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d:"
                           " Sata OOB Completed",PhyNumber);
                        break;
                case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d:"
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d:"
                           " Rate 1.5 Gbps",PhyNumber);
                        break;
                case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d:"
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d:"
                           " Rate 3.0 Gpbs",PhyNumber);
                        break;
                default:
-                       sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber);
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                          "SAS PHY Link Status: Phy=%d", PhyNumber);
                        break;
                }
-               ds = buf;
                break;
        }
        case MPI_EVENT_SAS_DISCOVERY_ERROR:
@@ -5921,9 +5932,8 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
        case MPI_EVENT_IR_RESYNC_UPDATE:
        {
                u8 resync_complete = (u8)(evData0 >> 16);
-               char buf[40];
-               sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete);
-               ds = buf;
+               snprintf(evStr, EVENT_DESCR_STR_SZ,
+                   "IR Resync Update: Complete = %d:",resync_complete);
                break;
        }
        case MPI_EVENT_IR2:
@@ -5976,7 +5986,8 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                ds = "Unknown";
                break;
        }
-       strcpy(evStr,ds);
+       if (ds)
+               strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5998,7 +6009,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
        int ii;
        int r = 0;
        int handlers = 0;
-       char evStr[100];
+       char evStr[EVENT_DESCR_STR_SZ];
        u8 event;
 
        /*
index be7e850..f673cca 100644 (file)
@@ -76,8 +76,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.03.08"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.03.08"
+#define MPT_LINUX_VERSION_COMMON       "3.03.09"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.03.09"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -489,7 +489,6 @@ typedef     struct _RaidCfgData {
 
 #define MPT_RPORT_INFO_FLAGS_REGISTERED        0x01    /* rport registered */
 #define MPT_RPORT_INFO_FLAGS_MISSING   0x02    /* missing from DevPage0 scan */
-#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04  /* target mapped in vdev */
 
 /*
  * data allocated for each fc rport device
@@ -501,7 +500,6 @@ struct mptfc_rport_info
        struct scsi_target *starget;
        FCDevicePage0_t pg0;
        u8              flags;
-       u8              remap_needed;
 };
 
 /*
@@ -628,11 +626,11 @@ typedef struct _MPT_ADAPTER
        struct work_struct       mptscsih_persistTask;
 
        struct list_head         fc_rports;
-       spinlock_t               fc_rport_lock; /* list and ri flags */
        spinlock_t               fc_rescan_work_lock;
        int                      fc_rescan_work_count;
        struct work_struct       fc_rescan_work;
-
+       char                     fc_rescan_work_q_name[KOBJ_NAME_LEN];
+       struct workqueue_struct *fc_rescan_work_q;
 } MPT_ADAPTER;
 
 /*
index b343f2a..8564877 100644 (file)
@@ -341,9 +341,6 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
        rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
        rid->port_id =   pg0->PortIdentifier;
        rid->roles = FC_RPORT_ROLE_UNKNOWN;
-       rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
-       if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
-               rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 
        return 0;
 }
@@ -355,15 +352,18 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
        struct fc_rport         *rport;
        struct mptfc_rport_info *ri;
        int                     new_ri = 1;
-       u64                     pn;
-       unsigned long           flags;
+       u64                     pn, nn;
        VirtTarget              *vtarget;
+       u32                     roles = FC_RPORT_ROLE_UNKNOWN;
 
        if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
                return;
 
+       roles |= FC_RPORT_ROLE_FCP_TARGET;
+       if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
+               roles |= FC_RPORT_ROLE_FCP_INITIATOR;
+
        /* scan list looking for a match */
-       spin_lock_irqsave(&ioc->fc_rport_lock, flags);
        list_for_each_entry(ri, &ioc->fc_rports, list) {
                pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
                if (pn == rport_ids.port_name) {        /* match */
@@ -373,11 +373,9 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
                }
        }
        if (new_ri) {   /* allocate one */
-               spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
                ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
                if (!ri)
                        return;
-               spin_lock_irqsave(&ioc->fc_rport_lock, flags);
                list_add_tail(&ri->list, &ioc->fc_rports);
        }
 
@@ -387,14 +385,11 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
        /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
        if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
                ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
-               spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
                rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
-               spin_lock_irqsave(&ioc->fc_rport_lock, flags);
                if (rport) {
                        ri->rport = rport;
                        if (new_ri) /* may have been reset by user */
                                rport->dev_loss_tmo = mptfc_dev_loss_tmo;
-                       *((struct mptfc_rport_info **)rport->dd_data) = ri;
                        /*
                         * if already mapped, remap here.  If not mapped,
                         * target_alloc will allocate vtarget and map,
@@ -406,16 +401,21 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
                                        vtarget->target_id = pg0->CurrentTargetID;
                                        vtarget->bus_id = pg0->CurrentBus;
                                }
-                               ri->remap_needed = 0;
                        }
+                       *((struct mptfc_rport_info **)rport->dd_data) = ri;
+                       /* scan will be scheduled once rport becomes a target */
+                       fc_remote_port_rolechg(rport,roles);
+
+                       pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
+                       nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
                        dfcprintk ((MYIOC_s_INFO_FMT
                                "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
                                "rport tid %d, tmo %d\n",
                                        ioc->name,
                                        ioc->sh->host_no,
                                        pg0->PortIdentifier,
-                                       pg0->WWNN,
-                                       pg0->WWPN,
+                                       (unsigned long long)nn,
+                                       (unsigned long long)pn,
                                        pg0->CurrentTargetID,
                                        ri->rport->scsi_target_id,
                                        ri->rport->dev_loss_tmo));
@@ -425,8 +425,6 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
                        ri = NULL;
                }
        }
-       spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
-
 }
 
 /*
@@ -476,7 +474,6 @@ mptfc_target_alloc(struct scsi_target *starget)
                        vtarget->target_id = ri->pg0.CurrentTargetID;
                        vtarget->bus_id = ri->pg0.CurrentBus;
                        ri->starget = starget;
-                       ri->remap_needed = 0;
                        rc = 0;
                }
        }
@@ -502,10 +499,10 @@ mptfc_slave_alloc(struct scsi_device *sdev)
        VirtDevice              *vdev;
        struct scsi_target      *starget;
        struct fc_rport         *rport;
-       unsigned long           flags;
 
 
-       rport = starget_to_rport(scsi_target(sdev));
+       starget = scsi_target(sdev);
+       rport = starget_to_rport(starget);
 
        if (!rport || fc_remote_port_chkready(rport))
                return -ENXIO;
@@ -519,10 +516,8 @@ mptfc_slave_alloc(struct scsi_device *sdev)
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
 
        sdev->hostdata = vdev;
-       starget = scsi_target(sdev);
        vtarget = starget->hostdata;
 
        if (vtarget->num_luns == 0) {
@@ -535,14 +530,16 @@ mptfc_slave_alloc(struct scsi_device *sdev)
        vdev->vtarget = vtarget;
        vdev->lun = sdev->lun;
 
-       spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
-
        vtarget->num_luns++;
 
+
 #ifdef DMPT_DEBUG_FC
-        {
+       {
+       u64 nn, pn;
        struct mptfc_rport_info *ri;
        ri = *((struct mptfc_rport_info **)rport->dd_data);
+       pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
+       nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
        dfcprintk ((MYIOC_s_INFO_FMT
                "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
                "CurrentTargetID %d, %x %llx %llx\n",
@@ -550,7 +547,9 @@ mptfc_slave_alloc(struct scsi_device *sdev)
                sdev->host->host_no,
                vtarget->num_luns,
                sdev->id, ri->pg0.CurrentTargetID,
-               ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
+               ri->pg0.PortIdentifier,
+               (unsigned long long)pn,
+               (unsigned long long)nn));
        }
 #endif
 
@@ -570,11 +569,31 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
                done(SCpnt);
                return 0;
        }
+
+       /* dd_data is null until finished adding target */
        ri = *((struct mptfc_rport_info **)rport->dd_data);
-       if (unlikely(ri->remap_needed))
-               return SCSI_MLQUEUE_HOST_BUSY;
+       if (unlikely(!ri)) {
+               dfcprintk ((MYIOC_s_INFO_FMT
+                       "mptfc_qcmd.%d: %d:%d, dd_data is null.\n",
+                       ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
+                       ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
+                       SCpnt->device->id,SCpnt->device->lun));
+               SCpnt->result = DID_IMM_RETRY << 16;
+               done(SCpnt);
+               return 0;
+       }
 
-       return mptscsih_qcmd(SCpnt,done);
+       err = mptscsih_qcmd(SCpnt,done);
+#ifdef DMPT_DEBUG_FC
+       if (unlikely(err)) {
+               dfcprintk ((MYIOC_s_INFO_FMT
+                       "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n",
+                       ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
+                       ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
+                       SCpnt->device->id,SCpnt->device->lun));
+       }
+#endif
+       return err;
 }
 
 static void
@@ -615,18 +634,17 @@ mptfc_rescan_devices(void *arg)
        MPT_ADAPTER             *ioc = (MPT_ADAPTER *)arg;
        int                     ii;
        int                     work_to_do;
+       u64                     pn;
        unsigned long           flags;
        struct mptfc_rport_info *ri;
 
        do {
                /* start by tagging all ports as missing */
-               spin_lock_irqsave(&ioc->fc_rport_lock,flags);
                list_for_each_entry(ri, &ioc->fc_rports, list) {
                        if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
                                ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
                        }
                }
-               spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
 
                /*
                 * now rescan devices known to adapter,
@@ -639,33 +657,24 @@ mptfc_rescan_devices(void *arg)
                }
 
                /* delete devices still missing */
-               spin_lock_irqsave(&ioc->fc_rport_lock, flags);
                list_for_each_entry(ri, &ioc->fc_rports, list) {
                        /* if newly missing, delete it */
-                       if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
-                                         MPT_RPORT_INFO_FLAGS_MISSING))
-                         == (MPT_RPORT_INFO_FLAGS_REGISTERED |
-                             MPT_RPORT_INFO_FLAGS_MISSING)) {
+                       if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
 
                                ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
                                               MPT_RPORT_INFO_FLAGS_MISSING);
-                               ri->remap_needed = 1;
-                               fc_remote_port_delete(ri->rport);
-                               /*
-                                * remote port not really deleted 'cause
-                                * binding is by WWPN and driver only
-                                * registers FCP_TARGETs but cannot trust
-                                * data structures.
-                                */
+                               fc_remote_port_delete(ri->rport);       /* won't sleep */
                                ri->rport = NULL;
+
+                               pn = (u64)ri->pg0.WWPN.High << 32 |
+                                    (u64)ri->pg0.WWPN.Low;
                                dfcprintk ((MYIOC_s_INFO_FMT
                                        "mptfc_rescan.%d: %llx deleted\n",
                                        ioc->name,
                                        ioc->sh->host_no,
-                                       ri->pg0.WWPN));
+                                       (unsigned long long)pn));
                        }
                }
-               spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
 
                /*
                 * allow multiple passes as target state
@@ -870,10 +879,23 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto out_mptfc_probe;
        }
 
-       for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
-               mptfc_init_host_attr(ioc,ii);
-               mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
-       }
+       /* initialize workqueue */
+
+       snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
+               sh->host_no);
+       ioc->fc_rescan_work_q =
+               create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
+       if (!ioc->fc_rescan_work_q)
+               goto out_mptfc_probe;
+
+       /*
+        * scan for rports -
+        *      by doing it via the workqueue, some locking is eliminated
+        */
+
+       ioc->fc_rescan_work_count = 1;
+       queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
+       flush_workqueue(ioc->fc_rescan_work_q);
 
        return 0;
 
@@ -949,8 +971,18 @@ mptfc_init(void)
 static void __devexit
 mptfc_remove(struct pci_dev *pdev)
 {
-       MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
-       struct mptfc_rport_info *p, *n;
+       MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
+       struct mptfc_rport_info *p, *n;
+       struct workqueue_struct *work_q;
+       unsigned long           flags;
+
+       /* destroy workqueue */
+       if ((work_q=ioc->fc_rescan_work_q)) {
+               spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
+               ioc->fc_rescan_work_q = NULL;
+               spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
+               destroy_workqueue(work_q);
+       }
 
        fc_remove_host(ioc->sh);
 
index e9716b1..af6ec55 100644 (file)
@@ -91,6 +91,7 @@ enum mptsas_hotplug_action {
        MPTSAS_DEL_DEVICE,
        MPTSAS_ADD_RAID,
        MPTSAS_DEL_RAID,
+       MPTSAS_IGNORE_EVENT,
 };
 
 struct mptsas_hotplug_event {
@@ -298,6 +299,26 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
        return rc;
 }
 
+/*
+ * Returns true if there is a scsi end device
+ */
+static inline int
+mptsas_is_end_device(struct mptsas_devinfo * attached)
+{
+       if ((attached->handle) &&
+           (attached->device_info &
+           MPI_SAS_DEVICE_INFO_END_DEVICE) &&
+           ((attached->device_info &
+           MPI_SAS_DEVICE_INFO_SSP_TARGET) |
+           (attached->device_info &
+           MPI_SAS_DEVICE_INFO_STP_TARGET) |
+           (attached->device_info &
+           MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
+               return 1;
+       else
+               return 0;
+}
+
 static int
 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
                u32 form, u32 form_specific)
@@ -872,7 +893,11 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
        SasDevicePage0_t *buffer;
        dma_addr_t dma_handle;
        __le64 sas_address;
-       int error;
+       int error=0;
+
+       if (ioc->sas_discovery_runtime &&
+               mptsas_is_end_device(device_info))
+                       goto out;
 
        hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
        hdr.ExtPageLength = 0;
@@ -1009,7 +1034,11 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
        CONFIGPARMS cfg;
        SasExpanderPage1_t *buffer;
        dma_addr_t dma_handle;
-       int error;
+       int error=0;
+
+       if (ioc->sas_discovery_runtime &&
+               mptsas_is_end_device(&phy_info->attached))
+                       goto out;
 
        hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
        hdr.ExtPageLength = 0;
@@ -1068,26 +1097,6 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
        return error;
 }
 
-/*
- * Returns true if there is a scsi end device
- */
-static inline int
-mptsas_is_end_device(struct mptsas_devinfo * attached)
-{
-       if ((attached->handle) &&
-           (attached->device_info &
-           MPI_SAS_DEVICE_INFO_END_DEVICE) &&
-           ((attached->device_info &
-           MPI_SAS_DEVICE_INFO_SSP_TARGET) |
-           (attached->device_info &
-           MPI_SAS_DEVICE_INFO_STP_TARGET) |
-           (attached->device_info &
-           MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
-               return 1;
-       else
-               return 0;
-}
-
 static void
 mptsas_parse_device_info(struct sas_identify *identify,
                struct mptsas_devinfo *device_info)
@@ -1737,6 +1746,9 @@ mptsas_hotplug_work(void *arg)
                break;
        case MPTSAS_ADD_DEVICE:
 
+               if (ev->phys_disk_num_valid)
+                       mpt_findImVolumes(ioc);
+
                /*
                 * Refresh sas device pg0 data
                 */
@@ -1868,6 +1880,9 @@ mptsas_hotplug_work(void *arg)
                scsi_device_put(sdev);
                mpt_findImVolumes(ioc);
                break;
+       case MPTSAS_IGNORE_EVENT:
+       default:
+               break;
        }
 
        kfree(ev);
@@ -1940,7 +1955,8 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
                EVENT_DATA_RAID *raid_event_data)
 {
        struct mptsas_hotplug_event *ev;
-       RAID_VOL0_STATUS * volumeStatus;
+       int status = le32_to_cpu(raid_event_data->SettingsStatus);
+       int state = (status >> 8) & 0xff;
 
        if (ioc->bus_type != SAS)
                return;
@@ -1955,6 +1971,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
        INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
        ev->ioc = ioc;
        ev->id = raid_event_data->VolumeID;
+       ev->event_type = MPTSAS_IGNORE_EVENT;
 
        switch (raid_event_data->ReasonCode) {
        case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
@@ -1966,6 +1983,25 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
                ev->phys_disk_num = raid_event_data->PhysDiskNum;
                ev->event_type = MPTSAS_DEL_DEVICE;
                break;
+       case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
+               switch (state) {
+               case MPI_PD_STATE_ONLINE:
+                       ioc->raid_data.isRaid = 1;
+                       ev->phys_disk_num_valid = 1;
+                       ev->phys_disk_num = raid_event_data->PhysDiskNum;
+                       ev->event_type = MPTSAS_ADD_DEVICE;
+                       break;
+               case MPI_PD_STATE_MISSING:
+               case MPI_PD_STATE_NOT_COMPATIBLE:
+               case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
+               case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
+               case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
+                       ev->event_type = MPTSAS_DEL_DEVICE;
+                       break;
+               default:
+                       break;
+               }
+               break;
        case MPI_EVENT_RAID_RC_VOLUME_DELETED:
                ev->event_type = MPTSAS_DEL_RAID;
                break;
@@ -1973,11 +2009,18 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
                ev->event_type = MPTSAS_ADD_RAID;
                break;
        case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
-               volumeStatus = (RAID_VOL0_STATUS *) &
-                   raid_event_data->SettingsStatus;
-               ev->event_type = (volumeStatus->State ==
-                   MPI_RAIDVOL0_STATUS_STATE_FAILED) ?
-                   MPTSAS_DEL_RAID : MPTSAS_ADD_RAID;
+               switch (state) {
+               case MPI_RAIDVOL0_STATUS_STATE_FAILED:
+               case MPI_RAIDVOL0_STATUS_STATE_MISSING:
+                       ev->event_type = MPTSAS_DEL_RAID;
+                       break;
+               case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
+               case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
+                       ev->event_type = MPTSAS_ADD_RAID;
+                       break;
+               default:
+                       break;
+               }
                break;
        default:
                break;
index 3729062..84fa271 100644 (file)
@@ -632,7 +632,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 
                case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
                        /* Spoof to SCSI Selection Timeout! */
-                       sc->result = DID_NO_CONNECT << 16;
+                       if (ioc->bus_type != FC)
+                               sc->result = DID_NO_CONNECT << 16;
+                       /* else fibre, just stall until rescan event */
+                       else
+                               sc->result = DID_REQUEUE << 16;
 
                        if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
                                hd->sel_timeout[pScsiReq->TargetID]++;
@@ -877,7 +881,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
        struct scsi_cmnd *sc;
 
        dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
-                       vdevice->target_id, vdevice->lun, max));
+                       vdevice->vtarget->target_id, vdevice->lun, max));
 
        for (ii=0; ii < max; ii++) {
                if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -1645,7 +1649,6 @@ int
 mptscsih_abort(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
-       MPT_ADAPTER     *ioc;
        MPT_FRAME_HDR   *mf;
        u32              ctx2abort;
        int              scpnt_idx;
@@ -1663,14 +1666,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
                return FAILED;
        }
 
-       ioc = hd->ioc;
-       if (hd->resetPending) {
-               return FAILED;
-       }
-
-       if (hd->timeouts < -1)
-               hd->timeouts++;
-
        /* Find this command
         */
        if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
@@ -1684,6 +1679,13 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
                return SUCCESS;
        }
 
+       if (hd->resetPending) {
+               return FAILED;
+       }
+
+       if (hd->timeouts < -1)
+               hd->timeouts++;
+
        printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
               hd->ioc->name, SCpnt);
        scsi_print_command(SCpnt);
@@ -1703,7 +1705,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
        vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
                vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
-               ctx2abort, mptscsih_get_tm_timeout(ioc));
+               ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
 
        printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
                hd->ioc->name,
@@ -2521,15 +2523,15 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 
                /* 7. FC: Rescan for blocked rports which might have returned.
                 */
-               else if (ioc->bus_type == FC) {
-                       int work_count;
-                       unsigned long flags;
-
+               if (ioc->bus_type == FC) {
                        spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
-                       work_count = ++ioc->fc_rescan_work_count;
+                       if (ioc->fc_rescan_work_q) {
+                               if (ioc->fc_rescan_work_count++ == 0) {
+                                       queue_work(ioc->fc_rescan_work_q,
+                                                  &ioc->fc_rescan_work);
+                               }
+                       }
                        spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
-                       if (work_count == 1)
-                               schedule_work(&ioc->fc_rescan_work);
                }
                dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
 
@@ -2544,7 +2546,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
        MPT_SCSI_HOST *hd;
        u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
-       int work_count;
        unsigned long flags;
 
        devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
@@ -2569,10 +2570,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 
        case MPI_EVENT_RESCAN:                          /* 06 */
                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
-               work_count = ++ioc->fc_rescan_work_count;
+               if (ioc->fc_rescan_work_q) {
+                       if (ioc->fc_rescan_work_count++ == 0) {
+                               queue_work(ioc->fc_rescan_work_q,
+                                          &ioc->fc_rescan_work);
+                       }
+               }
                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
-               if (work_count == 1)
-                       schedule_work(&ioc->fc_rescan_work);
                break;
 
                /*
index 09c745b..f2a4d38 100644 (file)
@@ -783,6 +783,70 @@ static struct pci_device_id mptspi_pci_table[] = {
 };
 MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
 
+
+/*
+ * renegotiate for a given target
+ */
+static void
+mptspi_dv_renegotiate_work(void *data)
+{
+       struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
+       struct _MPT_SCSI_HOST *hd = wqw->hd;
+       struct scsi_device *sdev;
+
+       kfree(wqw);
+
+       shost_for_each_device(sdev, hd->ioc->sh)
+               mptspi_dv_device(hd, sdev);
+}
+
+static void
+mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd)
+{
+       struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
+
+       if (!wqw)
+               return;
+
+       INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw);
+       wqw->hd = hd;
+
+       schedule_work(&wqw->work);
+}
+
+/*
+ * spi module reset handler
+ */
+static int
+mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+       struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
+       int rc;
+
+       rc = mptscsih_ioc_reset(ioc, reset_phase);
+
+       if (reset_phase == MPT_IOC_POST_RESET)
+               mptspi_dv_renegotiate(hd);
+
+       return rc;
+}
+
+/*
+ * spi module resume handler
+ */
+static int
+mptspi_resume(struct pci_dev *pdev)
+{
+       MPT_ADAPTER     *ioc = pci_get_drvdata(pdev);
+       struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
+       int rc;
+
+       rc = mptscsih_resume(pdev);
+       mptspi_dv_renegotiate(hd);
+
+       return rc;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -1032,7 +1096,7 @@ static struct pci_driver mptspi_driver = {
        .shutdown       = mptscsih_shutdown,
 #ifdef CONFIG_PM
        .suspend        = mptscsih_suspend,
-       .resume         = mptscsih_resume,
+       .resume         = mptspi_resume,
 #endif
 };
 
@@ -1061,7 +1125,7 @@ mptspi_init(void)
                  ": Registered for IOC event notifications\n"));
        }
 
-       if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) {
+       if (mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset) == 0) {
                dprintk((KERN_INFO MYNAM
                  ": Registered for IOC reset notifications\n"));
        }
index 6061c2d..88f0eef 100644 (file)
@@ -621,9 +621,6 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct at91mci_host *host = mmc_priv(mmc);
        unsigned long at91_master_clock = clk_get_rate(mci_clk);
 
-       DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n",
-               ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
-
        if (host)
                host->bus_mode = ios->bus_mode;
        else
index c0326bb..914d62b 100644 (file)
@@ -720,10 +720,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
 {
        struct au1xmmc_host *host = mmc_priv(mmc);
 
-       DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",
-             host->id, ios->power_mode, ios->clock, ios->vdd,
-             ios->bus_mode);
-
        if (ios->power_mode == MMC_POWER_OFF)
                au1xmmc_set_power(host, 0);
        else if (ios->power_mode == MMC_POWER_ON) {
index ffb7f55..79358e2 100644 (file)
@@ -102,6 +102,7 @@ struct imxmci_host {
 #define IMXMCI_PEND_CPU_DATA_b 5
 #define IMXMCI_PEND_CARD_XCHG_b        6
 #define IMXMCI_PEND_SET_INIT_b 7
+#define IMXMCI_PEND_STARTED_b  8
 
 #define IMXMCI_PEND_IRQ_m      (1 << IMXMCI_PEND_IRQ_b)
 #define IMXMCI_PEND_DMA_END_m  (1 << IMXMCI_PEND_DMA_END_b)
@@ -111,6 +112,7 @@ struct imxmci_host {
 #define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b)
 #define IMXMCI_PEND_CARD_XCHG_m        (1 << IMXMCI_PEND_CARD_XCHG_b)
 #define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b)
+#define IMXMCI_PEND_STARTED_m  (1 << IMXMCI_PEND_STARTED_b)
 
 static void imxmci_stop_clock(struct imxmci_host *host)
 {
@@ -131,23 +133,52 @@ static void imxmci_stop_clock(struct imxmci_host *host)
        dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n");
 }
 
-static void imxmci_start_clock(struct imxmci_host *host)
+static int imxmci_start_clock(struct imxmci_host *host)
 {
-       int i = 0;
+       unsigned int trials = 0;
+       unsigned int delay_limit = 128;
+       unsigned long flags;
+
        MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK;
-       while(i < 0x1000) {
-               if(!(i & 0x7f))
-                       MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;
 
-               if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) {
-                       /* Check twice before cut */
+       clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events);
+
+       /*
+        * Command start of the clock, this usually succeeds in less
+        * then 6 delay loops, but during card detection (low clockrate)
+        * it takes up to 5000 delay loops and sometimes fails for the first time
+        */
+       MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;
+
+       do {
+               unsigned int delay = delay_limit;
+
+               while(delay--){
                        if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)
-                               return;
+                               /* Check twice before cut */
+                               if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)
+                                       return 0;
+
+                       if(test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events))
+                               return 0;
                }
 
-               i++;
-       }
-       dev_dbg(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");
+               local_irq_save(flags);
+               /*
+                * Ensure, that request is not doubled under all possible circumstances.
+                * It is possible, that cock running state is missed, because some other
+                * IRQ or schedule delays this function execution and the clocks has
+                * been already stopped by other means (response processing, SDHC HW)
+                */
+               if(!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events))
+                       MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;
+               local_irq_restore(flags);
+
+       } while(++trials<256);
+
+       dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");
+
+       return -1;
 }
 
 static void imxmci_softreset(void)
@@ -498,7 +529,7 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat)
 
        data_error = imxmci_finish_data(host, stat);
 
-       if (host->req->stop && (data_error == MMC_ERR_NONE)) {
+       if (host->req->stop) {
                imxmci_stop_clock(host);
                imxmci_start_cmd(host, host->req->stop, 0);
        } else {
@@ -622,6 +653,7 @@ static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs)
        atomic_set(&host->stuck_timeout, 0);
        host->status_reg = stat;
        set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);
+       set_bit(IMXMCI_PEND_STARTED_b, &host->pending_events);
        tasklet_schedule(&host->tasklet);
 
        return IRQ_RETVAL(handled);;
@@ -775,10 +807,6 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct imxmci_host *host = mmc_priv(mmc);
        int prescaler;
 
-       dev_dbg(mmc_dev(host->mmc), "clock %u power %u vdd %u width %u\n",
-               ios->clock, ios->power_mode, ios->vdd,
-               (ios->bus_width==MMC_BUS_WIDTH_4)?4:1);
-
        if( ios->bus_width==MMC_BUS_WIDTH_4 ) {
                host->actual_bus_width = MMC_BUS_WIDTH_4;
                imx_gpio_mode(PB11_PF_SD_DAT3);
index da6ddd9..1ca2c8b 100644 (file)
@@ -59,21 +59,23 @@ static const unsigned int tacc_mant[] = {
 
 
 /**
- *     mmc_request_done - finish processing an MMC command
- *     @host: MMC host which completed command
- *     @mrq: MMC request which completed
+ *     mmc_request_done - finish processing an MMC request
+ *     @host: MMC host which completed request
+ *     @mrq: MMC request which request
  *
  *     MMC drivers should call this function when they have completed
- *     their processing of a command.  This should be called before the
- *     data part of the command has completed.
+ *     their processing of a request.
  */
 void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 {
        struct mmc_command *cmd = mrq->cmd;
-       int err = mrq->cmd->error;
-       pr_debug("MMC: req done (%02x): %d: %08x %08x %08x %08x\n",
-                cmd->opcode, err, cmd->resp[0], cmd->resp[1],
-                cmd->resp[2], cmd->resp[3]);
+       int err = cmd->error;
+
+       pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n",
+                mmc_hostname(host), cmd->opcode, err,
+                mrq->data ? mrq->data->error : 0,
+                mrq->stop ? mrq->stop->error : 0,
+                cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
 
        if (err && cmd->retries) {
                cmd->retries--;
@@ -97,8 +99,9 @@ EXPORT_SYMBOL(mmc_request_done);
 void
 mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 {
-       pr_debug("MMC: starting cmd %02x arg %08x flags %08x\n",
-                mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags);
+       pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
+                mmc_hostname(host), mrq->cmd->opcode,
+                mrq->cmd->arg, mrq->cmd->flags);
 
        WARN_ON(host->card_busy == NULL);
 
@@ -312,6 +315,18 @@ void mmc_release_host(struct mmc_host *host)
 
 EXPORT_SYMBOL(mmc_release_host);
 
+static inline void mmc_set_ios(struct mmc_host *host)
+{
+       struct mmc_ios *ios = &host->ios;
+
+       pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
+                mmc_hostname(host), ios->clock, ios->bus_mode,
+                ios->power_mode, ios->chip_select, ios->vdd,
+                ios->bus_width);
+       
+       host->ops->set_ios(host, ios);
+}
+
 static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 {
        int err;
@@ -364,7 +379,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
                }
        }
 
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 
        return MMC_ERR_NONE;
 }
@@ -415,7 +430,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
                ocr = 3 << bit;
 
                host->ios.vdd = bit;
-               host->ops->set_ios(host, &host->ios);
+               mmc_set_ios(host);
        } else {
                ocr = 0;
        }
@@ -549,6 +564,7 @@ static void mmc_decode_csd(struct mmc_card *card)
                csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
                csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
                csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+               csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
                csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
                csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
        } else {
@@ -583,6 +599,7 @@ static void mmc_decode_csd(struct mmc_card *card)
                csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
                csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
                csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+               csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
                csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
                csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
        }
@@ -666,7 +683,7 @@ static void mmc_idle_cards(struct mmc_host *host)
        struct mmc_command cmd;
 
        host->ios.chip_select = MMC_CS_HIGH;
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 
        mmc_delay(1);
 
@@ -679,7 +696,7 @@ static void mmc_idle_cards(struct mmc_host *host)
        mmc_delay(1);
 
        host->ios.chip_select = MMC_CS_DONTCARE;
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 
        mmc_delay(1);
 }
@@ -704,13 +721,13 @@ static void mmc_power_up(struct mmc_host *host)
        host->ios.chip_select = MMC_CS_DONTCARE;
        host->ios.power_mode = MMC_POWER_UP;
        host->ios.bus_width = MMC_BUS_WIDTH_1;
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 
        mmc_delay(1);
 
        host->ios.clock = host->f_min;
        host->ios.power_mode = MMC_POWER_ON;
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 
        mmc_delay(2);
 }
@@ -723,7 +740,7 @@ static void mmc_power_off(struct mmc_host *host)
        host->ios.chip_select = MMC_CS_DONTCARE;
        host->ios.power_mode = MMC_POWER_OFF;
        host->ios.bus_width = MMC_BUS_WIDTH_1;
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 }
 
 static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
@@ -971,7 +988,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host)
                if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
                        max_dtr = card->csd.max_dtr;
 
-       pr_debug("MMC: selected %d.%03dMHz transfer rate\n",
+       pr_debug("%s: selected %d.%03dMHz transfer rate\n",
+                mmc_hostname(host),
                 max_dtr / 1000000, (max_dtr / 1000) % 1000);
 
        return max_dtr;
@@ -1046,7 +1064,7 @@ static void mmc_setup(struct mmc_host *host)
        } else {
                host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
                host->ios.clock = host->f_min;
-               host->ops->set_ios(host, &host->ios);
+               mmc_set_ios(host);
 
                /*
                 * We should remember the OCR mask from the existing
@@ -1082,7 +1100,7 @@ static void mmc_setup(struct mmc_host *host)
         * Ok, now switch to push-pull mode.
         */
        host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
-       host->ops->set_ios(host, &host->ios);
+       mmc_set_ios(host);
 
        mmc_read_csds(host);
 
@@ -1128,7 +1146,7 @@ static void mmc_rescan(void *data)
                 * attached cards and the host support.
                 */
                host->ios.clock = mmc_calculate_clock(host);
-               host->ops->set_ios(host, &host->ios);
+               mmc_set_ios(host);
        }
 
        mmc_release_host(host);
index 8eb2a2e..06bd1f4 100644 (file)
@@ -187,6 +187,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        brq.cmd.opcode = MMC_WRITE_BLOCK;
                        brq.data.flags |= MMC_DATA_WRITE;
                        brq.data.blocks = 1;
+
+                       /*
+                        * Scale up the timeout by the r2w factor
+                        */
+                       brq.data.timeout_ns <<= card->csd.r2w_factor;
+                       brq.data.timeout_clks <<= card->csd.r2w_factor;
                }
 
                if (brq.data.blocks > 1) {
index df7e861..da8e4d7 100644 (file)
@@ -402,9 +402,6 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct mmci_host *host = mmc_priv(mmc);
        u32 clk = 0, pwr = 0;
 
-       DBG(host, "clock %uHz busmode %u powermode %u Vdd %u\n",
-           ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
-
        if (ios->clock) {
                if (ios->clock >= host->mclk) {
                        clk = MCI_CLK_BYPASS;
index eb42cb3..f97b472 100644 (file)
@@ -198,7 +198,6 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd,
 
 static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq)
 {
-       pr_debug("PXAMCI: request done\n");
        host->mrq = NULL;
        host->cmd = NULL;
        host->data = NULL;
@@ -291,7 +290,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
        pxamci_disable_irq(host, DATA_TRAN_DONE);
 
        host->data = NULL;
-       if (host->mrq->stop && data->error == MMC_ERR_NONE) {
+       if (host->mrq->stop) {
                pxamci_stop_clock(host);
                pxamci_start_cmd(host, host->mrq->stop, 0);
        } else {
@@ -309,12 +308,10 @@ static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs)
 
        ireg = readl(host->base + MMC_I_REG);
 
-       pr_debug("PXAMCI: irq %08x\n", ireg);
-
        if (ireg) {
                unsigned stat = readl(host->base + MMC_STAT);
 
-               pr_debug("PXAMCI: stat %08x\n", stat);
+               pr_debug("PXAMCI: irq %08x stat %08x\n", ireg, stat);
 
                if (ireg & END_CMD_RES)
                        handled |= pxamci_cmd_done(host, stat);
@@ -368,10 +365,6 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct pxamci_host *host = mmc_priv(mmc);
 
-       pr_debug("pxamci_set_ios: clock %u power %u vdd %u.%02u\n",
-                ios->clock, ios->power_mode, ios->vdd / 100,
-                ios->vdd % 100);
-
        if (ios->clock) {
                unsigned int clk = CLOCKRATE / ios->clock;
                if (CLOCKRATE / clk > ios->clock)
@@ -397,7 +390,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        host->cmdat |= CMDAT_INIT;
        }
 
-       pr_debug("pxamci_set_ios: clkrt = %x cmdat = %x\n",
+       pr_debug("PXAMCI: clkrt = %x cmdat = %x\n",
                 host->clkrt, host->cmdat);
 }
 
index bdbfca0..b005328 100644 (file)
@@ -570,10 +570,6 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        spin_lock_irqsave(&host->lock, flags);
 
-       DBG("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
-            ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
-            ios->vdd, ios->bus_width);
-
        /*
         * Reset the chip on each power off.
         * Should clear out any weird states.
index 511f7b0..39b3d97 100644 (file)
@@ -931,10 +931,6 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct wbsd_host *host = mmc_priv(mmc);
        u8 clk, setup, pwr;
 
-       DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
-               ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
-               ios->vdd, ios->bus_width);
-
        spin_lock_bh(&host->lock);
 
        /*
index fe00af3..d0d5e52 100644 (file)
@@ -399,7 +399,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
        for (i=0; i< cfi->numchips; i++) {
                cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
                cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
-               cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
+               cfi->chips[i].erase_time = 1000<<cfi->cfiq->BlockEraseTimeoutTyp;
                cfi->chips[i].ref_point_counter = 0;
                init_waitqueue_head(&(cfi->chips[i].wq));
        }
@@ -894,26 +894,33 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
 
 /*
  * When a delay is required for the flash operation to complete, the
- * xip_udelay() function is polling for both the given timeout and pending
- * (but still masked) hardware interrupts.  Whenever there is an interrupt
- * pending then the flash erase or write operation is suspended, array mode
- * restored and interrupts unmasked.  Task scheduling might also happen at that
- * point.  The CPU eventually returns from the interrupt or the call to
- * schedule() and the suspended flash operation is resumed for the remaining
- * of the delay period.
+ * xip_wait_for_operation() function is polling for both the given timeout
+ * and pending (but still masked) hardware interrupts.  Whenever there is an
+ * interrupt pending then the flash erase or write operation is suspended,
+ * array mode restored and interrupts unmasked.  Task scheduling might also
+ * happen at that point.  The CPU eventually returns from the interrupt or
+ * the call to schedule() and the suspended flash operation is resumed for
+ * the remaining of the delay period.
  *
  * Warning: this function _will_ fool interrupt latency tracing tools.
  */
 
-static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
-                               unsigned long adr, int usec)
+static int __xipram xip_wait_for_operation(
+               struct map_info *map, struct flchip *chip,
+               unsigned long adr, int *chip_op_time )
 {
        struct cfi_private *cfi = map->fldrv_priv;
        struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
        map_word status, OK = CMD(0x80);
-       unsigned long suspended, start = xip_currtime();
+       unsigned long usec, suspended, start, done;
        flstate_t oldstate, newstate;
 
+               start = xip_currtime();
+       usec = *chip_op_time * 8;
+       if (usec == 0)
+               usec = 500000;
+       done = 0;
+
        do {
                cpu_relax();
                if (xip_irqpending() && cfip &&
@@ -930,9 +937,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
                         * we resume the whole thing at once).  Yes, it
                         * can happen!
                         */
+                       usec -= done;
                        map_write(map, CMD(0xb0), adr);
                        map_write(map, CMD(0x70), adr);
-                       usec -= xip_elapsed_since(start);
                        suspended = xip_currtime();
                        do {
                                if (xip_elapsed_since(suspended) > 100000) {
@@ -942,7 +949,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
                                         * This is a critical error but there
                                         * is not much we can do here.
                                         */
-                                       return;
+                                       return -EIO;
                                }
                                status = map_read(map, adr);
                        } while (!map_word_andequal(map, status, OK, OK));
@@ -1002,65 +1009,107 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
                        xip_cpu_idle();
                }
                status = map_read(map, adr);
+               done = xip_elapsed_since(start);
        } while (!map_word_andequal(map, status, OK, OK)
-                && xip_elapsed_since(start) < usec);
-}
+                && done < usec);
 
-#define UDELAY(map, chip, adr, usec)  xip_udelay(map, chip, adr, usec)
+       return (done >= usec) ? -ETIME : 0;
+}
 
 /*
  * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
  * the flash is actively programming or erasing since we have to poll for
  * the operation to complete anyway.  We can't do that in a generic way with
  * a XIP setup so do it before the actual flash operation in this case
- * and stub it out from INVALIDATE_CACHE_UDELAY.
+ * and stub it out from INVAL_CACHE_AND_WAIT.
  */
 #define XIP_INVAL_CACHED_RANGE(map, from, size)  \
        INVALIDATE_CACHED_RANGE(map, from, size)
 
-#define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec)  \
-       UDELAY(map, chip, cmd_adr, usec)
-
-/*
- * Extra notes:
- *
- * Activating this XIP support changes the way the code works a bit.  For
- * example the code to suspend the current process when concurrent access
- * happens is never executed because xip_udelay() will always return with the
- * same chip state as it was entered with.  This is why there is no care for
- * the presence of add_wait_queue() or schedule() calls from within a couple
- * xip_disable()'d  areas of code, like in do_erase_oneblock for example.
- * The queueing and scheduling are always happening within xip_udelay().
- *
- * Similarly, get_chip() and put_chip() just happen to always be executed
- * with chip->state set to FL_READY (or FL_XIP_WHILE_*) where flash state
- * is in array mode, therefore never executing many cases therein and not
- * causing any problem with XIP.
- */
+#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
+       xip_wait_for_operation(map, chip, cmd_adr, p_usec)
 
 #else
 
 #define xip_disable(map, chip, adr)
 #define xip_enable(map, chip, adr)
 #define XIP_INVAL_CACHED_RANGE(x...)
+#define INVAL_CACHE_AND_WAIT inval_cache_and_wait_for_operation
+
+static int inval_cache_and_wait_for_operation(
+               struct map_info *map, struct flchip *chip,
+               unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
+               int *chip_op_time )
+{
+       struct cfi_private *cfi = map->fldrv_priv;
+       map_word status, status_OK = CMD(0x80);
+       int z, chip_state = chip->state;
+       unsigned long timeo;
+
+       spin_unlock(chip->mutex);
+       if (inval_len)
+               INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
+       if (*chip_op_time)
+               cfi_udelay(*chip_op_time);
+       spin_lock(chip->mutex);
 
-#define UDELAY(map, chip, adr, usec)  \
-do {  \
-       spin_unlock(chip->mutex);  \
-       cfi_udelay(usec);  \
-       spin_lock(chip->mutex);  \
-} while (0)
-
-#define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec)  \
-do {  \
-       spin_unlock(chip->mutex);  \
-       INVALIDATE_CACHED_RANGE(map, adr, len);  \
-       cfi_udelay(usec);  \
-       spin_lock(chip->mutex);  \
-} while (0)
+       timeo = *chip_op_time * 8 * HZ / 1000000;
+       if (timeo < HZ/2)
+               timeo = HZ/2;
+       timeo += jiffies;
+
+       z = 0;
+       for (;;) {
+               if (chip->state != chip_state) {
+                       /* Someone's suspended the operation: sleep */
+                       DECLARE_WAITQUEUE(wait, current);
+
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+                       add_wait_queue(&chip->wq, &wait);
+                       spin_unlock(chip->mutex);
+                       schedule();
+                       remove_wait_queue(&chip->wq, &wait);
+                       timeo = jiffies + (HZ / 2); /* FIXME */
+                       spin_lock(chip->mutex);
+                       continue;
+               }
+
+               status = map_read(map, cmd_adr);
+               if (map_word_andequal(map, status, status_OK, status_OK))
+                       break;
+
+               /* OK Still waiting */
+               if (time_after(jiffies, timeo)) {
+                       map_write(map, CMD(0x70), cmd_adr);
+                       chip->state = FL_STATUS;
+                       return -ETIME;
+               }
+
+               /* Latency issues. Drop the lock, wait a while and retry */
+               z++;
+               spin_unlock(chip->mutex);
+               cfi_udelay(1);
+               spin_lock(chip->mutex);
+       }
+
+       if (!z) {
+               if (!--(*chip_op_time))
+                       *chip_op_time = 1;
+       } else if (z > 1)
+               ++(*chip_op_time);
+
+       /* Done and happy. */
+       chip->state = FL_STATUS;
+       return 0;
+}
 
 #endif
 
+#define WAIT_TIMEOUT(map, chip, adr, udelay) \
+       ({ int __udelay = (udelay); \
+          INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
+
+
 static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
 {
        unsigned long cmd_addr;
@@ -1250,14 +1299,11 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
                                     unsigned long adr, map_word datum, int mode)
 {
        struct cfi_private *cfi = map->fldrv_priv;
-       map_word status, status_OK, write_cmd;
-       unsigned long timeo;
-       int z, ret=0;
+       map_word status, write_cmd;
+       int ret=0;
 
        adr += chip->start;
 
-       /* Let's determine those according to the interleave only once */
-       status_OK = CMD(0x80);
        switch (mode) {
        case FL_WRITING:
                write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
@@ -1283,57 +1329,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
        map_write(map, datum, adr);
        chip->state = mode;
 
-       INVALIDATE_CACHE_UDELAY(map, chip, adr,
-                               adr, map_bankwidth(map),
-                               chip->word_write_time);
-
-       timeo = jiffies + (HZ/2);
-       z = 0;
-       for (;;) {
-               if (chip->state != mode) {
-                       /* Someone's suspended the write. Sleep */
-                       DECLARE_WAITQUEUE(wait, current);
-
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       add_wait_queue(&chip->wq, &wait);
-                       spin_unlock(chip->mutex);
-                       schedule();
-                       remove_wait_queue(&chip->wq, &wait);
-                       timeo = jiffies + (HZ / 2); /* FIXME */
-                       spin_lock(chip->mutex);
-                       continue;
-               }
-
-               status = map_read(map, adr);
-               if (map_word_andequal(map, status, status_OK, status_OK))
-                       break;
-
-               /* OK Still waiting */
-               if (time_after(jiffies, timeo)) {
-                       map_write(map, CMD(0x70), adr);
-                       chip->state = FL_STATUS;
-                       xip_enable(map, chip, adr);
-                       printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
-                       ret = -EIO;
-                       goto out;
-               }
-
-               /* Latency issues. Drop the lock, wait a while and retry */
-               z++;
-               UDELAY(map, chip, adr, 1);
-       }
-       if (!z) {
-               chip->word_write_time--;
-               if (!chip->word_write_time)
-                       chip->word_write_time = 1;
+       ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
+                                  adr, map_bankwidth(map),
+                                  &chip->word_write_time);
+       if (ret) {
+               xip_enable(map, chip, adr);
+               printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
+               goto out;
        }
-       if (z > 1)
-               chip->word_write_time++;
-
-       /* Done and happy. */
-       chip->state = FL_STATUS;
 
        /* check for errors */
+       status = map_read(map, adr);
        if (map_word_bitsset(map, status, CMD(0x1a))) {
                unsigned long chipstatus = MERGESTATUS(status);
 
@@ -1450,9 +1456,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
                                    unsigned long *pvec_seek, int len)
 {
        struct cfi_private *cfi = map->fldrv_priv;
-       map_word status, status_OK, write_cmd, datum;
-       unsigned long cmd_adr, timeo;
-       int wbufsize, z, ret=0, word_gap, words;
+       map_word status, write_cmd, datum;
+       unsigned long cmd_adr;
+       int ret, wbufsize, word_gap, words;
        const struct kvec *vec;
        unsigned long vec_seek;
 
@@ -1461,7 +1467,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        cmd_adr = adr & ~(wbufsize-1);
 
        /* Let's determine this according to the interleave only once */
-       status_OK = CMD(0x80);
        write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
 
        spin_lock(chip->mutex);
@@ -1475,12 +1480,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        ENABLE_VPP(map);
        xip_disable(map, chip, cmd_adr);
 
-       /* Â§4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
+       /* Ã‚§4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
           [...], the device will not accept any more Write to Buffer commands".
           So we must check here and reset those bits if they're set. Otherwise
           we're just pissing in the wind */
-       if (chip->state != FL_STATUS)
+       if (chip->state != FL_STATUS) {
                map_write(map, CMD(0x70), cmd_adr);
+               chip->state = FL_STATUS;
+       }
        status = map_read(map, cmd_adr);
        if (map_word_bitsset(map, status, CMD(0x30))) {
                xip_enable(map, chip, cmd_adr);
@@ -1491,32 +1498,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        }
 
        chip->state = FL_WRITING_TO_BUFFER;
-
-       z = 0;
-       for (;;) {
-               map_write(map, write_cmd, cmd_adr);
-
+       map_write(map, write_cmd, cmd_adr);
+       ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0);
+       if (ret) {
+               /* Argh. Not ready for write to buffer */
+               map_word Xstatus = map_read(map, cmd_adr);
+               map_write(map, CMD(0x70), cmd_adr);
+               chip->state = FL_STATUS;
                status = map_read(map, cmd_adr);
-               if (map_word_andequal(map, status, status_OK, status_OK))
-                       break;
-
-               UDELAY(map, chip, cmd_adr, 1);
-
-               if (++z > 20) {
-                       /* Argh. Not ready for write to buffer */
-                       map_word Xstatus;
-                       map_write(map, CMD(0x70), cmd_adr);
-                       chip->state = FL_STATUS;
-                       Xstatus = map_read(map, cmd_adr);
-                       /* Odd. Clear status bits */
-                       map_write(map, CMD(0x50), cmd_adr);
-                       map_write(map, CMD(0x70), cmd_adr);
-                       xip_enable(map, chip, cmd_adr);
-                       printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
-                              map->name, status.x[0], Xstatus.x[0]);
-                       ret = -EIO;
-                       goto out;
-               }
+               map_write(map, CMD(0x50), cmd_adr);
+               map_write(map, CMD(0x70), cmd_adr);
+               xip_enable(map, chip, cmd_adr);
+               printk(KERN_ERR "%s: Chip not ready for buffer write. Xstatus = %lx, status = %lx\n",
+                               map->name, Xstatus.x[0], status.x[0]);
+               goto out;
        }
 
        /* Figure out the number of words to write */
@@ -1571,56 +1566,19 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        map_write(map, CMD(0xd0), cmd_adr);
        chip->state = FL_WRITING;
 
-       INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr,
-                               adr, len,
-                               chip->buffer_write_time);
-
-       timeo = jiffies + (HZ/2);
-       z = 0;
-       for (;;) {
-               if (chip->state != FL_WRITING) {
-                       /* Someone's suspended the write. Sleep */
-                       DECLARE_WAITQUEUE(wait, current);
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       add_wait_queue(&chip->wq, &wait);
-                       spin_unlock(chip->mutex);
-                       schedule();
-                       remove_wait_queue(&chip->wq, &wait);
-                       timeo = jiffies + (HZ / 2); /* FIXME */
-                       spin_lock(chip->mutex);
-                       continue;
-               }
-
-               status = map_read(map, cmd_adr);
-               if (map_word_andequal(map, status, status_OK, status_OK))
-                       break;
-
-               /* OK Still waiting */
-               if (time_after(jiffies, timeo)) {
-                       map_write(map, CMD(0x70), cmd_adr);
-                       chip->state = FL_STATUS;
-                       xip_enable(map, chip, cmd_adr);
-                       printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
-                       ret = -EIO;
-                       goto out;
-               }
-
-               /* Latency issues. Drop the lock, wait a while and retry */
-               z++;
-               UDELAY(map, chip, cmd_adr, 1);
-       }
-       if (!z) {
-               chip->buffer_write_time--;
-               if (!chip->buffer_write_time)
-                       chip->buffer_write_time = 1;
+       ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
+                                  adr, len,
+                                  &chip->buffer_write_time);
+       if (ret) {
+               map_write(map, CMD(0x70), cmd_adr);
+               chip->state = FL_STATUS;
+               xip_enable(map, chip, cmd_adr);
+               printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
+               goto out;
        }
-       if (z > 1)
-               chip->buffer_write_time++;
-
-       /* Done and happy. */
-       chip->state = FL_STATUS;
 
        /* check for errors */
+       status = map_read(map, cmd_adr);
        if (map_word_bitsset(map, status, CMD(0x1a))) {
                unsigned long chipstatus = MERGESTATUS(status);
 
@@ -1691,6 +1649,11 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
                        if (chipnum == cfi->numchips)
                                return 0;
                }
+
+               /* Be nice and reschedule with the chip in a usable state for other
+                  processes. */
+               cond_resched();
+
        } while (len);
 
        return 0;
@@ -1711,17 +1674,12 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
                                      unsigned long adr, int len, void *thunk)
 {
        struct cfi_private *cfi = map->fldrv_priv;
-       map_word status, status_OK;
-       unsigned long timeo;
+       map_word status;
        int retries = 3;
-       DECLARE_WAITQUEUE(wait, current);
-       int ret = 0;
+       int ret;
 
        adr += chip->start;
 
-       /* Let's determine this according to the interleave only once */
-       status_OK = CMD(0x80);
-
  retry:
        spin_lock(chip->mutex);
        ret = get_chip(map, chip, adr, FL_ERASING);
@@ -1743,48 +1701,15 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
 
-       INVALIDATE_CACHE_UDELAY(map, chip, adr,
-                               adr, len,
-                               chip->erase_time*1000/2);
-
-       /* FIXME. Use a timer to check this, and return immediately. */
-       /* Once the state machine's known to be working I'll do that */
-
-       timeo = jiffies + (HZ*20);
-       for (;;) {
-               if (chip->state != FL_ERASING) {
-                       /* Someone's suspended the erase. Sleep */
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       add_wait_queue(&chip->wq, &wait);
-                       spin_unlock(chip->mutex);
-                       schedule();
-                       remove_wait_queue(&chip->wq, &wait);
-                       spin_lock(chip->mutex);
-                       continue;
-               }
-               if (chip->erase_suspended) {
-                       /* This erase was suspended and resumed.
-                          Adjust the timeout */
-                       timeo = jiffies + (HZ*20); /* FIXME */
-                       chip->erase_suspended = 0;
-               }
-
-               status = map_read(map, adr);
-               if (map_word_andequal(map, status, status_OK, status_OK))
-                       break;
-
-               /* OK Still waiting */
-               if (time_after(jiffies, timeo)) {
-                       map_write(map, CMD(0x70), adr);
-                       chip->state = FL_STATUS;
-                       xip_enable(map, chip, adr);
-                       printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
-                       ret = -EIO;
-                       goto out;
-               }
-
-               /* Latency issues. Drop the lock, wait a while and retry */
-               UDELAY(map, chip, adr, 1000000/HZ);
+       ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
+                                  adr, len,
+                                  &chip->erase_time);
+       if (ret) {
+               map_write(map, CMD(0x70), adr);
+               chip->state = FL_STATUS;
+               xip_enable(map, chip, adr);
+               printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
+               goto out;
        }
 
        /* We've broken this before. It doesn't hurt to be safe */
@@ -1813,7 +1738,6 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
                        ret = -EIO;
                } else if (chipstatus & 0x20 && retries--) {
                        printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
-                       timeo = jiffies + HZ;
                        put_chip(map, chip, adr);
                        spin_unlock(chip->mutex);
                        goto retry;
@@ -1919,15 +1843,11 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
 {
        struct cfi_private *cfi = map->fldrv_priv;
        struct cfi_pri_intelext *extp = cfi->cmdset_priv;
-       map_word status, status_OK;
-       unsigned long timeo = jiffies + HZ;
+       int udelay;
        int ret;
 
        adr += chip->start;
 
-       /* Let's determine this according to the interleave only once */
-       status_OK = CMD(0x80);
-
        spin_lock(chip->mutex);
        ret = get_chip(map, chip, adr, FL_LOCKING);
        if (ret) {
@@ -1952,41 +1872,21 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
         * If Instant Individual Block Locking supported then no need
         * to delay.
         */
+       udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
 
-       if (!extp || !(extp->FeatureSupport & (1 << 5)))
-               UDELAY(map, chip, adr, 1000000/HZ);
-
-       /* FIXME. Use a timer to check this, and return immediately. */
-       /* Once the state machine's known to be working I'll do that */
-
-       timeo = jiffies + (HZ*20);
-       for (;;) {
-
-               status = map_read(map, adr);
-               if (map_word_andequal(map, status, status_OK, status_OK))
-                       break;
-
-               /* OK Still waiting */
-               if (time_after(jiffies, timeo)) {
-                       map_write(map, CMD(0x70), adr);
-                       chip->state = FL_STATUS;
-                       xip_enable(map, chip, adr);
-                       printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
-                       put_chip(map, chip, adr);
-                       spin_unlock(chip->mutex);
-                       return -EIO;
-               }
-
-               /* Latency issues. Drop the lock, wait a while and retry */
-               UDELAY(map, chip, adr, 1);
+       ret = WAIT_TIMEOUT(map, chip, adr, udelay);
+       if (ret) {
+               map_write(map, CMD(0x70), adr);
+               chip->state = FL_STATUS;
+               xip_enable(map, chip, adr);
+               printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
+               goto out;
        }
 
-       /* Done and happy. */
-       chip->state = FL_STATUS;
        xip_enable(map, chip, adr);
-       put_chip(map, chip, adr);
+out:   put_chip(map, chip, adr);
        spin_unlock(chip->mutex);
-       return 0;
+       return ret;
 }
 
 static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
index e636aa8..4bf9f8c 100644 (file)
@@ -349,12 +349,12 @@ static void print_cfi_ident(struct cfi_ident *cfip)
        else
                printk("No Vpp line\n");
 
-       printk("Typical byte/word write timeout: %d Âµs\n", 1<<cfip->WordWriteTimeoutTyp);
-       printk("Maximum byte/word write timeout: %d Âµs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
+       printk("Typical byte/word write timeout: %d Ã‚µs\n", 1<<cfip->WordWriteTimeoutTyp);
+       printk("Maximum byte/word write timeout: %d Ã‚µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
 
        if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
-               printk("Typical full buffer write timeout: %d Âµs\n", 1<<cfip->BufWriteTimeoutTyp);
-               printk("Maximum full buffer write timeout: %d Âµs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
+               printk("Typical full buffer write timeout: %d Ã‚µs\n", 1<<cfip->BufWriteTimeoutTyp);
+               printk("Maximum full buffer write timeout: %d Ã‚µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
        }
        else
                printk("Full buffer write not supported\n");
index 9b252d2..52d59d3 100644 (file)
@@ -37,8 +37,15 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
        if (!mtd)
                mtd = check_cmd_set(map, 0); /* Then the secondary */
 
-       if (mtd)
+       if (mtd) {
+               if (mtd->size > map->size) {
+                       printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n",
+                              (unsigned long)mtd->size >> 10, 
+                              (unsigned long)map->size >> 10);
+                       mtd->size = map->size;
+               }
                return mtd;
+       }
 
        printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
 
@@ -100,7 +107,12 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
         * Align bitmap storage size to full byte.
         */
        max_chips = map->size >> cfi.chipshift;
-       mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
+       if (!max_chips) {
+               printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n");
+               max_chips = 1;
+       }
+
+       mapsize = (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG;
        chip_map = kmalloc(mapsize, GFP_KERNEL);
        if (!chip_map) {
                printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
index 6e9f880..16c02b5 100644 (file)
@@ -47,6 +47,11 @@ config MTD_MS02NV
          accelerator.  Say Y here if you have a DECstation 5000/2x0 or a
          DECsystem 5900 equipped with such a module.
 
+         If you want to compile this driver as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want),
+         say M here and read <file:Documentation/modules.txt>.  The module will
+         be called ms02-nv.o.
+
 config MTD_DATAFLASH
        tristate "Support for AT45xxx DataFlash"
        depends on MTD && SPI_MASTER && EXPERIMENTAL
index f54e4bf..8ca04f4 100644 (file)
@@ -4,7 +4,7 @@
  * block2mtd.c - create an mtd from a block device
  *
  * Copyright (C) 2001,2002     Simon Evans <spse@secret.org.uk>
- * Copyright (C) 2004-2006     Jörn Engel <joern@wh.fh-wedel.de>
+ * Copyright (C) 2004-2006     Jörn Engel <joern@wh.fh-wedel.de>
  *
  * Licence: GPL
  */
@@ -429,7 +429,8 @@ static inline void kill_final_newline(char *str)
 
 static int block2mtd_setup(const char *val, struct kernel_param *kp)
 {
-       char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
+       char buf[80+12]; /* 80 for device, 12 for erase size */
+       char *str = buf;
        char *token[2];
        char *name;
        size_t erase_size = PAGE_SIZE;
@@ -441,7 +442,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
        strcpy(str, val);
        kill_final_newline(str);
 
-       for (i=0; i<2; i++)
+       for (i = 0; i < 2; i++)
                token[i] = strsep(&str, ",");
 
        if (str)
@@ -460,8 +461,10 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
 
        if (token[1]) {
                ret = parse_num(&erase_size, token[1]);
-               if (ret)
+               if (ret) {
+                       kfree(name);
                        parse_err("illegal erase size");
+               }
        }
 
        add_device(name, erase_size);
index 32f1d33..42ec084 100644 (file)
@@ -231,21 +231,21 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
 
 static int docfound;
 
-#ifdef CONFIG_DOC2000
+#ifdef CONFIG_MTD_DOC2000
 extern void DoC2k_init(struct mtd_info *);
 #define doc2k_initfunc (&DoC2k_init)
 #else 
 #define doc2k_initfunc NULL
 #endif
 
-#ifdef CONFIG_DOC2001
+#ifdef CONFIG_MTD_DOC2001
 extern void DoCMil_init(struct mtd_info *);
 #define docmil_initfunc (&DoCMil_init)
 #else 
 #define docmil_initfunc NULL
 #endif
 
-#ifdef CONFIG_DOC2001PLUS
+#ifdef CONFIG_MTD_DOC2001PLUS
 extern void DoCMilPlus_init(struct mtd_info *);
 #define docmplus_initfunc (&DoCMilPlus_init)
 #else 
index 41af969..e09e416 100644 (file)
@@ -1,8 +1,8 @@
 /**
  * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
  *
- * Copyright (c) ????          Jochen Schäuble <psionic@psionic.de>
- * Copyright (c) 2003-2004     Jörn Engel <joern@wh.fh-wedel.de>
+ * Copyright (c) ????          Jochen Schäuble <psionic@psionic.de>
+ * Copyright (c) 2003-2004     Jörn Engel <joern@wh.fh-wedel.de>
  *
  * Usage:
  *
@@ -266,12 +266,16 @@ static int phram_setup(const char *val, struct kernel_param *kp)
                return 0;
 
        ret = parse_num32(&start, token[1]);
-       if (ret)
+       if (ret) {
+               kfree(name);
                parse_err("illegal start address\n");
+       }
 
        ret = parse_num32(&len, token[2]);
-       if (ret)
+       if (ret) {
+               kfree(name);
                parse_err("illegal device length\n");
+       }
 
        register_device(name, start, len);
 
@@ -296,5 +300,5 @@ module_init(init_phram);
 module_exit(cleanup_phram);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>");
+MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>");
 MODULE_DESCRIPTION("MTD driver for physical RAM");
index 4e2bd37..6bdaacc 100644 (file)
@@ -200,8 +200,8 @@ config MTD_TSUNAMI
          Support for the flash chip on Tsunami TIG bus.
 
 config MTD_LASAT
-       tristate "Flash chips on LASAT board"
-       depends on LASAT
+       tristate "LASAT flash device"
+       depends on LASAT && MTD_CFI
        help
          Support for the flash chips on the Lasat 100 and 200 boards.
 
index fd0f0d3..92b5d88 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright Â© 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
+ *  Copyright Â© 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
  *
  *  $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
  *
@@ -135,5 +135,5 @@ module_exit(cleanup_flagadm);
 
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
 MODULE_DESCRIPTION("MTD map driver for Flaga digital module");
index 652813c..85c2a9e 100644 (file)
@@ -122,5 +122,5 @@ module_exit(cleanup_dbox2_flash);
 
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
 MODULE_DESCRIPTION("MTD map driver for D-Box 2 board");
index d1e66e1..5c25d4e 100644 (file)
@@ -4,7 +4,7 @@
  * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
  *
  * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
- * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
+ * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
  *
  */
 
index d27f412..c861134 100644 (file)
@@ -713,6 +713,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
 
        if(dev->mtd_info) {
                del_mtd_device(dev->mtd_info);
+               map_destroy(dev->mtd_info);
                info("mtd%d: Removed", dev->mtd_info->index);
        }
 
index 76ce9bd..bc82f70 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <asm/io.h>
-#include <asm/mach/flash.h>
 
 struct physmap_flash_info {
        struct mtd_info         *mtd;
index 9af8403..b7de908 100644 (file)
@@ -251,6 +251,106 @@ concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 }
 
 static int
+concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
+               unsigned long count, loff_t to, size_t * retlen,
+               u_char *eccbuf, struct nand_oobinfo *oobsel)
+{
+       struct mtd_concat *concat = CONCAT(mtd);
+       struct kvec *vecs_copy;
+       unsigned long entry_low, entry_high;
+       size_t total_len = 0;
+       int i;
+       int err = -EINVAL;
+
+       if (!(mtd->flags & MTD_WRITEABLE))
+               return -EROFS;
+
+       *retlen = 0;
+
+       /* Calculate total length of data */
+       for (i = 0; i < count; i++)
+               total_len += vecs[i].iov_len;
+
+       /* Do not allow write past end of device */
+       if ((to + total_len) > mtd->size)
+               return -EINVAL;
+
+       /* Check alignment */
+       if (mtd->oobblock > 1)
+               if ((to % mtd->oobblock) || (total_len % mtd->oobblock))
+                       return -EINVAL;
+
+       /* make a copy of vecs */
+       vecs_copy = kmalloc(sizeof(struct kvec) * count, GFP_KERNEL);
+       if (!vecs_copy)
+               return -ENOMEM;
+       memcpy(vecs_copy, vecs, sizeof(struct kvec) * count);
+
+       entry_low = 0;
+       for (i = 0; i < concat->num_subdev; i++) {
+               struct mtd_info *subdev = concat->subdev[i];
+               size_t size, wsize, retsize, old_iov_len;
+
+               if (to >= subdev->size) {
+                       to -= subdev->size;
+                       continue;
+               }
+
+               size = min(total_len, (size_t)(subdev->size - to));
+               wsize = size; /* store for future use */
+
+               entry_high = entry_low;
+               while (entry_high < count) {
+                       if (size <= vecs_copy[entry_high].iov_len)
+                               break;
+                       size -= vecs_copy[entry_high++].iov_len;
+               }
+
+               old_iov_len = vecs_copy[entry_high].iov_len;
+               vecs_copy[entry_high].iov_len = size;
+
+               if (!(subdev->flags & MTD_WRITEABLE))
+                       err = -EROFS;
+               else if (eccbuf)
+                       err = subdev->writev_ecc(subdev, &vecs_copy[entry_low],
+                               entry_high - entry_low + 1, to, &retsize,
+                               eccbuf, oobsel);
+               else
+                       err = subdev->writev(subdev, &vecs_copy[entry_low],
+                               entry_high - entry_low + 1, to, &retsize);
+
+               vecs_copy[entry_high].iov_len = old_iov_len - size;
+               vecs_copy[entry_high].iov_base += size;
+
+               entry_low = entry_high;
+
+               if (err)
+                       break;
+
+               *retlen += retsize;
+               total_len -= wsize;
+               if (concat->mtd.type == MTD_NANDFLASH && eccbuf)
+                       eccbuf += mtd->oobavail * (wsize / mtd->oobblock);
+
+               if (total_len == 0)
+                       break;
+
+               err = -EINVAL;
+               to = 0;
+       }
+
+       kfree(vecs_copy);
+       return err;
+}
+
+static int
+concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
+               unsigned long count, loff_t to, size_t * retlen)
+{
+       return concat_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
+}
+
+static int
 concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
                size_t * retlen, u_char * buf)
 {
@@ -636,6 +736,58 @@ static void concat_resume(struct mtd_info *mtd)
        }
 }
 
+static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
+{
+       struct mtd_concat *concat = CONCAT(mtd);
+       int i, res = 0;
+
+       if (!concat->subdev[0]->block_isbad)
+               return res;
+
+       if (ofs > mtd->size)
+               return -EINVAL;
+
+       for (i = 0; i < concat->num_subdev; i++) {
+               struct mtd_info *subdev = concat->subdev[i];
+
+               if (ofs >= subdev->size) {
+                       ofs -= subdev->size;
+                       continue;
+               }
+
+               res = subdev->block_isbad(subdev, ofs);
+               break;
+       }
+
+       return res;
+}
+
+static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+       struct mtd_concat *concat = CONCAT(mtd);
+       int i, err = -EINVAL;
+
+       if (!concat->subdev[0]->block_markbad)
+               return 0;
+
+       if (ofs > mtd->size)
+               return -EINVAL;
+
+       for (i = 0; i < concat->num_subdev; i++) {
+               struct mtd_info *subdev = concat->subdev[i];
+
+               if (ofs >= subdev->size) {
+                       ofs -= subdev->size;
+                       continue;
+               }
+
+               err = subdev->block_markbad(subdev, ofs);
+               break;
+       }
+
+       return err;
+}
+
 /*
  * This function constructs a virtual MTD device by concatenating
  * num_devs MTD devices. A pointer to the new device object is
@@ -685,10 +837,18 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],     /* subdevices to c
                concat->mtd.read_ecc = concat_read_ecc;
        if (subdev[0]->write_ecc)
                concat->mtd.write_ecc = concat_write_ecc;
+       if (subdev[0]->writev)
+               concat->mtd.writev = concat_writev;
+       if (subdev[0]->writev_ecc)
+               concat->mtd.writev_ecc = concat_writev_ecc;
        if (subdev[0]->read_oob)
                concat->mtd.read_oob = concat_read_oob;
        if (subdev[0]->write_oob)
                concat->mtd.write_oob = concat_write_oob;
+       if (subdev[0]->block_isbad)
+               concat->mtd.block_isbad = concat_block_isbad;
+       if (subdev[0]->block_markbad)
+               concat->mtd.block_markbad = concat_block_markbad;
 
        concat->subdev[0] = subdev[0];
 
@@ -734,14 +894,13 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],     /* subdevices to c
 
        }
 
+       if(concat->mtd.type == MTD_NANDFLASH)
+               memcpy(&concat->mtd.oobinfo, &subdev[0]->oobinfo,
+                       sizeof(struct nand_oobinfo));
+
        concat->num_subdev = num_devs;
        concat->mtd.name = name;
 
-       /*
-        * NOTE: for now, we do not provide any readv()/writev() methods
-        *       because they are messy to implement and they are not
-        *       used to a great extent anyway.
-        */
        concat->mtd.erase = concat_erase;
        concat->mtd.read = concat_read;
        concat->mtd.write = concat_write;
index 9939591..29ed5ab 100644 (file)
@@ -400,6 +400,7 @@ int add_mtd_partitions(struct mtd_info *master,
                slave->mtd.size = parts[i].size;
                slave->mtd.oobblock = master->oobblock;
                slave->mtd.oobsize = master->oobsize;
+               slave->mtd.oobavail = master->oobavail;
                slave->mtd.ecctype = master->ecctype;
                slave->mtd.eccsize = master->eccsize;
 
index b4a7086..b1f8079 100644 (file)
@@ -192,12 +192,21 @@ config MTD_NAND_SHARPSL
 config MTD_NAND_CS553X
        tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
        depends on MTD_NAND && X86_PC && PCI
-       
+       help
+         The CS553x companion chips for the AMD Geode processor
+         include NAND flash controllers with built-in hardware ECC
+         capabilities; enabling this option will allow you to use
+         these. The driver will check the MSRs to verify that the
+         controller is enabled for NAND, and currently requires that
+         the controller be in MMIO mode.
+
+         If you say "m", the module will be called "cs553x_nand.ko".
+
 config MTD_NAND_NANDSIM
        tristate "Support for NAND Flash Simulator"
        depends on MTD_NAND && MTD_PARTITIONS
        help
-         The simulator may simulate verious NAND flash chips for the
+         The simulator may simulate various NAND flash chips for the
          MTD nand layer.
 
 endmenu
index bde3550..d9a0143 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
  */
 static struct mtd_info *au1550_mtd = NULL;
 static void __iomem *p_nand;
-static int nand_width = 1; /* default x8*/
+static int nand_width = 1;     /* default x8 */
 
 /*
  * Define partitions for flash device
  */
 static const struct mtd_partition partition_info[] = {
        {
-               .name   = "NAND FS 0",
-               .offset = 0,
-               .size   = 8*1024*1024
-       },
+        .name = "NAND FS 0",
+        .offset = 0,
+        .size = 8 * 1024 * 1024},
        {
-               .name   = "NAND FS 1",
-               .offset =  MTDPART_OFS_APPEND,
-               .size   =    MTDPART_SIZ_FULL
-       }
+        .name = "NAND FS 1",
+        .offset = MTDPART_OFS_APPEND,
+        .size = MTDPART_SIZ_FULL}
 };
 
 /**
@@ -157,7 +156,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
        int i;
        struct nand_chip *this = mtd->priv;
 
-       for (i=0; i<len; i++) {
+       for (i = 0; i < len; i++) {
                writeb(buf[i], this->IO_ADDR_W);
                au_sync();
        }
@@ -176,7 +175,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
        int i;
        struct nand_chip *this = mtd->priv;
 
-       for (i=0; i<len; i++) {
+       for (i = 0; i < len; i++) {
                buf[i] = readb(this->IO_ADDR_R);
                au_sync();
        }
@@ -195,7 +194,7 @@ static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
        int i;
        struct nand_chip *this = mtd->priv;
 
-       for (i=0; i<len; i++) {
+       for (i = 0; i < len; i++) {
                if (buf[i] != readb(this->IO_ADDR_R))
                        return -EFAULT;
                au_sync();
@@ -219,7 +218,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
        u16 *p = (u16 *) buf;
        len >>= 1;
 
-       for (i=0; i<len; i++) {
+       for (i = 0; i < len; i++) {
                writew(p[i], this->IO_ADDR_W);
                au_sync();
        }
@@ -241,7 +240,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
        u16 *p = (u16 *) buf;
        len >>= 1;
 
-       for (i=0; i<len; i++) {
+       for (i = 0; i < len; i++) {
                p[i] = readw(this->IO_ADDR_R);
                au_sync();
        }
@@ -262,7 +261,7 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
        u16 *p = (u16 *) buf;
        len >>= 1;
 
-       for (i=0; i<len; i++) {
+       for (i = 0; i < len; i++) {
                if (p[i] != readw(this->IO_ADDR_R))
                        return -EFAULT;
                au_sync();
@@ -275,27 +274,35 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
 {
        register struct nand_chip *this = mtd->priv;
 
-       switch(cmd){
+       switch (cmd) {
+
+       case NAND_CTL_SETCLE:
+               this->IO_ADDR_W = p_nand + MEM_STNAND_CMD;
+               break;
 
-       case NAND_CTL_SETCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; break;
-       case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
+       case NAND_CTL_CLRCLE:
+               this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
+               break;
+
+       case NAND_CTL_SETALE:
+               this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR;
+               break;
 
-       case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
        case NAND_CTL_CLRALE:
                this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
-               /* FIXME: Nobody knows why this is neccecary,
+               /* FIXME: Nobody knows why this is necessary,
                 * but it works only that way */
                udelay(1);
                break;
 
        case NAND_CTL_SETNCE:
                /* assert (force assert) chip enable */
-               au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
+               au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL);
                break;
 
        case NAND_CTL_CLRNCE:
-               /* deassert chip enable */
-               au_writel(0, MEM_STNDCTL); break;
+               /* deassert chip enable */
+               au_writel(0, MEM_STNDCTL);
                break;
        }
 
@@ -312,69 +319,200 @@ int au1550_device_ready(struct mtd_info *mtd)
        return ret;
 }
 
+/**
+ * au1550_select_chip - control -CE line
+ *     Forbid driving -CE manually permitting the NAND controller to do this.
+ *     Keeping -CE asserted during the whole sector reads interferes with the
+ *     NOR flash and PCMCIA drivers as it causes contention on the static bus.
+ *     We only have to hold -CE low for the NAND read commands since the flash
+ *     chip needs it to be asserted during chip not ready time but the NAND
+ *     controller keeps it released.
+ *
+ * @mtd:       MTD device structure
+ * @chip:      chipnumber to select, -1 for deselect
+ */
+static void au1550_select_chip(struct mtd_info *mtd, int chip)
+{
+}
+
+/**
+ * au1550_command - Send command to NAND device
+ * @mtd:       MTD device structure
+ * @command:   the command to be sent
+ * @column:    the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
+ */
+static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+       register struct nand_chip *this = mtd->priv;
+       int ce_override = 0, i;
+       ulong flags;
+
+       /* Begin command latch cycle */
+       this->hwcontrol(mtd, NAND_CTL_SETCLE);
+       /*
+        * Write out the command to the device.
+        */
+       if (command == NAND_CMD_SEQIN) {
+               int readcmd;
+
+               if (column >= mtd->oobblock) {
+                       /* OOB area */
+                       column -= mtd->oobblock;
+                       readcmd = NAND_CMD_READOOB;
+               } else if (column < 256) {
+                       /* First 256 bytes --> READ0 */
+                       readcmd = NAND_CMD_READ0;
+               } else {
+                       column -= 256;
+                       readcmd = NAND_CMD_READ1;
+               }
+               this->write_byte(mtd, readcmd);
+       }
+       this->write_byte(mtd, command);
+
+       /* Set ALE and clear CLE to start address cycle */
+       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+
+       if (column != -1 || page_addr != -1) {
+               this->hwcontrol(mtd, NAND_CTL_SETALE);
+
+               /* Serially input address */
+               if (column != -1) {
+                       /* Adjust columns for 16 bit buswidth */
+                       if (this->options & NAND_BUSWIDTH_16)
+                               column >>= 1;
+                       this->write_byte(mtd, column);
+               }
+               if (page_addr != -1) {
+                       this->write_byte(mtd, (u8)(page_addr & 0xff));
+
+                       if (command == NAND_CMD_READ0 ||
+                           command == NAND_CMD_READ1 ||
+                           command == NAND_CMD_READOOB) {
+                               /*
+                                * NAND controller will release -CE after
+                                * the last address byte is written, so we'll
+                                * have to forcibly assert it. No interrupts
+                                * are allowed while we do this as we don't
+                                * want the NOR flash or PCMCIA drivers to
+                                * steal our precious bytes of data...
+                                */
+                               ce_override = 1;
+                               local_irq_save(flags);
+                               this->hwcontrol(mtd, NAND_CTL_SETNCE);
+                       }
+
+                       this->write_byte(mtd, (u8)(page_addr >> 8));
+
+                       /* One more address cycle for devices > 32MiB */
+                       if (this->chipsize > (32 << 20))
+                               this->write_byte(mtd, (u8)((page_addr >> 16) & 0x0f));
+               }
+               /* Latch in address */
+               this->hwcontrol(mtd, NAND_CTL_CLRALE);
+       }
+
+       /*
+        * Program and erase have their own busy handlers.
+        * Status and sequential in need no delay.
+        */
+       switch (command) {
+
+       case NAND_CMD_PAGEPROG:
+       case NAND_CMD_ERASE1:
+       case NAND_CMD_ERASE2:
+       case NAND_CMD_SEQIN:
+       case NAND_CMD_STATUS:
+               return;
+
+       case NAND_CMD_RESET:
+               break;
+
+       case NAND_CMD_READ0:
+       case NAND_CMD_READ1:
+       case NAND_CMD_READOOB:
+               /* Check if we're really driving -CE low (just in case) */
+               if (unlikely(!ce_override))
+                       break;
+
+               /* Apply a short delay always to ensure that we do wait tWB. */
+               ndelay(100);
+               /* Wait for a chip to become ready... */
+               for (i = this->chip_delay; !this->dev_ready(mtd) && i > 0; --i)
+                       udelay(1);
+
+               /* Release -CE and re-enable interrupts. */
+               this->hwcontrol(mtd, NAND_CTL_CLRNCE);
+               local_irq_restore(flags);
+               return;
+       }
+       /* Apply this short delay always to ensure that we do wait tWB. */
+       ndelay(100);
+
+       while(!this->dev_ready(mtd));
+}
+
+
 /*
  * Main initialization routine
  */
-int __init au1xxx_nand_init (void)
+static int __init au1xxx_nand_init(void)
 {
        struct nand_chip *this;
-       u16 boot_swapboot = 0; /* default value */
+       u16 boot_swapboot = 0;  /* default value */
        int retval;
        u32 mem_staddr;
        u32 nand_phys;
 
        /* Allocate memory for MTD device structure and private data */
-       au1550_mtd = kmalloc (sizeof(struct mtd_info) +
-                       sizeof (struct nand_chip), GFP_KERNEL);
+       au1550_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!au1550_mtd) {
-               printk ("Unable to allocate NAND MTD dev structure.\n");
+               printk("Unable to allocate NAND MTD dev structure.\n");
                return -ENOMEM;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&au1550_mtd[1]);
+       this = (struct nand_chip *)(&au1550_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) au1550_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(au1550_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        au1550_mtd->priv = this;
+       au1550_mtd->owner = THIS_MODULE;
 
 
-       /* disable interrupts */
-       au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
-
-       /* disable NAND boot */
-       au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
+       /* MEM_STNDCTL: disable ints, disable nand boot */
+       au_writel(0, MEM_STNDCTL);
 
 #ifdef CONFIG_MIPS_PB1550
        /* set gpio206 high */
-       au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
+       au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
 
-       boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
-               ((bcsr->status >> 6)  & 0x1);
+       boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1);
        switch (boot_swapboot) {
-               case 0:
-               case 2:
-               case 8:
-               case 0xC:
-               case 0xD:
-                       /* x16 NAND Flash */
-                       nand_width = 0;
-                       break;
-               case 1:
-               case 9:
-               case 3:
-               case 0xE:
-               case 0xF:
-                       /* x8 NAND Flash */
-                       nand_width = 1;
-                       break;
-               default:
-                       printk("Pb1550 NAND: bad boot:swap\n");
-                       retval = -EINVAL;
-                       goto outmem;
+       case 0:
+       case 2:
+       case 8:
+       case 0xC:
+       case 0xD:
+               /* x16 NAND Flash */
+               nand_width = 0;
+               break;
+       case 1:
+       case 9:
+       case 3:
+       case 0xE:
+       case 0xF:
+               /* x8 NAND Flash */
+               nand_width = 1;
+               break;
+       default:
+               printk("Pb1550 NAND: bad boot:swap\n");
+               retval = -EINVAL;
+               goto outmem;
        }
 #endif
 
@@ -424,18 +562,20 @@ int __init au1xxx_nand_init (void)
 
        /* make controller and MTD agree */
        if (NAND_CS == 0)
-               nand_width = au_readl(MEM_STCFG0) & (1<<22);
+               nand_width = au_readl(MEM_STCFG0) & (1 << 22);
        if (NAND_CS == 1)
-               nand_width = au_readl(MEM_STCFG1) & (1<<22);
+               nand_width = au_readl(MEM_STCFG1) & (1 << 22);
        if (NAND_CS == 2)
-               nand_width = au_readl(MEM_STCFG2) & (1<<22);
+               nand_width = au_readl(MEM_STCFG2) & (1 << 22);
        if (NAND_CS == 3)
-               nand_width = au_readl(MEM_STCFG3) & (1<<22);
-
+               nand_width = au_readl(MEM_STCFG3) & (1 << 22);
 
        /* Set address of hardware control function */
        this->hwcontrol = au1550_hwcontrol;
        this->dev_ready = au1550_device_ready;
+       this->select_chip = au1550_select_chip;
+       this->cmdfunc = au1550_command;
+
        /* 30 us command delay time */
        this->chip_delay = 30;
        this->eccmode = NAND_ECC_SOFT;
@@ -454,7 +594,7 @@ int __init au1xxx_nand_init (void)
        this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;
 
        /* Scan to find existence of the device */
-       if (nand_scan (au1550_mtd, 1)) {
+       if (nand_scan(au1550_mtd, 1)) {
                retval = -ENXIO;
                goto outio;
        }
@@ -465,10 +605,10 @@ int __init au1xxx_nand_init (void)
        return 0;
 
  outio:
-       iounmap ((void *)p_nand);
+       iounmap((void *)p_nand);
 
  outmem:
-       kfree (au1550_mtd);
+       kfree(au1550_mtd);
        return retval;
 }
 
@@ -477,22 +617,21 @@ module_init(au1xxx_nand_init);
 /*
  * Clean up routine
  */
-#ifdef MODULE
-static void __exit au1550_cleanup (void)
+static void __exit au1550_cleanup(void)
 {
-       struct nand_chip *this = (struct nand_chip *) &au1550_mtd[1];
+       struct nand_chip *this = (struct nand_chip *)&au1550_mtd[1];
 
        /* Release resources, unregister device */
-       nand_release (au1550_mtd);
+       nand_release(au1550_mtd);
 
        /* Free the MTD device structure */
-       kfree (au1550_mtd);
+       kfree(au1550_mtd);
 
        /* Unmap */
-       iounmap ((void *)p_nand);
+       iounmap((void *)p_nand);
 }
+
 module_exit(au1550_cleanup);
-#endif
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Embedded Edge, LLC");
index a3c7fea..43b2960 100644 (file)
@@ -47,7 +47,7 @@ static int autcpu12_io_base = CS89712_VIRT_BASE;
 static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC;
 static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET;
 static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET;
-static void __iomem * autcpu12_fio_base;
+static void __iomem *autcpu12_fio_base;
 
 /*
  * Define partitions for flash devices
@@ -95,10 +95,10 @@ static struct mtd_partition partition_info128k[] = {
 /*
  *     hardware specific access to control-lines
 */
+
 static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
 {
-
-       switch(cmd){
+       switch (cmd) {
 
                case NAND_CTL_SETCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |=  AUTCPU12_SMC_CLE; break;
                case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_CLE; break;
@@ -117,44 +117,44 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
 int autcpu12_device_ready(struct mtd_info *mtd)
 {
 
-       return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
+       return ((*(volatile unsigned char *)(autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
 
 }
 
 /*
  * Main initialization routine
  */
-int __init autcpu12_init (void)
+static int __init autcpu12_init(void)
 {
        struct nand_chip *this;
        int err = 0;
 
        /* Allocate memory for MTD device structure and private data */
-       autcpu12_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-                               GFP_KERNEL);
+       autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!autcpu12_mtd) {
-               printk ("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
+               printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
                err = -ENOMEM;
                goto out;
        }
 
        /* map physical adress */
-       autcpu12_fio_base = ioremap(autcpu12_fio_pbase,SZ_1K);
-       if(!autcpu12_fio_base){
+       autcpu12_fio_base = ioremap(autcpu12_fio_pbase, SZ_1K);
+       if (!autcpu12_fio_base) {
                printk("Ioremap autcpu12 SmartMedia Card failed\n");
                err = -EIO;
                goto out_mtd;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&autcpu12_mtd[1]);
+       this = (struct nand_chip *)(&autcpu12_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) autcpu12_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(autcpu12_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        autcpu12_mtd->priv = this;
+       autcpu12_mtd->owner = THIS_MODULE;
 
        /* Set address of NAND IO lines */
        this->IO_ADDR_R = autcpu12_fio_base;
@@ -167,35 +167,34 @@ int __init autcpu12_init (void)
 
        /* Enable the following for a flash based bad block table */
        /*
-       this->options = NAND_USE_FLASH_BBT;
-       */
+          this->options = NAND_USE_FLASH_BBT;
+        */
        this->options = NAND_USE_FLASH_BBT;
 
        /* Scan to find existance of the device */
-       if (nand_scan (autcpu12_mtd, 1)) {
+       if (nand_scan(autcpu12_mtd, 1)) {
                err = -ENXIO;
                goto out_ior;
        }
 
        /* Register the partitions */
-       switch(autcpu12_mtd->size){
+       switch (autcpu12_mtd->size) {
                case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
                case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
                case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
                case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
-               default: {
-                       printk ("Unsupported SmartMedia device\n");
+               default:
+                       printk("Unsupported SmartMedia device\n");
                        err = -ENXIO;
                        goto out_ior;
-               }
        }
        goto out;
 
-out_ior:
+ out_ior:
        iounmap((void *)autcpu12_fio_base);
-out_mtd:
-       kfree (autcpu12_mtd);
-out:
+ out_mtd:
+       kfree(autcpu12_mtd);
+ out:
        return err;
 }
 
@@ -204,20 +203,19 @@ module_init(autcpu12_init);
 /*
  * Clean up routine
  */
-#ifdef MODULE
-static void __exit autcpu12_cleanup (void)
+static void __exit autcpu12_cleanup(void)
 {
        /* Release resources, unregister device */
-       nand_release (autcpu12_mtd);
+       nand_release(autcpu12_mtd);
 
        /* unmap physical adress */
        iounmap((void *)autcpu12_fio_base);
 
        /* Free the MTD device structure */
-       kfree (autcpu12_mtd);
+       kfree(autcpu12_mtd);
 }
+
 module_exit(autcpu12_cleanup);
-#endif
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
index 91207a4..bf25125 100644 (file)
@@ -4,6 +4,7 @@
  * (C) 2005, 2006 Red Hat Inc.
  *
  * Author: David Woodhouse <dwmw2@infradead.org>
+ *        Tom Sylla <tom.sylla@amd.com>
  *
  * 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
@@ -22,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
 #include <asm/msr.h>
@@ -48,7 +50,7 @@
 
 /* Pin function selection MSR (IDE vs. flash on the IDE pins) */
 #define MSR_DIVIL_BALL_OPTS    0x51400015
-#define PIN_OPT_IDE            (1<<0)          /* 0 for flash, 1 for IDE */
+#define PIN_OPT_IDE            (1<<0)  /* 0 for flash, 1 for IDE */
 
 /* Registers within the NAND flash controller BAR -- memory mapped */
 #define MM_NAND_DATA           0x00    /* 0 to 0x7ff, in fact */
 #define CS_NAND_ECC_CLRECC     (1<<1)
 #define CS_NAND_ECC_ENECC      (1<<0)
 
+static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+
+       while (unlikely(len > 0x800)) {
+               memcpy_fromio(buf, this->IO_ADDR_R, 0x800);
+               buf += 0x800;
+               len -= 0x800;
+       }
+       memcpy_fromio(buf, this->IO_ADDR_R, len);
+}
+
+static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+
+       while (unlikely(len > 0x800)) {
+               memcpy_toio(this->IO_ADDR_R, buf, 0x800);
+               buf += 0x800;
+               len -= 0x800;
+       }
+       memcpy_toio(this->IO_ADDR_R, buf, len);
+}
+
 static unsigned char cs553x_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
-       unsigned char foo = readb(this->IO_ADDR_R);
-       return foo;
+       return readb(this->IO_ADDR_R);
 }
 
 static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
@@ -103,52 +128,67 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
                udelay(1);
                i--;
        }
-       writeb(byte, this->IO_ADDR_W+0x801);
+       writeb(byte, this->IO_ADDR_W + 0x801);
 }
 
 static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd)
 {
        struct nand_chip *this = mtd->priv;
        void __iomem *mmio_base = this->IO_ADDR_R;
+       unsigned char ctl;
 
-       uint8_t old = readb(mmio_base + MM_NAND_CTL);
-
-       switch(cmd) {
+       switch (cmd) {
        case NAND_CTL_SETCLE:
-               old |= CS_NAND_CTL_CLE;
+               ctl = CS_NAND_CTL_CLE;
                break;
 
        case NAND_CTL_CLRCLE:
-               old &= ~CS_NAND_CTL_CLE;
-               break;
-
-       case NAND_CTL_SETALE:
-               old |= CS_NAND_CTL_ALE;
-               break;
-
        case NAND_CTL_CLRALE:
-               old &= ~CS_NAND_CTL_ALE;
+       case NAND_CTL_SETNCE:
+               ctl = 0;
                break;
 
-       case NAND_CTL_SETNCE:
-               old &= ~CS_NAND_CTL_CE;
+       case NAND_CTL_SETALE:
+               ctl = CS_NAND_CTL_ALE;
                break;
 
+       default:
        case NAND_CTL_CLRNCE:
-               old |= CS_NAND_CTL_CE;
+               ctl = CS_NAND_CTL_CE;
                break;
        }
-       writeb(old, mmio_base + MM_NAND_CTL);
+       writeb(ctl, mmio_base + MM_NAND_CTL);
 }
 
-
 static int cs553x_device_ready(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
        void __iomem *mmio_base = this->IO_ADDR_R;
        unsigned char foo = readb(mmio_base + MM_NAND_STS);
 
-       return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY); 
+       return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY);
+}
+
+static void cs_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+       struct nand_chip *this = mtd->priv;
+       void __iomem *mmio_base = this->IO_ADDR_R;
+
+       writeb(0x07, mmio_base + MM_NAND_ECC_CTL);
+}
+
+static int cs_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+       uint32_t ecc;
+       struct nand_chip *this = mtd->priv;
+       void __iomem *mmio_base = this->IO_ADDR_R;
+
+       ecc = readl(mmio_base + MM_NAND_STS);
+
+       ecc_code[1] = ecc >> 8;
+       ecc_code[0] = ecc >> 16;
+       ecc_code[2] = ecc >> 24;
+       return 0;
 }
 
 static struct mtd_info *cs553x_mtd[4];
@@ -167,7 +207,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        }
 
        /* Allocate memory for MTD device structure and private data */
-       new_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
+       new_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!new_mtd) {
                printk(KERN_WARNING "Unable to allocate CS553X NAND MTD device structure.\n");
                err = -ENOMEM;
@@ -175,14 +215,15 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&new_mtd[1]);
+       this = (struct nand_chip *)(&new_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) new_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(new_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        new_mtd->priv = this;
+       new_mtd->owner = THIS_MODULE;
 
        /* map physical address */
        this->IO_ADDR_R = this->IO_ADDR_W = ioremap(adr, 4096);
@@ -196,16 +237,21 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        this->dev_ready = cs553x_device_ready;
        this->read_byte = cs553x_read_byte;
        this->write_byte = cs553x_write_byte;
+       this->read_buf = cs553x_read_buf;
+       this->write_buf = cs553x_write_buf;
 
-       /* 20 us command delay time */
-       this->chip_delay = 20;
-       this->eccmode = NAND_ECC_SOFT;
+       this->chip_delay = 0;
 
+       this->eccmode = NAND_ECC_HW3_256;
+       this->enable_hwecc  = cs_enable_hwecc;
+       this->calculate_ecc = cs_calculate_ecc;
+       this->correct_data  = nand_correct_data;
+       
        /* Enable the following for a flash based bad block table */
-       //      this->options = NAND_USE_FLASH_BBT;
+       this->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
 
        /* Scan to find existance of the device */
-       if (nand_scan (new_mtd, 1)) {
+       if (nand_scan(new_mtd, 1)) {
                err = -ENXIO;
                goto out_ior;
        }
@@ -216,12 +262,12 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
 out_ior:
        iounmap((void *)this->IO_ADDR_R);
 out_mtd:
-       kfree (new_mtd);
+       kfree(new_mtd);
 out:
        return err;
 }
 
-int __init cs553x_init(void)
+static int __init cs553x_init(void)
 {
        int err = -ENXIO;
        int i;
@@ -238,16 +284,16 @@ int __init cs553x_init(void)
                return -ENXIO;
        }
 
-       for (i=0; i<NR_CS553X_CONTROLLERS; i++) {
-               rdmsrl(MSR_DIVIL_LBAR_FLSH0+i, val);
+       for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
+               rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val);
 
                if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND))
                        err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);
        }
-       
+
        /* Register all devices together here. This means we can easily hack it to 
           do mtdconcat etc. if we want to. */
-       for (i=0; i<NR_CS553X_CONTROLLERS; i++) {
+       for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
                if (cs553x_mtd[i]) {
                        add_mtd_device(cs553x_mtd[i]);
 
@@ -258,13 +304,14 @@ int __init cs553x_init(void)
 
        return err;
 }
+
 module_init(cs553x_init);
 
-static void __exit cs553x_cleanup (void)
+static void __exit cs553x_cleanup(void)
 {
        int i;
 
-       for (i=0; i<NR_CS553X_CONTROLLERS; i++) {
+       for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
                struct mtd_info *mtd = cs553x_mtd[i];
                struct nand_chip *this;
                void __iomem *mmio_base;
@@ -276,16 +323,17 @@ static void __exit cs553x_cleanup (void)
                mmio_base = this->IO_ADDR_R;
 
                /* Release resources, unregister device */
-               nand_release (cs553x_mtd[i]);
+               nand_release(cs553x_mtd[i]);
                cs553x_mtd[i] = NULL;
 
                /* unmap physical adress */
                iounmap(mmio_base);
 
                /* Free the MTD device structure */
-               kfree (mtd);
+               kfree(mtd);
        }
 }
+
 module_exit(cs553x_cleanup);
 
 MODULE_LICENSE("GPL");
index ec5e45e..a2391c6 100644 (file)
@@ -58,10 +58,10 @@ static unsigned long __initdata doc_locations[] = {
        0xe4000000,
 #elif defined(CONFIG_MOMENCO_OCELOT)
        0x2f000000,
-        0xff000000,
+       0xff000000,
 #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
-        0xff000000,
-##else
+       0xff000000,
+#else
 #warning Unknown architecture for DiskOnChip. No default probe locations defined
 #endif
        0xffffffff };
@@ -73,7 +73,7 @@ struct doc_priv {
        unsigned long physadr;
        u_char ChipID;
        u_char CDSNControl;
-       int chips_per_floor; /* The number of chips detected on each floor */
+       int chips_per_floor;    /* The number of chips detected on each floor */
        int curfloor;
        int curchip;
        int mh0_page;
@@ -84,6 +84,7 @@ struct doc_priv {
 /* This is the syndrome computed by the HW ecc generator upon reading an empty
    page, one with all 0xff for data and stored ecc code. */
 static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
+
 /* This is the ecc value computed by the HW ecc generator upon writing an empty
    page, one with all 0xff for data. */
 static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
@@ -97,25 +98,25 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
 static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd);
 static void doc200x_select_chip(struct mtd_info *mtd, int chip);
 
-static int debug=0;
+static int debug = 0;
 module_param(debug, int, 0);
 
-static int try_dword=1;
+static int try_dword = 1;
 module_param(try_dword, int, 0);
 
-static int no_ecc_failures=0;
+static int no_ecc_failures = 0;
 module_param(no_ecc_failures, int, 0);
 
-static int no_autopart=0;
+static int no_autopart = 0;
 module_param(no_autopart, int, 0);
 
-static int show_firmware_partition=0;
+static int show_firmware_partition = 0;
 module_param(show_firmware_partition, int, 0);
 
 #ifdef MTD_NAND_DISKONCHIP_BBTWRITE
-static int inftl_bbt_write=1;
+static int inftl_bbt_write = 1;
 #else
-static int inftl_bbt_write=0;
+static int inftl_bbt_write = 0;
 #endif
 module_param(inftl_bbt_write, int, 0);
 
@@ -123,7 +124,6 @@ static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDR
 module_param(doc_config_location, ulong, 0);
 MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
 
-
 /* Sector size for HW ECC */
 #define SECTOR_SIZE 512
 /* The sector bytes are packed into NB_DATA 10 bit words */
@@ -147,7 +147,7 @@ static struct rs_control *rs_decoder;
  * some comments, improved a minor bit and converted it to make use
  * of the generic Reed-Solomon libary. tglx
  */
-static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
+static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
 {
        int i, j, nerr, errpos[8];
        uint8_t parity;
@@ -168,18 +168,18 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
         *  s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
         *  where x = alpha^(FCR + i)
         */
-       for(j = 1; j < NROOTS; j++) {
-               if(ds[j] == 0)
+       for (j = 1; j < NROOTS; j++) {
+               if (ds[j] == 0)
                        continue;
                tmp = rs->index_of[ds[j]];
-               for(i = 0; i < NROOTS; i++)
+               for (i = 0; i < NROOTS; i++)
                        s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];
        }
 
        /* Calc s[i] = s[i] / alpha^(v + i) */
        for (i = 0; i < NROOTS; i++) {
                if (syn[i])
-                       syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
+                       syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
        }
        /* Call the decoder library */
        nerr = decode_rs16(rs, NULL, NULL, 1019, syn, 0, errpos, 0, errval);
@@ -193,7 +193,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
         * but they are given by the design of the de/encoder circuit
         * in the DoC ASIC's.
         */
-       for(i = 0;i < nerr; i++) {
+       for (i = 0; i < nerr; i++) {
                int index, bitpos, pos = 1015 - errpos[i];
                uint8_t val;
                if (pos >= NB_DATA && pos < 1019)
@@ -205,8 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
                           can be modified since pos is even */
                        index = (pos >> 3) ^ 1;
                        bitpos = pos & 7;
-                       if ((index >= 0 && index < SECTOR_SIZE) ||
-                           index == (SECTOR_SIZE + 1)) {
+                       if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) {
                                val = (uint8_t) (errval[i] >> (2 + bitpos));
                                parity ^= val;
                                if (index < SECTOR_SIZE)
@@ -216,9 +215,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
                        bitpos = (bitpos + 10) & 7;
                        if (bitpos == 0)
                                bitpos = 8;
-                       if ((index >= 0 && index < SECTOR_SIZE) ||
-                           index == (SECTOR_SIZE + 1)) {
-                               val = (uint8_t)(errval[i] << (8 - bitpos));
+                       if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) {
+                               val = (uint8_t) (errval[i] << (8 - bitpos));
                                parity ^= val;
                                if (index < SECTOR_SIZE)
                                        data[index] ^= val;
@@ -250,10 +248,11 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
 /* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
 static int _DoC_WaitReady(struct doc_priv *doc)
 {
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        unsigned long timeo = jiffies + (HZ * 10);
 
-       if(debug) printk("_DoC_WaitReady...\n");
+       if (debug)
+               printk("_DoC_WaitReady...\n");
        /* Out-of-line routine to wait for chip response */
        if (DoC_is_MillenniumPlus(doc)) {
                while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
@@ -280,7 +279,7 @@ static int _DoC_WaitReady(struct doc_priv *doc)
 
 static inline int DoC_WaitReady(struct doc_priv *doc)
 {
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int ret = 0;
 
        if (DoC_is_MillenniumPlus(doc)) {
@@ -298,7 +297,8 @@ static inline int DoC_WaitReady(struct doc_priv *doc)
                DoC_Delay(doc, 2);
        }
 
-       if(debug) printk("DoC_WaitReady OK\n");
+       if (debug)
+               printk("DoC_WaitReady OK\n");
        return ret;
 }
 
@@ -306,9 +306,10 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
-       if(debug)printk("write_byte %02x\n", datum);
+       if (debug)
+               printk("write_byte %02x\n", datum);
        WriteDOC(datum, docptr, CDSNSlowIO);
        WriteDOC(datum, docptr, 2k_CDSN_IO);
 }
@@ -317,77 +318,78 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        u_char ret;
 
        ReadDOC(docptr, CDSNSlowIO);
        DoC_Delay(doc, 2);
        ret = ReadDOC(docptr, 2k_CDSN_IO);
-       if (debug) printk("read_byte returns %02x\n", ret);
+       if (debug)
+               printk("read_byte returns %02x\n", ret);
        return ret;
 }
 
-static void doc2000_writebuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
+static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
-       if (debug)printk("writebuf of %d bytes: ", len);
-       for (i=0; i < len; i++) {
+       if (debug)
+               printk("writebuf of %d bytes: ", len);
+       for (i = 0; i < len; i++) {
                WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);
                if (debug && i < 16)
                        printk("%02x ", buf[i]);
        }
-       if (debug) printk("\n");
+       if (debug)
+               printk("\n");
 }
 
-static void doc2000_readbuf(struct mtd_info *mtd,
-                           u_char *buf, int len)
+static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
-       int i;
+       void __iomem *docptr = doc->virtadr;
+       int i;
 
-       if (debug)printk("readbuf of %d bytes: ", len);
+       if (debug)
+               printk("readbuf of %d bytes: ", len);
 
-       for (i=0; i < len; i++) {
+       for (i = 0; i < len; i++) {
                buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
        }
 }
 
-static void doc2000_readbuf_dword(struct mtd_info *mtd,
-                           u_char *buf, int len)
+static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
-       int i;
+       void __iomem *docptr = doc->virtadr;
+       int i;
 
-       if (debug) printk("readbuf_dword of %d bytes: ", len);
+       if (debug)
+               printk("readbuf_dword of %d bytes: ", len);
 
-       if (unlikely((((unsigned long)buf)|len) & 3)) {
-               for (i=0; i < len; i++) {
-                       *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
+       if (unlikely((((unsigned long)buf) | len) & 3)) {
+               for (i = 0; i < len; i++) {
+                       *(uint8_t *) (&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
                }
        } else {
-               for (i=0; i < len; i+=4) {
-                       *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
+               for (i = 0; i < len; i += 4) {
+                       *(uint32_t *) (&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
                }
        }
 }
 
-static int doc2000_verifybuf(struct mtd_info *mtd,
-                             const u_char *buf, int len)
+static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
-       for (i=0; i < len; i++)
+       for (i = 0; i < len; i++)
                if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
                        return -EFAULT;
        return 0;
@@ -482,7 +484,7 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
        WriteDOC(datum, docptr, CDSNSlowIO);
        WriteDOC(datum, docptr, Mil_CDSN_IO);
@@ -493,7 +495,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
        //ReadDOC(docptr, CDSNSlowIO);
        /* 11.4.5 -- delay twice to allow extended length cycle */
@@ -503,50 +505,47 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
        return ReadDOC(docptr, LastDataRead);
 }
 
-static void doc2001_writebuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
+static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
-       for (i=0; i < len; i++)
+       for (i = 0; i < len; i++)
                WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
        /* Terminate write pipeline */
        WriteDOC(0x00, docptr, WritePipeTerm);
 }
 
-static void doc2001_readbuf(struct mtd_info *mtd,
-                           u_char *buf, int len)
+static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
        /* Start read pipeline */
        ReadDOC(docptr, ReadPipeInit);
 
-       for (i=0; i < len-1; i++)
+       for (i = 0; i < len - 1; i++)
                buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
 
        /* Terminate read pipeline */
        buf[i] = ReadDOC(docptr, LastDataRead);
 }
 
-static int doc2001_verifybuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
+static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
        /* Start read pipeline */
        ReadDOC(docptr, ReadPipeInit);
 
-       for (i=0; i < len-1; i++)
+       for (i = 0; i < len - 1; i++)
                if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
                        ReadDOC(docptr, LastDataRead);
                        return i;
@@ -560,87 +559,90 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        u_char ret;
 
-        ReadDOC(docptr, Mplus_ReadPipeInit);
-        ReadDOC(docptr, Mplus_ReadPipeInit);
-        ret = ReadDOC(docptr, Mplus_LastDataRead);
-       if (debug) printk("read_byte returns %02x\n", ret);
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+       ret = ReadDOC(docptr, Mplus_LastDataRead);
+       if (debug)
+               printk("read_byte returns %02x\n", ret);
        return ret;
 }
 
-static void doc2001plus_writebuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
+static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
-       if (debug)printk("writebuf of %d bytes: ", len);
-       for (i=0; i < len; i++) {
+       if (debug)
+               printk("writebuf of %d bytes: ", len);
+       for (i = 0; i < len; i++) {
                WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
                if (debug && i < 16)
                        printk("%02x ", buf[i]);
        }
-       if (debug) printk("\n");
+       if (debug)
+               printk("\n");
 }
 
-static void doc2001plus_readbuf(struct mtd_info *mtd,
-                           u_char *buf, int len)
+static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
-       if (debug)printk("readbuf of %d bytes: ", len);
+       if (debug)
+               printk("readbuf of %d bytes: ", len);
 
        /* Start read pipeline */
        ReadDOC(docptr, Mplus_ReadPipeInit);
        ReadDOC(docptr, Mplus_ReadPipeInit);
 
-       for (i=0; i < len-2; i++) {
+       for (i = 0; i < len - 2; i++) {
                buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
                if (debug && i < 16)
                        printk("%02x ", buf[i]);
        }
 
        /* Terminate read pipeline */
-       buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
+       buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead);
        if (debug && i < 16)
-               printk("%02x ", buf[len-2]);
-       buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
+               printk("%02x ", buf[len - 2]);
+       buf[len - 1] = ReadDOC(docptr, Mplus_LastDataRead);
        if (debug && i < 16)
-               printk("%02x ", buf[len-1]);
-       if (debug) printk("\n");
+               printk("%02x ", buf[len - 1]);
+       if (debug)
+               printk("\n");
 }
 
-static int doc2001plus_verifybuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
+static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
 
-       if (debug)printk("verifybuf of %d bytes: ", len);
+       if (debug)
+               printk("verifybuf of %d bytes: ", len);
 
        /* Start read pipeline */
        ReadDOC(docptr, Mplus_ReadPipeInit);
        ReadDOC(docptr, Mplus_ReadPipeInit);
 
-       for (i=0; i < len-2; i++)
+       for (i = 0; i < len - 2; i++)
                if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
                        ReadDOC(docptr, Mplus_LastDataRead);
                        ReadDOC(docptr, Mplus_LastDataRead);
                        return i;
                }
-       if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead))
-               return len-2;
-       if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead))
-               return len-1;
+       if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead))
+               return len - 2;
+       if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead))
+               return len - 1;
        return 0;
 }
 
@@ -648,10 +650,11 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int floor = 0;
 
-       if(debug)printk("select chip (%d)\n", chip);
+       if (debug)
+               printk("select chip (%d)\n", chip);
 
        if (chip == -1) {
                /* Disable flash internally */
@@ -660,7 +663,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
        }
 
        floor = chip / doc->chips_per_floor;
-       chip -= (floor *  doc->chips_per_floor);
+       chip -= (floor * doc->chips_per_floor);
 
        /* Assert ChipEnable and deassert WriteProtect */
        WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
@@ -674,16 +677,17 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int floor = 0;
 
-       if(debug)printk("select chip (%d)\n", chip);
+       if (debug)
+               printk("select chip (%d)\n", chip);
 
        if (chip == -1)
                return;
 
        floor = chip / doc->chips_per_floor;
-       chip -= (floor *  doc->chips_per_floor);
+       chip -= (floor * doc->chips_per_floor);
 
        /* 11.4.4 -- deassert CE before changing chip */
        doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
@@ -701,9 +705,9 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
-       switch(cmd) {
+       switch (cmd) {
        case NAND_CTL_SETNCE:
                doc->CDSNControl |= CDSN_CTRL_CE;
                break;
@@ -729,17 +733,18 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
                doc->CDSNControl &= ~CDSN_CTRL_WP;
                break;
        }
-       if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
+       if (debug)
+               printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
        WriteDOC(doc->CDSNControl, docptr, CDSNControl);
        /* 11.4.3 -- 4 NOPs after CSDNControl write */
        DoC_Delay(doc, 4);
 }
 
-static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
        /*
         * Must terminate write pipeline before sending any commands
@@ -782,25 +787,26 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
                        WriteDOC(column, docptr, Mplus_FlashAddress);
                }
                if (page_addr != -1) {
-                       WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress);
-                       WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
+                       WriteDOC((unsigned char)(page_addr & 0xff), docptr, Mplus_FlashAddress);
+                       WriteDOC((unsigned char)((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
                        /* One more address cycle for higher density devices */
                        if (this->chipsize & 0x0c000000) {
-                               WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
+                               WriteDOC((unsigned char)((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
                                printk("high density\n");
                        }
                }
                WriteDOC(0, docptr, Mplus_WritePipeTerm);
                WriteDOC(0, docptr, Mplus_WritePipeTerm);
                /* deassert ALE */
-               if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID)
+               if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
+                   command == NAND_CMD_READOOB || command == NAND_CMD_READID)
                        WriteDOC(0, docptr, Mplus_FlashControl);
        }
 
        /*
         * program and erase have their own busy handlers
         * status and sequential in needs no delay
-       */
+        */
        switch (command) {
 
        case NAND_CMD_PAGEPROG:
@@ -817,55 +823,57 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
                WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
                WriteDOC(0, docptr, Mplus_WritePipeTerm);
                WriteDOC(0, docptr, Mplus_WritePipeTerm);
-               while ( !(this->read_byte(mtd) & 0x40));
+               while (!(this->read_byte(mtd) & 0x40)) ;
                return;
 
-       /* This applies to read commands */
+               /* This applies to read commands */
        default:
                /*
                 * If we don't have access to the busy pin, we apply the given
                 * command delay
-               */
+                */
                if (!this->dev_ready) {
-                       udelay (this->chip_delay);
+                       udelay(this->chip_delay);
                        return;
                }
        }
 
        /* Apply this short delay always to ensure that we do wait tWB in
         * any case on any machine. */
-       ndelay (100);
+       ndelay(100);
        /* wait until command is processed */
-       while (!this->dev_ready(mtd));
+       while (!this->dev_ready(mtd)) ;
 }
 
 static int doc200x_dev_ready(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
        if (DoC_is_MillenniumPlus(doc)) {
                /* 11.4.2 -- must NOP four times before checking FR/B# */
                DoC_Delay(doc, 4);
                if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
-                       if(debug)
+                       if (debug)
                                printk("not ready\n");
                        return 0;
                }
-               if (debug)printk("was ready\n");
+               if (debug)
+                       printk("was ready\n");
                return 1;
        } else {
                /* 11.4.2 -- must NOP four times before checking FR/B# */
                DoC_Delay(doc, 4);
                if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-                       if(debug)
+                       if (debug)
                                printk("not ready\n");
                        return 0;
                }
                /* 11.4.2 -- Must NOP twice if it's ready */
                DoC_Delay(doc, 2);
-               if (debug)printk("was ready\n");
+               if (debug)
+                       printk("was ready\n");
                return 1;
        }
 }
@@ -881,10 +889,10 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
        /* Prime the ECC engine */
-       switch(mode) {
+       switch (mode) {
        case NAND_ECC_READ:
                WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
                WriteDOC(DOC_ECC_EN, docptr, ECCConf);
@@ -900,10 +908,10 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
 
        /* Prime the ECC engine */
-       switch(mode) {
+       switch (mode) {
        case NAND_ECC_READ:
                WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
                WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
@@ -916,12 +924,11 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
 }
 
 /* This code is only called on write */
-static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-                                unsigned char *ecc_code)
+static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        int i;
        int emptymatch = 1;
 
@@ -961,7 +968,8 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
                   often.  It could be optimized away by examining the data in
                   the writebuf routine, and remembering the result. */
                for (i = 0; i < 512; i++) {
-                       if (dat[i] == 0xff) continue;
+                       if (dat[i] == 0xff)
+                               continue;
                        emptymatch = 0;
                        break;
                }
@@ -969,7 +977,8 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
        /* If emptymatch still =1, we do have an all-0xff data buffer.
           Return all-0xff ecc value instead of the computed one, so
           it'll look just like a freshly-erased page. */
-       if (emptymatch) memset(ecc_code, 0xff, 6);
+       if (emptymatch)
+               memset(ecc_code, 0xff, 6);
 #endif
        return 0;
 }
@@ -979,7 +988,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
        int i, ret = 0;
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
-        void __iomem *docptr = doc->virtadr;
+       void __iomem *docptr = doc->virtadr;
        volatile u_char dummy;
        int emptymatch = 1;
 
@@ -1012,18 +1021,20 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
                   all-0xff data and stored ecc block.  Check the stored ecc. */
                if (emptymatch) {
                        for (i = 0; i < 6; i++) {
-                               if (read_ecc[i] == 0xff) continue;
+                               if (read_ecc[i] == 0xff)
+                                       continue;
                                emptymatch = 0;
                                break;
                        }
                }
                /* If emptymatch still =1, check the data block. */
                if (emptymatch) {
-               /* Note: this somewhat expensive test should not be triggered
-                  often.  It could be optimized away by examining the data in
-                  the readbuf routine, and remembering the result. */
+                       /* Note: this somewhat expensive test should not be triggered
+                          often.  It could be optimized away by examining the data in
+                          the readbuf routine, and remembering the result. */
                        for (i = 0; i < 512; i++) {
-                               if (dat[i] == 0xff) continue;
+                               if (dat[i] == 0xff)
+                                       continue;
                                emptymatch = 0;
                                break;
                        }
@@ -1032,7 +1043,8 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
                   erased block, in which case the ECC will not come out right.
                   We'll suppress the error and tell the caller everything's
                   OK.  Because it is. */
-               if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
+               if (!emptymatch)
+                       ret = doc_ecc_decode(rs_decoder, dat, calc_ecc);
                if (ret > 0)
                        printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
        }
@@ -1060,10 +1072,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
  * be able to handle out-of-order segments.
  */
 static struct nand_oobinfo doc200x_oobinfo = {
-        .useecc = MTD_NANDECC_AUTOPLACE,
-        .eccbytes = 6,
-        .eccpos = {0, 1, 2, 3, 4, 5},
-        .oobfree = { {8, 8}, {6, 2} }
+       .useecc = MTD_NANDECC_AUTOPLACE,
+       .eccbytes = 6,
+       .eccpos = {0, 1, 2, 3, 4, 5},
+       .oobfree = {{8, 8}, {6, 2}}
 };
 
 /* Find the (I)NFTL Media Header, and optionally also the mirror media header.
@@ -1072,8 +1084,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
    either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media
    header.  The page #s of the found media headers are placed in mh0_page and
    mh1_page in the DOC private structure. */
-static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
-                                    const char *id, int findmirror)
+static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
@@ -1083,16 +1094,18 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
 
        for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
                ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
-               if (retlen != mtd->oobblock) continue;
+               if (retlen != mtd->oobblock)
+                       continue;
                if (ret) {
-                       printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n",
-                               offs);
+                       printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", offs);
                }
-               if (memcmp(buf, id, 6)) continue;
+               if (memcmp(buf, id, 6))
+                       continue;
                printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);
                if (doc->mh0_page == -1) {
                        doc->mh0_page = offs >> this->page_shift;
-                       if (!findmirror) return 1;
+                       if (!findmirror)
+                               return 1;
                        continue;
                }
                doc->mh1_page = offs >> this->page_shift;
@@ -1114,8 +1127,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
        return 1;
 }
 
-static inline int __init nftl_partscan(struct mtd_info *mtd,
-                               struct mtd_partition *parts)
+static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
@@ -1132,8 +1144,9 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
                printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
                return 0;
        }
-       if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
-       mh = (struct NFTLMediaHeader *) buf;
+       if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1)))
+               goto out;
+       mh = (struct NFTLMediaHeader *)buf;
 
        mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits);
        mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN);
@@ -1155,8 +1168,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
                /* Auto-determine UnitSizeFactor.  The constraints are:
                   - There can be at most 32768 virtual blocks.
                   - There can be at most (virtual block size - page size)
-                    virtual blocks (because MediaHeader+BBT must fit in 1).
-               */
+                  virtual blocks (because MediaHeader+BBT must fit in 1).
+                */
                mh->UnitSizeFactor = 0xff;
                while (blocks > maxblocks) {
                        blocks >>= 1;
@@ -1211,14 +1224,13 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
        }
 
        ret = numparts;
-out:
+ out:
        kfree(buf);
        return ret;
 }
 
 /* This is a stripped-down copy of the code in inftlmount.c */
-static inline int __init inftl_partscan(struct mtd_info *mtd,
-                                struct mtd_partition *parts)
+static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts)
 {
        struct nand_chip *this = mtd->priv;
        struct doc_priv *doc = this->priv;
@@ -1241,9 +1253,10 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
                return 0;
        }
 
-       if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out;
+       if (!find_media_headers(mtd, buf, "BNAND", 0))
+               goto out;
        doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift);
-       mh = (struct INFTLMediaHeader *) buf;
+       mh = (struct INFTLMediaHeader *)buf;
 
        mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
        mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
@@ -1319,8 +1332,10 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
                parts[numparts].offset = ip->firstUnit << vshift;
                parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift;
                numparts++;
-               if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit;
-               if (ip->flags & INFTL_LAST) break;
+               if (ip->lastUnit > lastvunit)
+                       lastvunit = ip->lastUnit;
+               if (ip->flags & INFTL_LAST)
+                       break;
        }
        lastvunit++;
        if ((lastvunit << vshift) < end) {
@@ -1330,7 +1345,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
                numparts++;
        }
        ret = numparts;
-out:
+ out:
        kfree(buf);
        return ret;
 }
@@ -1342,11 +1357,12 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd)
        struct doc_priv *doc = this->priv;
        struct mtd_partition parts[2];
 
-       memset((char *) parts, 0, sizeof(parts));
+       memset((char *)parts, 0, sizeof(parts));
        /* On NFTL, we have to find the media headers before we can read the
           BBTs, since they're stored in the media header eraseblocks. */
        numparts = nftl_partscan(mtd, parts);
-       if (!numparts) return -EIO;
+       if (!numparts)
+               return -EIO;
        this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |
                                NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |
                                NAND_BBT_VERSION;
@@ -1393,8 +1409,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
                this->bbt_td->pages[0] = 2;
                this->bbt_md = NULL;
        } else {
-               this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
-                                       NAND_BBT_VERSION;
+               this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION;
                if (inftl_bbt_write)
                        this->bbt_td->options |= NAND_BBT_WRITE;
                this->bbt_td->offs = 8;
@@ -1404,8 +1419,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
                this->bbt_td->reserved_block_code = 0x01;
                this->bbt_td->pattern = "MSYS_BBT";
 
-               this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
-                                       NAND_BBT_VERSION;
+               this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION;
                if (inftl_bbt_write)
                        this->bbt_md->options |= NAND_BBT_WRITE;
                this->bbt_md->offs = 8;
@@ -1420,12 +1434,13 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
           At least as nand_bbt.c is currently written. */
        if ((ret = nand_scan_bbt(mtd, NULL)))
                return ret;
-       memset((char *) parts, 0, sizeof(parts));
+       memset((char *)parts, 0, sizeof(parts));
        numparts = inftl_partscan(mtd, parts);
        /* At least for now, require the INFTL Media Header.  We could probably
           do without it for non-INFTL use, since all it gives us is
           autopartitioning, but I want to give it more thought. */
-       if (!numparts) return -EIO;
+       if (!numparts)
+               return -EIO;
        add_mtd_device(mtd);
 #ifdef CONFIG_MTD_PARTITIONS
        if (!no_autopart)
@@ -1535,20 +1550,16 @@ static int __init doc_probe(unsigned long physadr)
        save_control = ReadDOC(virtadr, DOCControl);
 
        /* Reset the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-                virtadr, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-                virtadr, DOCControl);
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl);
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl);
 
        /* Enable the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-                virtadr, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-                virtadr, DOCControl);
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl);
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl);
 
        ChipID = ReadDOC(virtadr, ChipID);
 
-       switch(ChipID) {
+       switch (ChipID) {
        case DOC_ChipID_Doc2k:
                reg = DoC_2k_ECCStatus;
                break;
@@ -1564,15 +1575,13 @@ static int __init doc_probe(unsigned long physadr)
                        ReadDOC(virtadr, Mplus_Power);
 
                /* Reset the Millennium Plus ASIC */
-               tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-                       DOC_MODE_BDECT;
+               tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT;
                WriteDOC(tmp, virtadr, Mplus_DOCControl);
                WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
 
                mdelay(1);
                /* Enable the Millennium Plus ASIC */
-               tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-                       DOC_MODE_BDECT;
+               tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT;
                WriteDOC(tmp, virtadr, Mplus_DOCControl);
                WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
                mdelay(1);
@@ -1596,7 +1605,7 @@ static int __init doc_probe(unsigned long physadr)
                goto notfound;
        }
        /* Check the TOGGLE bit in the ECC register */
-       tmp  = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
+       tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
        tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
        tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
        if ((tmp == tmpb) || (tmp != tmpc)) {
@@ -1626,11 +1635,11 @@ static int __init doc_probe(unsigned long physadr)
                if (ChipID == DOC_ChipID_DocMilPlus16) {
                        WriteDOC(~newval, virtadr, Mplus_AliasResolution);
                        oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
-                       WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it
+                       WriteDOC(newval, virtadr, Mplus_AliasResolution);       // restore it
                } else {
                        WriteDOC(~newval, virtadr, AliasResolution);
                        oldval = ReadDOC(doc->virtadr, AliasResolution);
-                       WriteDOC(newval, virtadr, AliasResolution); // restore it
+                       WriteDOC(newval, virtadr, AliasResolution);     // restore it
                }
                newval = ~newval;
                if (oldval == newval) {
@@ -1642,10 +1651,8 @@ static int __init doc_probe(unsigned long physadr)
        printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr);
 
        len = sizeof(struct mtd_info) +
-             sizeof(struct nand_chip) +
-             sizeof(struct doc_priv) +
-             (2 * sizeof(struct nand_bbt_descr));
-       mtd =  kmalloc(len, GFP_KERNEL);
+           sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr));
+       mtd = kmalloc(len, GFP_KERNEL);
        if (!mtd) {
                printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len);
                ret = -ENOMEM;
@@ -1707,18 +1714,18 @@ static int __init doc_probe(unsigned long physadr)
        doclist = mtd;
        return 0;
 
-notfound:
+ notfound:
        /* Put back the contents of the DOCControl register, in case it's not
           actually a DiskOnChip.  */
        WriteDOC(save_control, virtadr, DOCControl);
-fail:
+ fail:
        iounmap(virtadr);
        return ret;
 }
 
 static void release_nanddoc(void)
 {
-       struct mtd_info *mtd, *nextmtd;
+       struct mtd_info *mtd, *nextmtd;
        struct nand_chip *nand;
        struct doc_priv *doc;
 
@@ -1747,8 +1754,8 @@ static int __init init_nanddoc(void)
         * generator polinomial degree = 4
         */
        rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS);
-       if (!rs_decoder) {
-               printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n");
+       if (!rs_decoder) {
+               printk(KERN_ERR "DiskOnChip: Could not create a RS decoder\n");
                return -ENOMEM;
        }
 
@@ -1758,7 +1765,7 @@ static int __init init_nanddoc(void)
                if (ret < 0)
                        goto outerr;
        } else {
-               for (i=0; (doc_locations[i] != 0xffffffff); i++) {
+               for (i = 0; (doc_locations[i] != 0xffffffff); i++) {
                        doc_probe(doc_locations[i]);
                }
        }
@@ -1770,7 +1777,7 @@ static int __init init_nanddoc(void)
                goto outerr;
        }
        return 0;
-outerr:
+ outerr:
        free_rs(rs_decoder);
        return ret;
 }
index 9b1fd2f..8e56570 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/mtd/nand/edb7312.c
  *
- *  Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
+ *  Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
  *
  *  Derived from drivers/mtd/nand/autcpu12.c
  *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
@@ -25,7 +25,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <asm/io.h>
-#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
+#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
 #include <asm/sizes.h>
 #include <asm/hardware/clps7111.h>
 
@@ -54,29 +54,29 @@ static struct mtd_info *ep7312_mtd = NULL;
  */
 
 static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE;
-static void __iomem * ep7312_pxdr = (void __iomem *) EP7312_PXDR;
-static void __iomem * ep7312_pxddr = (void __iomem *) EP7312_PXDDR;
+static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
+static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
 
 #ifdef CONFIG_MTD_PARTITIONS
 /*
  * Define static partitions for flash device
  */
 static struct mtd_partition partition_info[] = {
-       { .name = "EP7312 Nand Flash",
-                 .offset = 0,
-                 .size = 8*1024*1024 }
+       {.name = "EP7312 Nand Flash",
+        .offset = 0,
+        .size = 8 * 1024 * 1024}
 };
+
 #define NUM_PARTITIONS 1
 
 #endif
 
-
 /*
  *     hardware specific access to control-lines
  */
 static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
 {
-       switch(cmd) {
+       switch (cmd) {
 
        case NAND_CTL_SETCLE:
                clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
@@ -108,6 +108,7 @@ static int ep7312_device_ready(struct mtd_info *mtd)
 {
        return 1;
 }
+
 #ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
 #endif
@@ -115,18 +116,16 @@ const char *part_probes[] = { "cmdlinepart", NULL };
 /*
  * Main initialization routine
  */
-static int __init ep7312_init (void)
+static int __init ep7312_init(void)
 {
        struct nand_chip *this;
        const char *part_type = 0;
        int mtd_parts_nb = 0;
        struct mtd_partition *mtd_parts = 0;
-       void __iomem * ep7312_fio_base;
+       void __iomem *ep7312_fio_base;
 
        /* Allocate memory for MTD device structure and private data */
-       ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
-                            sizeof(struct nand_chip),
-                            GFP_KERNEL);
+       ep7312_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!ep7312_mtd) {
                printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
                return -ENOMEM;
@@ -134,21 +133,22 @@ static int __init ep7312_init (void)
 
        /* map physical adress */
        ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
-       if(!ep7312_fio_base) {
+       if (!ep7312_fio_base) {
                printk("ioremap EDB7312 NAND flash failed\n");
                kfree(ep7312_mtd);
                return -EIO;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&ep7312_mtd[1]);
+       this = (struct nand_chip *)(&ep7312_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(ep7312_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        ep7312_mtd->priv = this;
+       ep7312_mtd->owner = THIS_MODULE;
 
        /*
         * Set GPIO Port B control register so that the pins are configured
@@ -165,16 +165,14 @@ static int __init ep7312_init (void)
        this->chip_delay = 15;
 
        /* Scan to find existence of the device */
-       if (nand_scan (ep7312_mtd, 1)) {
+       if (nand_scan(ep7312_mtd, 1)) {
                iounmap((void *)ep7312_fio_base);
-               kfree (ep7312_mtd);
+               kfree(ep7312_mtd);
                return -ENXIO;
        }
-
 #ifdef CONFIG_MTD_PARTITIONS
        ep7312_mtd->name = "edb7312-nand";
-       mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
-                                           &mtd_parts, 0);
+       mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
        if (mtd_parts_nb > 0)
                part_type = "command line";
        else
@@ -193,24 +191,26 @@ static int __init ep7312_init (void)
        /* Return happy */
        return 0;
 }
+
 module_init(ep7312_init);
 
 /*
  * Clean up routine
  */
-static void __exit ep7312_cleanup (void)
+static void __exit ep7312_cleanup(void)
 {
-       struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
+       struct nand_chip *this = (struct nand_chip *)&ep7312_mtd[1];
 
        /* Release resources, unregister device */
-       nand_release (ap7312_mtd);
+       nand_release(ap7312_mtd);
 
        /* Free internal data buffer */
-       kfree (this->data_buf);
+       kfree(this->data_buf);
 
        /* Free the MTD device structure */
-       kfree (ep7312_mtd);
+       kfree(ep7312_mtd);
 }
+
 module_exit(ep7312_cleanup);
 
 MODULE_LICENSE("GPL");
index f68f7a9..9848eb0 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (C) 2003 Joshua Wise (joshua@joshuawise.com)
  *
  *  Derived from drivers/mtd/nand/edb7312.c
- *       Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
+ *       Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
  *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
  *
  * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
@@ -26,7 +26,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <asm/io.h>
-#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
+#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
 #include <asm/sizes.h>
 #include <asm/arch/h1900-gpio.h>
 #include <asm/arch/ipaq.h>
@@ -45,23 +45,23 @@ static struct mtd_info *h1910_nand_mtd = NULL;
  * Define static partitions for flash device
  */
 static struct mtd_partition partition_info[] = {
-       { name: "h1910 NAND Flash",
-                 offset: 0,
-                 size: 16*1024*1024 }
+      {name:"h1910 NAND Flash",
+             offset:0,
+      size:16 * 1024 * 1024}
 };
+
 #define NUM_PARTITIONS 1
 
 #endif
 
-
 /*
  *     hardware specific access to control-lines
  */
 static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
 {
-       struct nand_chip* this = (struct nand_chip *) (mtd->priv);
+       struct nand_chip *this = (struct nand_chip *)(mtd->priv);
 
-       switch(cmd) {
+       switch (cmd) {
 
        case NAND_CTL_SETCLE:
                this->IO_ADDR_R |= (1 << 2);
@@ -101,7 +101,7 @@ static int h1910_device_ready(struct mtd_info *mtd)
 /*
  * Main initialization routine
  */
-static int __init h1910_init (void)
+static int __init h1910_init(void)
 {
        struct nand_chip *this;
        const char *part_type = 0;
@@ -119,24 +119,23 @@ static int __init h1910_init (void)
        }
 
        /* Allocate memory for MTD device structure and private data */
-       h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
-                            sizeof(struct nand_chip),
-                            GFP_KERNEL);
+       h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!h1910_nand_mtd) {
                printk("Unable to allocate h1910 NAND MTD device structure.\n");
-               iounmap ((void *) nandaddr);
+               iounmap((void *)nandaddr);
                return -ENOMEM;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&h1910_nand_mtd[1]);
+       this = (struct nand_chip *)(&h1910_nand_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(h1910_nand_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        h1910_nand_mtd->priv = this;
+       h1910_nand_mtd->owner = THIS_MODULE;
 
        /*
         * Enable VPEN
@@ -154,23 +153,20 @@ static int __init h1910_init (void)
        this->options = NAND_NO_AUTOINCR;
 
        /* Scan to find existence of the device */
-       if (nand_scan (h1910_nand_mtd, 1)) {
+       if (nand_scan(h1910_nand_mtd, 1)) {
                printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
-               kfree (h1910_nand_mtd);
-               iounmap ((void *) nandaddr);
+               kfree(h1910_nand_mtd);
+               iounmap((void *)nandaddr);
                return -ENXIO;
        }
-
 #ifdef CONFIG_MTD_CMDLINE_PARTS
-       mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
-                                               "h1910-nand");
+       mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand");
        if (mtd_parts_nb > 0)
-         part_type = "command line";
+               part_type = "command line";
        else
-         mtd_parts_nb = 0;
+               mtd_parts_nb = 0;
 #endif
-       if (mtd_parts_nb == 0)
-       {
+       if (mtd_parts_nb == 0) {
                mtd_parts = partition_info;
                mtd_parts_nb = NUM_PARTITIONS;
                part_type = "static";
@@ -183,24 +179,26 @@ static int __init h1910_init (void)
        /* Return happy */
        return 0;
 }
+
 module_init(h1910_init);
 
 /*
  * Clean up routine
  */
-static void __exit h1910_cleanup (void)
+static void __exit h1910_cleanup(void)
 {
-       struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
+       struct nand_chip *this = (struct nand_chip *)&h1910_nand_mtd[1];
 
        /* Release resources, unregister device */
-       nand_release (h1910_nand_mtd);
+       nand_release(h1910_nand_mtd);
 
        /* Release io resource */
-       iounmap ((void *) this->IO_ADDR_W);
+       iounmap((void *)this->IO_ADDR_W);
 
        /* Free the MTD device structure */
-       kfree (h1910_nand_mtd);
+       kfree(h1910_nand_mtd);
 }
+
 module_exit(h1910_cleanup);
 
 MODULE_LICENSE("GPL");
index 95e96fa..08dffb7 100644 (file)
@@ -69,6 +69,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -92,24 +93,24 @@ static struct nand_oobinfo nand_oob_8 = {
        .useecc = MTD_NANDECC_AUTOPLACE,
        .eccbytes = 3,
        .eccpos = {0, 1, 2},
-       .oobfree = { {3, 2}, {6, 2} }
+       .oobfree = {{3, 2}, {6, 2}}
 };
 
 static struct nand_oobinfo nand_oob_16 = {
        .useecc = MTD_NANDECC_AUTOPLACE,
        .eccbytes = 6,
        .eccpos = {0, 1, 2, 3, 6, 7},
-       .oobfree = { {8, 8} }
+       .oobfree = {{8, 8}}
 };
 
 static struct nand_oobinfo nand_oob_64 = {
        .useecc = MTD_NANDECC_AUTOPLACE,
        .eccbytes = 24,
        .eccpos = {
-               40, 41, 42, 43, 44, 45, 46, 47,
-               48, 49, 50, 51, 52, 53, 54, 55,
-               56, 57, 58, 59, 60, 61, 62, 63},
-       .oobfree = { {2, 38} }
+                  40, 41, 42, 43, 44, 45, 46, 47,
+                  48, 49, 50, 51, 52, 53, 54, 55,
+                  56, 57, 58, 59, 60, 61, 62, 63},
+       .oobfree = {{2, 38}}
 };
 
 /* This is used for padding purposes in nand_write_oob */
@@ -131,32 +132,32 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
 static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
 
-static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
-static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                         size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
-static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
-static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
-static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
-static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
-static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
-                       unsigned long count, loff_t to, size_t * retlen);
-static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
-                       unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
-static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
-static void nand_sync (struct mtd_info *mtd);
+static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+static int nand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+                        size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
+static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+                         size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
+static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
+static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
+                          unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf,
+                          struct nand_oobinfo *oobsel);
+static int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
+static void nand_sync(struct mtd_info *mtd);
 
 /* Some internal functions */
-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
-               struct nand_oobinfo *oobsel, int mode);
+static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int page, u_char * oob_buf,
+                          struct nand_oobinfo *oobsel, int mode);
 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
-       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
+static int nand_verify_pages(struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
+                            u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
 #else
 #define nand_verify_pages(...) (0)
 #endif
 
-static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
+static int nand_get_device(struct nand_chip *this, struct mtd_info *mtd, int new_state);
 
 /**
  * nand_release_device - [GENERIC] release chip
@@ -164,7 +165,7 @@ static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int ne
  *
  * Deselect, release chip lock and wake up anyone waiting on the device
  */
-static void nand_release_device (struct mtd_info *mtd)
+static void nand_release_device(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
@@ -276,7 +277,7 @@ static void nand_write_word(struct mtd_info *mtd, u16 word)
 static void nand_select_chip(struct mtd_info *mtd, int chip)
 {
        struct nand_chip *this = mtd->priv;
-       switch(chip) {
+       switch (chip) {
        case -1:
                this->hwcontrol(mtd, NAND_CTL_CLRNCE);
                break;
@@ -302,7 +303,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
        int i;
        struct nand_chip *this = mtd->priv;
 
-       for (i=0; i<len; i++)
+       for (i = 0; i < len; i++)
                writeb(buf[i], this->IO_ADDR_W);
 }
 
@@ -319,7 +320,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
        int i;
        struct nand_chip *this = mtd->priv;
 
-       for (i=0; i<len; i++)
+       for (i = 0; i < len; i++)
                buf[i] = readb(this->IO_ADDR_R);
 }
 
@@ -336,7 +337,7 @@ static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
        int i;
        struct nand_chip *this = mtd->priv;
 
-       for (i=0; i<len; i++)
+       for (i = 0; i < len; i++)
                if (buf[i] != readb(this->IO_ADDR_R))
                        return -EFAULT;
 
@@ -358,7 +359,7 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
        u16 *p = (u16 *) buf;
        len >>= 1;
 
-       for (i=0; i<len; i++)
+       for (i = 0; i < len; i++)
                writew(p[i], this->IO_ADDR_W);
 
 }
@@ -378,7 +379,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
        u16 *p = (u16 *) buf;
        len >>= 1;
 
-       for (i=0; i<len; i++)
+       for (i = 0; i < len; i++)
                p[i] = readw(this->IO_ADDR_R);
 }
 
@@ -397,7 +398,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
        u16 *p = (u16 *) buf;
        len >>= 1;
 
-       for (i=0; i<len; i++)
+       for (i = 0; i < len; i++)
                if (p[i] != readw(this->IO_ADDR_R))
                        return -EFAULT;
 
@@ -423,22 +424,22 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
                chipnr = (int)(ofs >> this->chip_shift);
 
                /* Grab the lock and see if the device is available */
-               nand_get_device (this, mtd, FL_READING);
+               nand_get_device(this, mtd, FL_READING);
 
                /* Select the NAND device */
                this->select_chip(mtd, chipnr);
        } else
-               page = (int) ofs;
+               page = (int)ofs;
 
        if (this->options & NAND_BUSWIDTH_16) {
-               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
+               this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
                bad = cpu_to_le16(this->read_word(mtd));
                if (this->badblockpos & 0x1)
                        bad >>= 8;
                if ((bad & 0xFF) != 0xff)
                        res = 1;
        } else {
-               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
+               this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
                if (this->read_byte(mtd) != 0xff)
                        res = 1;
        }
@@ -462,22 +463,22 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
        struct nand_chip *this = mtd->priv;
-       u_char buf[2] = {0, 0};
-       size_t  retlen;
+       u_char buf[2] = { 0, 0 };
+       size_t retlen;
        int block;
 
        /* Get block number */
-       block = ((int) ofs) >> this->bbt_erase_shift;
+       block = ((int)ofs) >> this->bbt_erase_shift;
        if (this->bbt)
                this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
        /* Do we have a flash based bad block table ? */
        if (this->options & NAND_USE_FLASH_BBT)
-               return nand_update_bbt (mtd, ofs);
+               return nand_update_bbt(mtd, ofs);
 
        /* We write two bytes, so we dont have to mess with 16 bit access */
        ofs += mtd->oobsize + (this->badblockpos & ~0x01);
-       return nand_write_oob (mtd, ofs , 2, &retlen, buf);
+       return nand_write_oob(mtd, ofs, 2, &retlen, buf);
 }
 
 /**
@@ -487,11 +488,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
  *
  * The function expects, that the device is already selected
  */
-static int nand_check_wp (struct mtd_info *mtd)
+static int nand_check_wp(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
        /* Check the WP bit */
-       this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
        return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
 }
 
@@ -505,7 +506,7 @@ static int nand_check_wp (struct mtd_info *mtd)
  * Check, if the block is bad. Either by reading the bad block table or
  * calling of the scan function.
  */
-static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
+static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
 {
        struct nand_chip *this = mtd->priv;
 
@@ -513,7 +514,7 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i
                return this->block_bad(mtd, ofs, getchip);
 
        /* Return info from the table */
-       return nand_isbad_bbt (mtd, ofs, allowbbt);
+       return nand_isbad_bbt(mtd, ofs, allowbbt);
 }
 
 DEFINE_LED_TRIGGER(nand_led_trigger);
@@ -525,7 +526,7 @@ DEFINE_LED_TRIGGER(nand_led_trigger);
 static void nand_wait_ready(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
-       unsigned long   timeo = jiffies + 2;
+       unsigned long timeo = jiffies + 2;
 
        led_trigger_event(nand_led_trigger, LED_FULL);
        /* wait until command is processed or timeout occures */
@@ -547,7 +548,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
  * Send command to NAND device. This function is used for small page
  * devices (256/512 Bytes per page)
  */
-static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+static void nand_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
 {
        register struct nand_chip *this = mtd->priv;
 
@@ -588,11 +589,11 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
                        this->write_byte(mtd, column);
                }
                if (page_addr != -1) {
-                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
+                       this->write_byte(mtd, (unsigned char)(page_addr & 0xff));
+                       this->write_byte(mtd, (unsigned char)((page_addr >> 8) & 0xff));
                        /* One more address cycle for devices > 32MiB */
                        if (this->chipsize > (32 << 20))
-                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
+                               this->write_byte(mtd, (unsigned char)((page_addr >> 16) & 0x0f));
                }
                /* Latch in address */
                this->hwcontrol(mtd, NAND_CTL_CLRALE);
@@ -601,7 +602,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
        /*
         * program and erase have their own busy handlers
         * status and sequential in needs no delay
-       */
+        */
        switch (command) {
 
        case NAND_CMD_PAGEPROG:
@@ -618,23 +619,23 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
                this->hwcontrol(mtd, NAND_CTL_SETCLE);
                this->write_byte(mtd, NAND_CMD_STATUS);
                this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-               while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
+               while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ;
                return;
 
-       /* This applies to read commands */
+               /* This applies to read commands */
        default:
                /*
                 * If we don't have access to the busy pin, we apply the given
                 * command delay
-               */
+                */
                if (!this->dev_ready) {
-                       udelay (this->chip_delay);
+                       udelay(this->chip_delay);
                        return;
                }
        }
        /* Apply this short delay always to ensure that we do wait tWB in
         * any case on any machine. */
-       ndelay (100);
+       ndelay(100);
 
        nand_wait_ready(mtd);
 }
@@ -647,11 +648,11 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
  * @page_addr: the page address for this command, -1 if none
  *
  * Send command to NAND device. This is the version for the new large page devices
- * We dont have the seperate regions as we have in the small page devices.
+ * We dont have the separate regions as we have in the small page devices.
  * We must emulate NAND_CMD_READOOB to keep the code compatible.
  *
  */
-static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column, int page_addr)
 {
        register struct nand_chip *this = mtd->priv;
 
@@ -661,7 +662,6 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
                command = NAND_CMD_READ0;
        }
 
-
        /* Begin command latch cycle */
        this->hwcontrol(mtd, NAND_CTL_SETCLE);
        /* Write out the command to the device. */
@@ -681,11 +681,11 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
                        this->write_byte(mtd, column >> 8);
                }
                if (page_addr != -1) {
-                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
+                       this->write_byte(mtd, (unsigned char)(page_addr & 0xff));
+                       this->write_byte(mtd, (unsigned char)((page_addr >> 8) & 0xff));
                        /* One more address cycle for devices > 128MiB */
                        if (this->chipsize > (128 << 20))
-                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
+                               this->write_byte(mtd, (unsigned char)((page_addr >> 16) & 0xff));
                }
                /* Latch in address */
                this->hwcontrol(mtd, NAND_CTL_CLRALE);
@@ -706,9 +706,9 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
        case NAND_CMD_DEPLETE1:
                return;
 
-       /*
-        * read error status commands require only a short delay
-        */
+               /*
+                * read error status commands require only a short delay
+                */
        case NAND_CMD_STATUS_ERROR:
        case NAND_CMD_STATUS_ERROR0:
        case NAND_CMD_STATUS_ERROR1:
@@ -724,7 +724,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
                this->hwcontrol(mtd, NAND_CTL_SETCLE);
                this->write_byte(mtd, NAND_CMD_STATUS);
                this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-               while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
+               while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ;
                return;
 
        case NAND_CMD_READ0:
@@ -736,21 +736,21 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
                this->hwcontrol(mtd, NAND_CTL_CLRCLE);
                /* Fall through into ready check */
 
-       /* This applies to read commands */
+               /* This applies to read commands */
        default:
                /*
                 * If we don't have access to the busy pin, we apply the given
                 * command delay
-               */
+                */
                if (!this->dev_ready) {
-                       udelay (this->chip_delay);
+                       udelay(this->chip_delay);
                        return;
                }
        }
 
        /* Apply this short delay always to ensure that we do wait tWB in
         * any case on any machine. */
-       ndelay (100);
+       ndelay(100);
 
        nand_wait_ready(mtd);
 }
@@ -763,16 +763,16 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
  *
  * Get the device and lock it for exclusive access
  */
-static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
+static int nand_get_device(struct nand_chip *this, struct mtd_info *mtd, int new_state)
 {
        struct nand_chip *active;
        spinlock_t *lock;
        wait_queue_head_t *wq;
-       DECLARE_WAITQUEUE (wait, current);
+       DECLARE_WAITQUEUE(wait, current);
 
        lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
        wq = (this->controller) ? &this->controller->wq : &this->wq;
-retry:
+ retry:
        active = this;
        spin_lock(lock);
 
@@ -814,24 +814,24 @@ retry:
 static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
 {
 
-       unsigned long   timeo = jiffies;
-       int     status;
+       unsigned long timeo = jiffies;
+       int status;
 
        if (state == FL_ERASING)
-                timeo += (HZ * 400) / 1000;
+               timeo += (HZ * 400) / 1000;
        else
-                timeo += (HZ * 20) / 1000;
+               timeo += (HZ * 20) / 1000;
 
        led_trigger_event(nand_led_trigger, LED_FULL);
 
        /* Apply this short delay always to ensure that we do wait tWB in
         * any case on any machine. */
-       ndelay (100);
+       ndelay(100);
 
        if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
-               this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
+               this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
        else
-               this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
+               this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
 
        while (time_before(jiffies, timeo)) {
                /* Check, if we were interrupted */
@@ -849,7 +849,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
        }
        led_trigger_event(nand_led_trigger, LED_OFF);
 
-       status = (int) this->read_byte(mtd);
+       status = (int)this->read_byte(mtd);
        return status;
 }
 
@@ -868,31 +868,31 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
  *
  * Cached programming is not supported yet.
  */
-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
-       u_char *oob_buf,  struct nand_oobinfo *oobsel, int cached)
+static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int page,
+                          u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
 {
-       int     i, status;
-       u_char  ecc_code[32];
-       int     eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-       int     *oob_config = oobsel->eccpos;
-       int     datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
-       int     eccbytes = 0;
+       int i, status;
+       u_char ecc_code[32];
+       int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
+       int *oob_config = oobsel->eccpos;
+       int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
+       int eccbytes = 0;
 
        /* FIXME: Enable cached programming */
        cached = 0;
 
        /* Send command to begin auto page programming */
-       this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
+       this->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
        /* Write out complete page of data, take care of eccmode */
        switch (eccmode) {
-       /* No ecc, write all */
+               /* No ecc, write all */
        case NAND_ECC_NONE:
-               printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
+               printk(KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
                this->write_buf(mtd, this->data_poi, mtd->oobblock);
                break;
 
-       /* Software ecc 3/256, write all */
+               /* Software ecc 3/256, write all */
        case NAND_ECC_SOFT:
                for (; eccsteps; eccsteps--) {
                        this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
@@ -928,11 +928,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
                this->write_buf(mtd, oob_buf, mtd->oobsize);
 
        /* Send command to actually program the data */
-       this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
+       this->cmdfunc(mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
 
        if (!cached) {
                /* call wait ready function */
-               status = this->waitfunc (mtd, this, FL_WRITING);
+               status = this->waitfunc(mtd, this, FL_WRITING);
 
                /* See if operation failed and additional status checks are available */
                if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
@@ -941,12 +941,12 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
 
                /* See if device thinks it succeeded */
                if (status & NAND_STATUS_FAIL) {
-                       DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
+                       DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
                        return -EIO;
                }
        } else {
                /* FIXME: Implement cached programming ! */
-               /* wait until cache is ready*/
+               /* wait until cache is ready */
                // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
        }
        return 0;
@@ -972,24 +972,24 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
  * the error later when the ECC page check fails, but we would rather catch
  * it early in the page write stage. Better to write no data than invalid data.
  */
-static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
-       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
+static int nand_verify_pages(struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
+                            u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
 {
-       int     i, j, datidx = 0, oobofs = 0, res = -EIO;
-       int     eccsteps = this->eccsteps;
-       int     hweccbytes;
-       u_char  oobdata[64];
+       int i, j, datidx = 0, oobofs = 0, res = -EIO;
+       int eccsteps = this->eccsteps;
+       int hweccbytes;
+       u_char oobdata[64];
 
        hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
 
        /* Send command to read back the first page */
-       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
+       this->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
 
-       for(;;) {
+       for (;;) {
                for (j = 0; j < eccsteps; j++) {
                        /* Loop through and verify the data */
                        if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+                               DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
                                goto out;
                        }
                        datidx += mtd->eccsize;
@@ -997,7 +997,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
                        if (!hweccbytes)
                                continue;
                        if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+                               DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
                                goto out;
                        }
                        oobofs += hweccbytes;
@@ -1008,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
                 */
                if (oobmode) {
                        if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+                               DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
                                goto out;
                        }
                } else {
@@ -1020,10 +1020,9 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
 
                                for (i = 0; i < ecccnt; i++) {
                                        int idx = oobsel->eccpos[i];
-                                       if (oobdata[idx] != oob_buf[oobofs + idx] ) {
-                                               DEBUG (MTD_DEBUG_LEVEL0,
-                                               "%s: Failed ECC write "
-                                               "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
+                                       if (oobdata[idx] != oob_buf[oobofs + idx]) {
+                                               DEBUG(MTD_DEBUG_LEVEL0, "%s: Failed ECC write verify, page 0x%08x, %6i bytes were succesful\n",
+                                                     __FUNCTION__, page, i);
                                                goto out;
                                        }
                                }
@@ -1039,9 +1038,9 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
                 * is marked as NOAUTOINCR by the board driver.
                 * Do this also before returning, so the chip is
                 * ready for the next command.
-               */
+                */
                if (!this->dev_ready)
-                       udelay (this->chip_delay);
+                       udelay(this->chip_delay);
                else
                        nand_wait_ready(mtd);
 
@@ -1049,17 +1048,16 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
                if (!numpages)
                        return 0;
 
-
                /* Check, if the chip supports auto page increment */
                if (!NAND_CANAUTOINCR(this))
-                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
+                       this->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
        }
        /*
         * Terminate the read command. We come here in case of an error
         * So we must issue a reset command.
         */
-out:
-       this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
+ out:
+       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
        return res;
 }
 #endif
@@ -1075,12 +1073,11 @@ out:
  * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
  * and flags = 0xff
  */
-static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
+static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-       return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
+       return nand_do_read_ecc(mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
 }
 
-
 /**
  * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
  * @mtd:       MTD device structure
@@ -1093,8 +1090,8 @@ static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * re
  *
  * This function simply calls nand_do_read_ecc with flags = 0xff
  */
-static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                         size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
+static int nand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+                        size_t *retlen, u_char *buf, u_char *oob_buf, struct nand_oobinfo *oobsel)
 {
        /* use userspace supplied oobinfo, if zero */
        if (oobsel == NULL)
@@ -1102,7 +1099,6 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
        return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
 }
 
-
 /**
  * nand_do_read_ecc - [MTD Interface] Read data with ECC
  * @mtd:       MTD device structure
@@ -1119,9 +1115,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
  *
  * NAND read with ECC
  */
-int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                            size_t * retlen, u_char * buf, u_char * oob_buf,
-                            struct nand_oobinfo *oobsel, int flags)
+int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+                    size_t *retlen, u_char *buf, u_char *oob_buf, struct nand_oobinfo *oobsel, int flags)
 {
 
        int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
@@ -1130,26 +1125,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
        u_char *data_poi, *oob_data = oob_buf;
        u_char ecc_calc[32];
        u_char ecc_code[32];
-        int eccmode, eccsteps;
-       int     *oob_config, datidx;
-       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-       int     eccbytes;
-       int     compareecc = 1;
-       int     oobreadlen;
+       int eccmode, eccsteps;
+       int *oob_config, datidx;
+       int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
+       int eccbytes;
+       int compareecc = 1;
+       int oobreadlen;
 
-
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int)from, (int)len);
 
        /* Do not allow reads past end of device */
        if ((from + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
                *retlen = 0;
                return -EINVAL;
        }
 
        /* Grab the lock and see if the device is available */
        if (flags & NAND_GET_DEVICE)
-               nand_get_device (this, mtd, FL_READING);
+               nand_get_device(this, mtd, FL_READING);
 
        /* Autoplace of oob data ? Use the default placement scheme */
        if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
@@ -1163,7 +1157,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
        this->select_chip(mtd, chipnr);
 
        /* First we calculate the starting page */
-       realpage = (int) (from >> this->page_shift);
+       realpage = (int)(from >> this->page_shift);
        page = realpage & this->pagemask;
 
        /* Get raw starting column */
@@ -1201,13 +1195,13 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                if (realpage == this->pagebuf && !oob_buf) {
                        /* aligned read ? */
                        if (aligned)
-                               memcpy (data_poi, this->data_buf, end);
+                               memcpy(data_poi, this->data_buf, end);
                        goto readdata;
                }
 
                /* Check, if we must send the read command */
                if (sndcmd) {
-                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
+                       this->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
                        sndcmd = 0;
                }
 
@@ -1219,24 +1213,26 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                eccsteps = this->eccsteps;
 
                switch (eccmode) {
-               case NAND_ECC_NONE: {   /* No ECC, Read in a page */
-                       static unsigned long lastwhinge = 0;
-                       if ((lastwhinge / HZ) != (jiffies / HZ)) {
-                               printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
-                               lastwhinge = jiffies;
+               case NAND_ECC_NONE:{
+                               /* No ECC, Read in a page */
+                               static unsigned long lastwhinge = 0;
+                               if ((lastwhinge / HZ) != (jiffies / HZ)) {
+                                       printk(KERN_WARNING
+                                              "Reading data from NAND FLASH without ECC is not recommended\n");
+                                       lastwhinge = jiffies;
+                               }
+                               this->read_buf(mtd, data_poi, end);
+                               break;
                        }
-                       this->read_buf(mtd, data_poi, end);
-                       break;
-               }
 
                case NAND_ECC_SOFT:     /* Software ECC 3/256: Read in a page + oob data */
                        this->read_buf(mtd, data_poi, end);
-                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
+                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i += 3, datidx += ecc)
                                this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
                        break;
 
                default:
-                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
+                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i += eccbytes, datidx += ecc) {
                                this->enable_hwecc(mtd, NAND_ECC_READ);
                                this->read_buf(mtd, &data_poi[datidx], ecc);
 
@@ -1252,8 +1248,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                                         * does the error correction on the fly */
                                        ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
                                        if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
-                                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
-                                                       "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
+                                               DEBUG(MTD_DEBUG_LEVEL0, "nand_read_ecc: "
+                                                     "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
                                                ecc_failed++;
                                        }
                                } else {
@@ -1274,7 +1270,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                for (j = 0; j < oobsel->eccbytes; j++)
                        ecc_code[j] = oob_data[oob_config[j]];
 
-               /* correct data, if neccecary */
+               /* correct data, if necessary */
                for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
                        ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
 
@@ -1291,16 +1287,16 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                        }
 
                        if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
+                               DEBUG(MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
                                ecc_failed++;
                        }
                }
 
-       readoob:
+             readoob:
                /* check, if we have a fs supplied oob-buffer */
                if (oob_buf) {
                        /* without autoplace. Legacy mode used by YAFFS1 */
-                       switch(oobsel->useecc) {
+                       switch (oobsel->useecc) {
                        case MTD_NANDECC_AUTOPLACE:
                        case MTD_NANDECC_AUTOPL_USR:
                                /* Walk through the autoplace chunks */
@@ -1313,7 +1309,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                                break;
                        case MTD_NANDECC_PLACE:
                                /* YAFFS1 legacy mode */
-                               oob_data += this->eccsteps * sizeof (int);
+                               oob_data += this->eccsteps * sizeof(int);
                        default:
                                oob_data += mtd->oobsize;
                        }
@@ -1331,9 +1327,9 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                 * Do this before the AUTOINCR check, so no problems
                 * arise if a chip which does auto increment
                 * is marked as NOAUTOINCR by the board driver.
-               */
+                */
                if (!this->dev_ready)
-                       udelay (this->chip_delay);
+                       udelay(this->chip_delay);
                else
                        nand_wait_ready(mtd);
 
@@ -1354,7 +1350,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
                }
                /* Check, if the chip supports auto page increment
                 * or if we have hit a block boundary.
-               */
+                */
                if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
                        sndcmd = 1;
        }
@@ -1382,13 +1378,13 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
  *
  * NAND read out-of-band data from the spare area
  */
-static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
+static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
        int i, col, page, chipnr;
        struct nand_chip *this = mtd->priv;
-       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
+       int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
 
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int)from, (int)len);
 
        /* Shift to get page */
        page = (int)(from >> this->page_shift);
@@ -1402,19 +1398,19 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
 
        /* Do not allow reads past end of device */
        if ((from + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
                *retlen = 0;
                return -EINVAL;
        }
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd , FL_READING);
+       nand_get_device(this, mtd, FL_READING);
 
        /* Select the NAND device */
        this->select_chip(mtd, chipnr);
 
        /* Send the read command */
-       this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
+       this->cmdfunc(mtd, NAND_CMD_READOOB, col, page & this->pagemask);
        /*
         * Read the data, if we read more than one page
         * oob data, let the device transfer the data !
@@ -1444,16 +1440,16 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
                         * is marked as NOAUTOINCR by the board driver.
                         */
                        if (!this->dev_ready)
-                               udelay (this->chip_delay);
+                               udelay(this->chip_delay);
                        else
                                nand_wait_ready(mtd);
 
                        /* Check, if the chip supports auto page increment
                         * or if we have hit a block boundary.
-                       */
+                        */
                        if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
                                /* For subsequent page reads set offset to 0 */
-                               this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
+                               this->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
                        }
                }
        }
@@ -1476,43 +1472,43 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
  *
  * Read raw data including oob into buffer
  */
-int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
+int nand_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
 {
        struct nand_chip *this = mtd->priv;
-       int page = (int) (from >> this->page_shift);
-       int chip = (int) (from >> this->chip_shift);
+       int page = (int)(from >> this->page_shift);
+       int chip = (int)(from >> this->chip_shift);
        int sndcmd = 1;
        int cnt = 0;
        int pagesize = mtd->oobblock + mtd->oobsize;
-       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
+       int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
 
        /* Do not allow reads past end of device */
        if ((from + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
                return -EINVAL;
        }
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd , FL_READING);
+       nand_get_device(this, mtd, FL_READING);
 
-       this->select_chip (mtd, chip);
+       this->select_chip(mtd, chip);
 
        /* Add requested oob length */
        len += ooblen;
 
        while (len) {
                if (sndcmd)
-                       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
+                       this->cmdfunc(mtd, NAND_CMD_READ0, 0, page & this->pagemask);
                sndcmd = 0;
 
-               this->read_buf (mtd, &buf[cnt], pagesize);
+               this->read_buf(mtd, &buf[cnt], pagesize);
 
                len -= pagesize;
                cnt += pagesize;
                page++;
 
                if (!this->dev_ready)
-                       udelay (this->chip_delay);
+                       udelay(this->chip_delay);
                else
                        nand_wait_ready(mtd);
 
@@ -1526,7 +1522,6 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
        return 0;
 }
 
-
 /**
  * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
  * @mtd:       MTD device structure
@@ -1550,8 +1545,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
  * forces the 0xff fill before using the buffer again.
  *
 */
-static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
-               int autoplace, int numpages)
+static u_char *nand_prepare_oobbuf(struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
+                                  int autoplace, int numpages)
 {
        struct nand_chip *this = mtd->priv;
        int i, len, ofs;
@@ -1562,8 +1557,7 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
 
        /* Check, if the buffer must be filled with ff again */
        if (this->oobdirty) {
-               memset (this->oob_buf, 0xff,
-                       mtd->oobsize << (this->phys_erase_shift - this->page_shift));
+               memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
                this->oobdirty = 0;
        }
 
@@ -1578,7 +1572,7 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
                for (i = 0, len = 0; len < mtd->oobavail; i++) {
                        int to = ofs + oobsel->oobfree[i][0];
                        int num = oobsel->oobfree[i][1];
-                       memcpy (&this->oob_buf[to], fsbuf, num);
+                       memcpy(&this->oob_buf[to], fsbuf, num);
                        len += num;
                        fsbuf += num;
                }
@@ -1600,9 +1594,9 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
  * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
  *
 */
-static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
+static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
-       return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
+       return (nand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL));
 }
 
 /**
@@ -1617,34 +1611,35 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret
  *
  * NAND write with ECC
  */
-static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
+static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+                         size_t *retlen, const u_char *buf, u_char *eccbuf,
+                         struct nand_oobinfo *oobsel)
 {
        int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
        int autoplace = 0, numpages, totalpages;
        struct nand_chip *this = mtd->priv;
        u_char *oobbuf, *bufstart;
-       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
+       int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
 
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int)to, (int)len);
 
        /* Initialize retlen, in case of early exit */
        *retlen = 0;
 
        /* Do not allow write past end of device */
        if ((to + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
                return -EINVAL;
        }
 
        /* reject writes, which are not page aligned */
-       if (NOTALIGNED (to) || NOTALIGNED(len)) {
-               printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
+       if (NOTALIGNED(to) || NOTALIGNED(len)) {
+               printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
                return -EINVAL;
        }
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_WRITING);
+       nand_get_device(this, mtd, FL_WRITING);
 
        /* Calculate chipnr */
        chipnr = (int)(to >> this->chip_shift);
@@ -1669,7 +1664,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
 
        /* Setup variables and oob buffer */
        totalpages = len >> this->page_shift;
-       page = (int) (to >> this->page_shift);
+       page = (int)(to >> this->page_shift);
        /* Invalidate the page cache, if we write to the cached page */
        if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
                this->pagebuf = -1;
@@ -1678,22 +1673,22 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
        page &= this->pagemask;
        startpage = page;
        /* Calc number of pages we can write in one go */
-       numpages = min (ppblock - (startpage  & (ppblock - 1)), totalpages);
-       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
-       bufstart = (u_char *)buf;
+       numpages = min(ppblock - (startpage & (ppblock - 1)), totalpages);
+       oobbuf = nand_prepare_oobbuf(mtd, eccbuf, oobsel, autoplace, numpages);
+       bufstart = (u_char *) buf;
 
        /* Loop until all data is written */
        while (written < len) {
 
-               this->data_poi = (u_char*) &buf[written];
+               this->data_poi = (u_char *) &buf[written];
                /* Write one page. If this is the last page to write
                 * or the last page in this block, then use the
                 * real pageprogram command, else select cached programming
                 * if supported by the chip.
                 */
-               ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
+               ret = nand_write_page(mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
                if (ret) {
-                       DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
+                       DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
                        goto out;
                }
                /* Next oob page */
@@ -1709,15 +1704,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
                /* Have we hit a block boundary ? Then we have to verify and
                 * if verify is ok, we have to setup the oob buffer for
                 * the next pages.
-               */
-               if (!(page & (ppblock - 1))){
+                */
+               if (!(page & (ppblock - 1))) {
                        int ofs;
                        this->data_poi = bufstart;
-                       ret = nand_verify_pages (mtd, this, startpage,
-                               page - startpage,
-                               oobbuf, oobsel, chipnr, (eccbuf != NULL));
+                       ret = nand_verify_pages(mtd, this, startpage, page - startpage,
+                                               oobbuf, oobsel, chipnr, (eccbuf != NULL));
                        if (ret) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
+                               DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
                                goto out;
                        }
                        *retlen = written;
@@ -1726,11 +1720,10 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
                        if (eccbuf)
                                eccbuf += (page - startpage) * ofs;
                        totalpages -= page - startpage;
-                       numpages = min (totalpages, ppblock);
+                       numpages = min(totalpages, ppblock);
                        page &= this->pagemask;
                        startpage = page;
-                       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
-                                       autoplace, numpages);
+                       oobbuf = nand_prepare_oobbuf(mtd, eccbuf, oobsel, autoplace, numpages);
                        oob = 0;
                        /* Check, if we cross a chip boundary */
                        if (!page) {
@@ -1741,23 +1734,21 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
                }
        }
        /* Verify the remaining pages */
-cmp:
+ cmp:
        this->data_poi = bufstart;
-       ret = nand_verify_pages (mtd, this, startpage, totalpages,
-               oobbuf, oobsel, chipnr, (eccbuf != NULL));
+       ret = nand_verify_pages(mtd, this, startpage, totalpages, oobbuf, oobsel, chipnr, (eccbuf != NULL));
        if (!ret)
                *retlen = written;
        else
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
 
-out:
+ out:
        /* Deselect and wake up anyone waiting on the device */
        nand_release_device(mtd);
 
        return ret;
 }
 
-
 /**
  * nand_write_oob - [MTD Interface] NAND write out-of-band
  * @mtd:       MTD device structure
@@ -1768,16 +1759,16 @@ out:
  *
  * NAND write out-of-band
  */
-static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
+static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
        int column, page, status, ret = -EIO, chipnr;
        struct nand_chip *this = mtd->priv;
 
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int)to, (int)len);
 
        /* Shift to get page */
-       page = (int) (to >> this->page_shift);
-       chipnr = (int) (to >> this->chip_shift);
+       page = (int)(to >> this->page_shift);
+       chipnr = (int)(to >> this->chip_shift);
 
        /* Mask to get column */
        column = to & (mtd->oobsize - 1);
@@ -1787,12 +1778,12 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
 
        /* Do not allow write past end of page */
        if ((column + len) > mtd->oobsize) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
                return -EINVAL;
        }
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_WRITING);
+       nand_get_device(this, mtd, FL_WRITING);
 
        /* Select the NAND device */
        this->select_chip(mtd, chipnr);
@@ -1814,27 +1805,27 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
 
        if (NAND_MUST_PAD(this)) {
                /* Write out desired data */
-               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
+               this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
                /* prepad 0xff for partial programming */
                this->write_buf(mtd, ffchars, column);
                /* write data */
                this->write_buf(mtd, buf, len);
                /* postpad 0xff for partial programming */
-               this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
+               this->write_buf(mtd, ffchars, mtd->oobsize - (len + column));
        } else {
                /* Write out desired data */
-               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
+               this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
                /* write data */
                this->write_buf(mtd, buf, len);
        }
        /* Send command to program the OOB data */
-       this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
-       status = this->waitfunc (mtd, this, FL_WRITING);
+       status = this->waitfunc(mtd, this, FL_WRITING);
 
        /* See if device thinks it succeeded */
        if (status & NAND_STATUS_FAIL) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
                ret = -EIO;
                goto out;
        }
@@ -1843,23 +1834,22 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
 
 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
        /* Send command to read back the data */
-       this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
+       this->cmdfunc(mtd, NAND_CMD_READOOB, column, page & this->pagemask);
 
        if (this->verify_buf(mtd, buf, len)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
                ret = -EIO;
                goto out;
        }
 #endif
        ret = 0;
-out:
+ out:
        /* Deselect and wake up anyone waiting on the device */
        nand_release_device(mtd);
 
        return ret;
 }
 
-
 /**
  * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
  * @mtd:       MTD device structure
@@ -1870,10 +1860,10 @@ out:
  *
  * NAND write with kvec. This just calls the ecc function
  */
-static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
-               loff_t to, size_t * retlen)
+static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
+                      loff_t to, size_t *retlen)
 {
-       return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
+       return (nand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL));
 }
 
 /**
@@ -1888,13 +1878,13 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned
  *
  * NAND write with iovec with ecc
  */
-static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
-               loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
+static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
+                          loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
 {
        int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
        int oob, numpages, autoplace = 0, startpage;
        struct nand_chip *this = mtd->priv;
-       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
+       int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
        u_char *oobbuf, *bufstart;
 
        /* Preset written len for early exit */
@@ -1903,28 +1893,27 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
        /* Calculate total length of data */
        total_len = 0;
        for (i = 0; i < count; i++)
-               total_len += (int) vecs[i].iov_len;
+               total_len += (int)vecs[i].iov_len;
 
-       DEBUG (MTD_DEBUG_LEVEL3,
-              "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int)to, (unsigned int)total_len, count);
 
        /* Do not allow write past end of page */
        if ((to + total_len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
                return -EINVAL;
        }
 
        /* reject writes, which are not page aligned */
-       if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
-               printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
+       if (NOTALIGNED(to) || NOTALIGNED(total_len)) {
+               printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
                return -EINVAL;
        }
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_WRITING);
+       nand_get_device(this, mtd, FL_WRITING);
 
        /* Get the current chip-nr */
-       chipnr = (int) (to >> this->chip_shift);
+       chipnr = (int)(to >> this->chip_shift);
        /* Select the NAND device */
        this->select_chip(mtd, chipnr);
 
@@ -1945,7 +1934,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                autoplace = 1;
 
        /* Setup start page */
-       page = (int) (to >> this->page_shift);
+       page = (int)(to >> this->page_shift);
        /* Invalidate the page cache, if we write to the cached page */
        if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
                this->pagebuf = -1;
@@ -1963,9 +1952,9 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                         * out of this iov in one go */
                        numpages = (vecs->iov_len - len) >> this->page_shift;
                        /* Do not cross block boundaries */
-                       numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
-                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
-                       bufstart = (u_char *)vecs->iov_base;
+                       numpages = min(ppblock - (startpage & (ppblock - 1)), numpages);
+                       oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages);
+                       bufstart = (u_char *) vecs->iov_base;
                        bufstart += len;
                        this->data_poi = bufstart;
                        oob = 0;
@@ -1974,8 +1963,8 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                                 * then use the real pageprogram command, else select
                                 * cached programming if supported by the chip.
                                 */
-                               ret = nand_write_page (mtd, this, page & this->pagemask,
-                                       &oobbuf[oob], oobsel, i != numpages);
+                               ret = nand_write_page(mtd, this, page & this->pagemask,
+                                                     &oobbuf[oob], oobsel, i != numpages);
                                if (ret)
                                        goto out;
                                this->data_poi += mtd->oobblock;
@@ -1984,7 +1973,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                                page++;
                        }
                        /* Check, if we have to switch to the next tuple */
-                       if (len >= (int) vecs->iov_len) {
+                       if (len >= (int)vecs->iov_len) {
                                vecs++;
                                len = 0;
                                count--;
@@ -1998,7 +1987,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                                if (vecs->iov_base != NULL && vecs->iov_len)
                                        this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
                                /* Check, if we have to switch to the next tuple */
-                               if (len >= (int) vecs->iov_len) {
+                               if (len >= (int)vecs->iov_len) {
                                        vecs++;
                                        len = 0;
                                        count--;
@@ -2008,16 +1997,15 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                        this->data_poi = this->data_buf;
                        bufstart = this->data_poi;
                        numpages = 1;
-                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
-                       ret = nand_write_page (mtd, this, page & this->pagemask,
-                               oobbuf, oobsel, 0);
+                       oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages);
+                       ret = nand_write_page(mtd, this, page & this->pagemask, oobbuf, oobsel, 0);
                        if (ret)
                                goto out;
                        page++;
                }
 
                this->data_poi = bufstart;
-               ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
+               ret = nand_verify_pages(mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
                if (ret)
                        goto out;
 
@@ -2035,7 +2023,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
                }
        }
        ret = 0;
-out:
+ out:
        /* Deselect and wake up anyone waiting on the device */
        nand_release_device(mtd);
 
@@ -2050,12 +2038,12 @@ out:
  *
  * Standard erase command for NAND chips
  */
-static void single_erase_cmd (struct mtd_info *mtd, int page)
+static void single_erase_cmd(struct mtd_info *mtd, int page)
 {
        struct nand_chip *this = mtd->priv;
        /* Send commands to erase a block */
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
-       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
+       this->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
 }
 
 /**
@@ -2066,15 +2054,15 @@ static void single_erase_cmd (struct mtd_info *mtd, int page)
  * AND multi block erase command function
  * Erase 4 consecutive blocks
  */
-static void multi_erase_cmd (struct mtd_info *mtd, int page)
+static void multi_erase_cmd(struct mtd_info *mtd, int page)
 {
        struct nand_chip *this = mtd->priv;
        /* Send commands to erase a block */
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
-       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
+       this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
+       this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
+       this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
+       this->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
 }
 
 /**
@@ -2084,9 +2072,9 @@ static void multi_erase_cmd (struct mtd_info *mtd, int page)
  *
  * Erase one ore more blocks
  */
-static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
+static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-       return nand_erase_nand (mtd, instr, 0);
+       return nand_erase_nand(mtd, instr, 0);
 }
 
 #define BBT_PAGE_MASK  0xffffff3f
@@ -2098,7 +2086,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
  *
  * Erase one ore more blocks
  */
-int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
+int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
 {
        int page, len, status, pages_per_block, ret, chipnr;
        struct nand_chip *this = mtd->priv;
@@ -2107,35 +2095,34 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
                                                /* It is used to see if the current page is in the same */
                                                /*   256 block group and the same bank as the bbt. */
 
-       DEBUG (MTD_DEBUG_LEVEL3,
-              "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n", (unsigned int)instr->addr, (unsigned int)instr->len);
 
        /* Start address must align on block boundary */
        if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
                return -EINVAL;
        }
 
        /* Length must align on block boundary */
        if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
                return -EINVAL;
        }
 
        /* Do not allow erase past end of device */
        if ((instr->len + instr->addr) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
                return -EINVAL;
        }
 
        instr->fail_addr = 0xffffffff;
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_ERASING);
+       nand_get_device(this, mtd, FL_ERASING);
 
        /* Shift to get first page */
-       page = (int) (instr->addr >> this->page_shift);
-       chipnr = (int) (instr->addr >> this->chip_shift);
+       page = (int)(instr->addr >> this->page_shift);
+       chipnr = (int)(instr->addr >> this->chip_shift);
 
        /* Calculate pages in each block */
        pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
@@ -2146,7 +2133,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
        /* Check the WP bit */
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
+               DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
                instr->state = MTD_ERASE_FAILED;
                goto erase_exit;
        }
@@ -2166,7 +2153,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
        while (len) {
                /* Check if we have a bad block, we do not erase bad blocks ! */
                if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
-                       printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
+                       printk(KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
                }
@@ -2176,9 +2163,9 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
                if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
                        this->pagebuf = -1;
 
-               this->erase_cmd (mtd, page & this->pagemask);
+               this->erase_cmd(mtd, page & this->pagemask);
 
-               status = this->waitfunc (mtd, this, FL_ERASING);
+               status = this->waitfunc(mtd, this, FL_ERASING);
 
                /* See if operation failed and additional status checks are available */
                if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
@@ -2187,7 +2174,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
 
                /* See if block erase succeeded */
                if (status & NAND_STATUS_FAIL) {
-                       DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
+                       DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
                        instr->state = MTD_ERASE_FAILED;
                        instr->fail_addr = (page << this->page_shift);
                        goto erase_exit;
@@ -2221,7 +2208,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
        }
        instr->state = MTD_ERASE_DONE;
 
-erase_exit:
+ erase_exit:
 
        ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
        /* Do call back function */
@@ -2236,9 +2223,9 @@ erase_exit:
                for (chipnr = 0; chipnr < this->numchips; chipnr++) {
                        if (rewrite_bbt[chipnr]) {
                                /* update the BBT for chip */
-                               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
-                                       chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
-                               nand_update_bbt (mtd, rewrite_bbt[chipnr]);
+                               DEBUG(MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
+                                     chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
+                               nand_update_bbt(mtd, rewrite_bbt[chipnr]);
                        }
                }
        }
@@ -2253,31 +2240,30 @@ erase_exit:
  *
  * Sync is actually a wait for chip ready function
  */
-static void nand_sync (struct mtd_info *mtd)
+static void nand_sync(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
+       DEBUG(MTD_DEBUG_LEVEL3, "nand_sync: called\n");
 
        /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_SYNCING);
+       nand_get_device(this, mtd, FL_SYNCING);
        /* Release it and go back */
-       nand_release_device (mtd);
+       nand_release_device(mtd);
 }
 
-
 /**
  * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
  * @mtd:       MTD device structure
  * @ofs:       offset relative to mtd start
  */
-static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
+static int nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
        /* Check for invalid offset */
        if (ofs > mtd->size)
                return -EINVAL;
 
-       return nand_block_checkbad (mtd, ofs, 1, 0);
+       return nand_block_checkbad(mtd, ofs, 1, 0);
 }
 
 /**
@@ -2285,17 +2271,17 @@ static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
  * @mtd:       MTD device structure
  * @ofs:       offset relative to mtd start
  */
-static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
+static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
        struct nand_chip *this = mtd->priv;
        int ret;
 
-        if ((ret = nand_block_isbad(mtd, ofs))) {
-               /* If it was bad already, return success and do nothing. */
+       if ((ret = nand_block_isbad(mtd, ofs))) {
+               /* If it was bad already, return success and do nothing. */
                if (ret > 0)
                        return 0;
-               return ret;
-        }
+               return ret;
+       }
 
        return this->block_markbad(mtd, ofs);
 }
@@ -2308,7 +2294,7 @@ static int nand_suspend(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
-       return nand_get_device (this, mtd, FL_PM_SUSPENDED);
+       return nand_get_device(this, mtd, FL_PM_SUSPENDED);
 }
 
 /**
@@ -2322,30 +2308,44 @@ static void nand_resume(struct mtd_info *mtd)
        if (this->state == FL_PM_SUSPENDED)
                nand_release_device(mtd);
        else
-               printk(KERN_ERR "resume() called for the chip which is not "
-                               "in suspended state\n");
+               printk(KERN_ERR "resume() called for the chip which is not in suspended state\n");
 
 }
 
+/* module_text_address() isn't exported, and it's mostly a pointless
+   test if this is a module _anyway_ -- they'd have to try _really_ hard
+   to call us from in-kernel code if the core NAND support is modular. */
+#ifdef MODULE
+#define caller_is_module() (1)
+#else
+#define caller_is_module() module_text_address((unsigned long)__builtin_return_address(0))
+#endif
 
 /**
  * nand_scan - [NAND Interface] Scan for the NAND device
  * @mtd:       MTD device structure
  * @maxchips:  Number of chips to scan for
  *
- * This fills out all the not initialized function pointers
+ * This fills out all the uninitialized function pointers
  * with the defaults.
  * The flash ID is read and the mtd/chip structures are
  * filled with the appropriate values. Buffers are allocated if
  * they are not provided by the board driver
+ * The mtd->owner field must be set to the module of the caller
  *
  */
-int nand_scan (struct mtd_info *mtd, int maxchips)
+int nand_scan(struct mtd_info *mtd, int maxchips)
 {
        int i, nand_maf_id, nand_dev_id, busw, maf_id;
        struct nand_chip *this = mtd->priv;
 
-       /* Get buswidth to select the correct functions*/
+       /* Many callers got this wrong, so check for it for a while... */
+       if (!mtd->owner && caller_is_module()) {
+               printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
+               BUG();
+       }
+
+       /* Get buswidth to select the correct functions */
        busw = this->options & NAND_BUSWIDTH_16;
 
        /* check for proper chip_delay setup, set 20us if not */
@@ -2387,7 +2387,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
        this->select_chip(mtd, 0);
 
        /* Send the command for reading device ID */
-       this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
+       this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 
        /* Read manufacturer and device IDs */
        nand_maf_id = this->read_byte(mtd);
@@ -2399,7 +2399,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                if (nand_dev_id != nand_flash_ids[i].id)
                        continue;
 
-               if (!mtd->name) mtd->name = nand_flash_ids[i].name;
+               if (!mtd->name)
+                       mtd->name = nand_flash_ids[i].name;
                this->chipsize = nand_flash_ids[i].chipsize << 20;
 
                /* New devices have all the information in additional id bytes */
@@ -2416,7 +2417,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                        mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
                        extid >>= 2;
                        /* Calc blocksize. Blocksize is multiples of 64KiB */
-                       mtd->erasesize = (64 * 1024)  << (extid & 0x03);
+                       mtd->erasesize = (64 * 1024) << (extid & 0x03);
                        extid >>= 2;
                        /* Get buswidth information */
                        busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
@@ -2439,13 +2440,12 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                /* Check, if buswidth is correct. Hardware drivers should set
                 * this correct ! */
                if (busw != (this->options & NAND_BUSWIDTH_16)) {
-                       printk (KERN_INFO "NAND device: Manufacturer ID:"
-                               " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
-                               nand_manuf_ids[maf_id].name , mtd->name);
-                       printk (KERN_WARNING
-                               "NAND bus width %d instead %d bit\n",
-                                       (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
-                                       busw ? 16 : 8);
+                       printk(KERN_INFO "NAND device: Manufacturer ID:"
+                              " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
+                              nand_manuf_ids[maf_id].name, mtd->name);
+                       printk(KERN_WARNING
+                              "NAND bus width %d instead %d bit\n",
+                              (this->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8);
                        this->select_chip(mtd, -1);
                        return 1;
                }
@@ -2456,13 +2456,12 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                this->chip_shift = ffs(this->chipsize) - 1;
 
                /* Set the bad block position */
-               this->badblockpos = mtd->oobblock > 512 ?
-                       NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
+               this->badblockpos = mtd->oobblock > 512 ? NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
 
                /* Get chip options, preserve non chip based options */
                this->options &= ~NAND_CHIPOPTIONS_MSK;
                this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
-               /* Set this as a default. Board drivers can override it, if neccecary */
+               /* Set this as a default. Board drivers can override it, if necessary */
                this->options |= NAND_NO_AUTOINCR;
                /* Check if this is a not a samsung device. Do not clear the options
                 * for chips which are not having an extended id.
@@ -2480,23 +2479,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
                        this->cmdfunc = nand_command_lp;
 
-               printk (KERN_INFO "NAND device: Manufacturer ID:"
-                       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
-                       nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
+               printk(KERN_INFO "NAND device: Manufacturer ID:"
+                      " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
+                      nand_manuf_ids[maf_id].name, nand_flash_ids[i].name);
                break;
        }
 
        if (!nand_flash_ids[i].name) {
-               printk (KERN_WARNING "No NAND device found!!!\n");
+               printk(KERN_WARNING "No NAND device found!!!\n");
                this->select_chip(mtd, -1);
                return 1;
        }
 
-       for (i=1; i < maxchips; i++) {
+       for (i = 1; i < maxchips; i++) {
                this->select_chip(mtd, i);
 
                /* Send the command for reading device ID */
-               this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
+               this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 
                /* Read manufacturer and device IDs */
                if (nand_maf_id != this->read_byte(mtd) ||
@@ -2506,13 +2505,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
        if (i > 1)
                printk(KERN_INFO "%d NAND chips detected\n", i);
 
-       /* Allocate buffers, if neccecary */
+       /* Allocate buffers, if necessary */
        if (!this->oob_buf) {
                size_t len;
                len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
-               this->oob_buf = kmalloc (len, GFP_KERNEL);
+               this->oob_buf = kmalloc(len, GFP_KERNEL);
                if (!this->oob_buf) {
-                       printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n");
+                       printk(KERN_ERR "nand_scan(): Cannot allocate oob_buf\n");
                        return -ENOMEM;
                }
                this->options |= NAND_OOBBUF_ALLOC;
@@ -2521,11 +2520,11 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
        if (!this->data_buf) {
                size_t len;
                len = mtd->oobblock + mtd->oobsize;
-               this->data_buf = kmalloc (len, GFP_KERNEL);
+               this->data_buf = kmalloc(len, GFP_KERNEL);
                if (!this->data_buf) {
                        if (this->options & NAND_OOBBUF_ALLOC)
-                               kfree (this->oob_buf);
-                       printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n");
+                               kfree(this->oob_buf);
+                       printk(KERN_ERR "nand_scan(): Cannot allocate data_buf\n");
                        return -ENOMEM;
                }
                this->options |= NAND_DATABUF_ALLOC;
@@ -2555,8 +2554,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                        this->autooob = &nand_oob_64;
                        break;
                default:
-                       printk (KERN_WARNING "No oob scheme defined for oobsize %d\n",
-                               mtd->oobsize);
+                       printk(KERN_WARNING "No oob scheme defined for oobsize %d\n", mtd->oobsize);
                        BUG();
                }
        }
@@ -2571,7 +2569,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
         * check ECC mode, default to software
         * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
         * fallback to software ECC
-       */
+        */
        this->eccsize = 256;    /* set default eccsize */
        this->eccbytes = 3;
 
@@ -2591,19 +2589,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
        case NAND_ECC_HW6_512:
        case NAND_ECC_HW8_512:
                if (mtd->oobblock == 256) {
-                       printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
+                       printk(KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
                        this->eccmode = NAND_ECC_SOFT;
                        this->calculate_ecc = nand_calculate_ecc;
                        this->correct_data = nand_correct_data;
                } else
-                       this->eccsize = 512; /* set eccsize to 512 */
+                       this->eccsize = 512;    /* set eccsize to 512 */
                break;
 
        case NAND_ECC_HW3_256:
                break;
 
        case NAND_ECC_NONE:
-               printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
+               printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
                this->eccmode = NAND_ECC_NONE;
                break;
 
@@ -2613,13 +2611,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                break;
 
        default:
-               printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
+               printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
                BUG();
        }
 
        /* Check hardware ecc function availability and adjust number of ecc bytes per
         * calculation step
-       */
+        */
        switch (this->eccmode) {
        case NAND_ECC_HW12_2048:
                this->eccbytes += 4;
@@ -2631,7 +2629,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
        case NAND_ECC_HW3_256:
                if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
                        break;
-               printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
+               printk(KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
                BUG();
        }
 
@@ -2659,8 +2657,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
 
        /* Initialize state, waitqueue and spinlock */
        this->state = FL_READY;
-       init_waitqueue_head (&this->wq);
-       spin_lock_init (&this->chip_lock);
+       init_waitqueue_head(&this->wq);
+       spin_lock_init(&this->chip_lock);
 
        /* De-select the device */
        this->select_chip(mtd, -1);
@@ -2695,44 +2693,41 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
        /* and make the autooob the default one */
        memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
 
-       mtd->owner = THIS_MODULE;
-
        /* Check, if we should skip the bad block table scan */
        if (this->options & NAND_SKIP_BBTSCAN)
                return 0;
 
        /* Build bad block table */
-       return this->scan_bbt (mtd);
+       return this->scan_bbt(mtd);
 }
 
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
  * @mtd:       MTD device structure
 */
-void nand_release (struct mtd_info *mtd)
+void nand_release(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
 #ifdef CONFIG_MTD_PARTITIONS
        /* Deregister partitions */
-       del_mtd_partitions (mtd);
+       del_mtd_partitions(mtd);
 #endif
        /* Deregister the device */
-       del_mtd_device (mtd);
+       del_mtd_device(mtd);
 
        /* Free bad block table memory */
-       kfree (this->bbt);
+       kfree(this->bbt);
        /* Buffer allocated by nand_scan ? */
        if (this->options & NAND_OOBBUF_ALLOC)
-               kfree (this->oob_buf);
+               kfree(this->oob_buf);
        /* Buffer allocated by nand_scan ? */
        if (this->options & NAND_DATABUF_ALLOC)
-               kfree (this->data_buf);
+               kfree(this->data_buf);
 }
 
-EXPORT_SYMBOL_GPL (nand_scan);
-EXPORT_SYMBOL_GPL (nand_release);
-
+EXPORT_SYMBOL_GPL(nand_scan);
+EXPORT_SYMBOL_GPL(nand_release);
 
 static int __init nand_base_init(void)
 {
@@ -2748,6 +2743,6 @@ static void __exit nand_base_exit(void)
 module_init(nand_base_init);
 module_exit(nand_base_exit);
 
-MODULE_LICENSE ("GPL");
-MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
-MODULE_DESCRIPTION ("Generic NAND flash driver code");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
+MODULE_DESCRIPTION("Generic NAND flash driver code");
index ca28699..9adc6d6 100644 (file)
@@ -48,7 +48,7 @@
  *
  * Following assumptions are made:
  * - bbts start at a page boundary, if autolocated on a block boundary
- * - the space neccecary for a bbt in FLASH does not exceed a block boundary
+ * - the space necessary for a bbt in FLASH does not exceed a block boundary
  *
  */
 
@@ -60,7 +60,7 @@
 #include <linux/mtd/compatmac.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
-
+#include <linux/vmalloc.h>
 
 /**
  * check_pattern - [GENERIC] check if a pattern is in the buffer
@@ -75,7 +75,7 @@
  * pattern area contain 0xff
  *
 */
-static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
+static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
 {
        int i, end = 0;
        uint8_t *p = buf;
@@ -116,7 +116,7 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
  * no optional empty check
  *
 */
-static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
+static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
 {
        int i;
        uint8_t *p = buf;
@@ -142,8 +142,8 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
  * Read the bad block table starting from page.
  *
  */
-static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
-       int bits, int offs, int reserved_block_code)
+static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
+                   int bits, int offs, int reserved_block_code)
 {
        int res, i, j, act = 0;
        struct nand_chip *this = mtd->priv;
@@ -152,17 +152,17 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
        uint8_t msk = (uint8_t) ((1 << bits) - 1);
 
        totlen = (num * bits) >> 3;
-       from = ((loff_t)page) << this->page_shift;
+       from = ((loff_t) page) << this->page_shift;
 
        while (totlen) {
-               len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
-               res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
+               len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
+               res = mtd->read_ecc(mtd, from, len, &retlen, buf, NULL, this->autooob);
                if (res < 0) {
                        if (retlen != len) {
-                               printk (KERN_INFO "nand_bbt: Error reading bad block table\n");
+                               printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
                                return res;
                        }
-                       printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
+                       printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
                }
 
                /* Analyse data */
@@ -172,17 +172,16 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
                                uint8_t tmp = (dat >> j) & msk;
                                if (tmp == msk)
                                        continue;
-                               if (reserved_block_code &&
-                                   (tmp == reserved_block_code)) {
-                                       printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
-                                               ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                               if (reserved_block_code && (tmp == reserved_block_code)) {
+                                       printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
+                                              ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
                                        this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
                                        continue;
                                }
                                /* Leave it for now, if its matured we can move this
                                 * message to MTD_DEBUG_LEVEL0 */
-                               printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
-                                       ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                               printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
+                                      ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
                                /* Factory marked bad or worn out ? */
                                if (tmp == 0)
                                        this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
@@ -207,7 +206,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
  * Read the bad block table for all chips starting at a given page
  * We assume that the bbt bits are in consecutive order.
 */
-static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
+static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
 {
        struct nand_chip *this = mtd->priv;
        int res = 0, i;
@@ -242,23 +241,22 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
  * We assume that the bbt bits are in consecutive order.
  *
 */
-static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
-       struct nand_bbt_descr *md)
+static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
        struct nand_chip *this = mtd->priv;
 
        /* Read the primary version, if available */
        if (td->options & NAND_BBT_VERSION) {
-               nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+               nand_read_raw(mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
                td->version[0] = buf[mtd->oobblock + td->veroffs];
-               printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
+               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
        }
 
        /* Read the mirror version, if available */
        if (md && (md->options & NAND_BBT_VERSION)) {
-               nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+               nand_read_raw(mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
                md->version[0] = buf[mtd->oobblock + md->veroffs];
-               printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
+               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
        }
 
        return 1;
@@ -275,7 +273,7 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
  * Create a bad block table by scanning the device
  * for the given good/bad block identify pattern
  */
-static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
+static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
 {
        struct nand_chip *this = mtd->priv;
        int i, j, numblocks, len, scanlen;
@@ -283,7 +281,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        loff_t from;
        size_t readlen, ooblen;
 
-       printk (KERN_INFO "Scanning device for bad blocks\n");
+       printk(KERN_INFO "Scanning device for bad blocks\n");
 
        if (bd->options & NAND_BBT_SCANALLPAGES)
                len = 1 << (this->bbt_erase_shift - this->page_shift);
@@ -300,7 +298,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                readlen = bd->len;
        } else {
                /* Full page content should be read */
-               scanlen = mtd->oobblock + mtd->oobsize;
+               scanlen = mtd->oobblock + mtd->oobsize;
                readlen = len * mtd->oobblock;
                ooblen = len * mtd->oobsize;
        }
@@ -313,8 +311,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                from = 0;
        } else {
                if (chip >= this->numchips) {
-                       printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
-                               chip + 1, this->numchips);
+                       printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
+                              chip + 1, this->numchips);
                        return -EINVAL;
                }
                numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
@@ -327,7 +325,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                int ret;
 
                if (bd->options & NAND_BBT_SCANEMPTY)
-                       if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
+                       if ((ret = nand_read_raw(mtd, buf, from, readlen, ooblen)))
                                return ret;
 
                for (j = 0; j < len; j++) {
@@ -336,22 +334,21 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
 
                                /* Read the full oob until read_oob is fixed to
                                 * handle single byte reads for 16 bit buswidth */
-                               ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
-                                                       mtd->oobsize, &retlen, buf);
+                               ret = mtd->read_oob(mtd, from + j * mtd->oobblock, mtd->oobsize, &retlen, buf);
                                if (ret)
                                        return ret;
 
-                               if (check_short_pattern (buf, bd)) {
+                               if (check_short_pattern(buf, bd)) {
                                        this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                                       printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
-                                               i >> 1, (unsigned int) from);
+                                       printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+                                              i >> 1, (unsigned int)from);
                                        break;
                                }
                        } else {
-                               if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+                               if (check_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
                                        this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                                       printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
-                                               i >> 1, (unsigned int) from);
+                                       printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+                                              i >> 1, (unsigned int)from);
                                        break;
                                }
                        }
@@ -374,12 +371,12 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
  * block.
  * If the option NAND_BBT_PERCHIP is given, each chip is searched
  * for a bbt, which contains the bad block information of this chip.
- * This is neccecary to provide support for certain DOC devices.
+ * This is necessary to provide support for certain DOC devices.
  *
  * The bbt ident pattern resides in the oob area of the first page
  * in a block.
  */
-static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
+static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
 {
        struct nand_chip *this = mtd->priv;
        int i, chips;
@@ -389,7 +386,7 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
 
        /* Search direction top -> down ? */
        if (td->options & NAND_BBT_LASTBLOCK) {
-               startblock = (mtd->size >> this->bbt_erase_shift) -1;
+               startblock = (mtd->size >> this->bbt_erase_shift) - 1;
                dir = -1;
        } else {
                startblock = 0;
@@ -417,7 +414,7 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                for (block = 0; block < td->maxblocks; block++) {
                        int actblock = startblock + dir * block;
                        /* Read first page */
-                       nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
+                       nand_read_raw(mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
                        if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
                                td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
                                if (td->options & NAND_BBT_VERSION) {
@@ -431,9 +428,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        /* Check, if we found a bbt for each requested chip */
        for (i = 0; i < chips; i++) {
                if (td->pages[i] == -1)
-                       printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
+                       printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
                else
-                       printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
+                       printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
+                              td->version[i]);
        }
        return 0;
 }
@@ -447,21 +445,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
  *
  * Search and read the bad block table(s)
 */
-static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
-       struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
        /* Search the primary table */
-       search_bbt (mtd, buf, td);
+       search_bbt(mtd, buf, td);
 
        /* Search the mirror table */
        if (md)
-               search_bbt (mtd, buf, md);
+               search_bbt(mtd, buf, md);
 
        /* Force result check */
        return 1;
 }
 
-
 /**
  * write_bbt - [GENERIC] (Re)write the bad block table
  *
@@ -474,8 +470,8 @@ static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
  * (Re)write the bad block table
  *
 */
-static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
-       struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
+static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
+                    struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
 {
        struct nand_chip *this = mtd->priv;
        struct nand_oobinfo oobinfo;
@@ -492,7 +488,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
                rcode = 0xff;
        /* Write bad block table per chip rather than per device ? */
        if (td->options & NAND_BBT_PERCHIP) {
-               numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
+               numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
                /* Full device write or specific chip ? */
                if (chipsel == -1) {
                        nrchips = this->numchips;
@@ -501,7 +497,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
                        chip = chipsel;
                }
        } else {
-               numblocks = (int) (mtd->size >> this->bbt_erase_shift);
+               numblocks = (int)(mtd->size >> this->bbt_erase_shift);
                nrchips = 1;
        }
 
@@ -540,9 +536,9 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
                        if (!md || md->pages[chip] != page)
                                goto write;
                }
-               printk (KERN_ERR "No space left to write bad block table\n");
+               printk(KERN_ERR "No space left to write bad block table\n");
                return -ENOSPC;
-write:
+       write:
 
                /* Set up shift count and masks for the flash table */
                bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -558,7 +554,7 @@ write:
 
                to = ((loff_t) page) << this->page_shift;
 
-               memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
+               memcpy(&oobinfo, this->autooob, sizeof(oobinfo));
                oobinfo.useecc = MTD_NANDECC_PLACEONLY;
 
                /* Must we save the block contents ? */
@@ -566,22 +562,23 @@ write:
                        /* Make it block aligned */
                        to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
                        len = 1 << this->bbt_erase_shift;
-                       res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
+                       res = mtd->read_ecc(mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
                        if (res < 0) {
                                if (retlen != len) {
-                                       printk (KERN_INFO "nand_bbt: Error reading block for writing the bad block table\n");
+                                       printk(KERN_INFO
+                                              "nand_bbt: Error reading block for writing the bad block table\n");
                                        return res;
                                }
-                               printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n");
+                               printk(KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n");
                        }
                        /* Calc the byte offset in the buffer */
                        pageoffs = page - (int)(to >> this->page_shift);
                        offs = pageoffs << this->page_shift;
                        /* Preset the bbt area with 0xff */
-                       memset (&buf[offs], 0xff, (size_t)(numblocks >> sft));
+                       memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
                        /* Preset the bbt's oob area with 0xff */
-                       memset (&buf[len + pageoffs * mtd->oobsize], 0xff,
-                               ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
+                       memset(&buf[len + pageoffs * mtd->oobsize], 0xff,
+                              ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
                        if (td->options & NAND_BBT_VERSION) {
                                buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
                        }
@@ -589,22 +586,22 @@ write:
                        /* Calc length */
                        len = (size_t) (numblocks >> sft);
                        /* Make it page aligned ! */
-                       len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
+                       len = (len + (mtd->oobblock - 1)) & ~(mtd->oobblock - 1);
                        /* Preset the buffer with 0xff */
-                       memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
+                       memset(buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
                        offs = 0;
                        /* Pattern is located in oob area of first page */
-                       memcpy (&buf[len + td->offs], td->pattern, td->len);
+                       memcpy(&buf[len + td->offs], td->pattern, td->len);
                        if (td->options & NAND_BBT_VERSION) {
                                buf[len + td->veroffs] = td->version[chip];
                        }
                }
 
                /* walk through the memory table */
-               for (i = 0; i < numblocks; ) {
+               for (i = 0; i < numblocks;) {
                        uint8_t dat;
                        dat = this->bbt[bbtoffs + (i >> 2)];
-                       for (j = 0; j < 4; j++ , i++) {
+                       for (j = 0; j < 4; j++, i++) {
                                int sftcnt = (i << (3 - sft)) & sftmsk;
                                /* Do not store the reserved bbt blocks ! */
                                buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt);
@@ -612,23 +609,23 @@ write:
                        }
                }
 
-               memset (&einfo, 0, sizeof (einfo));
+               memset(&einfo, 0, sizeof(einfo));
                einfo.mtd = mtd;
-               einfo.addr = (unsigned long) to;
+               einfo.addr = (unsigned long)to;
                einfo.len = 1 << this->bbt_erase_shift;
-               res = nand_erase_nand (mtd, &einfo, 1);
+               res = nand_erase_nand(mtd, &einfo, 1);
                if (res < 0) {
-                       printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
+                       printk(KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
                        return res;
                }
 
-               res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
+               res = mtd->write_ecc(mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
                if (res < 0) {
-                       printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
+                       printk(KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
                        return res;
                }
-               printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
-                       (unsigned int) to, td->version[chip]);
+               printk(KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
+                      (unsigned int)to, td->version[chip]);
 
                /* Mark it as used */
                td->pages[chip] = page;
@@ -644,27 +641,27 @@ write:
  * The function creates a memory based bbt by scanning the device
  * for manufacturer / software marked good / bad blocks
 */
-static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
 
        bd->options &= ~NAND_BBT_SCANEMPTY;
-       return create_bbt (mtd, this->data_buf, bd, -1);
+       return create_bbt(mtd, this->data_buf, bd, -1);
 }
 
 /**
- * check_create - [GENERIC] create and write bbt(s) if neccecary
+ * check_create - [GENERIC] create and write bbt(s) if necessary
  * @mtd:       MTD device structure
  * @buf:       temporary buffer
  * @bd:                descriptor for the good/bad block search pattern
  *
  * The function checks the results of the previous call to read_bbt
- * and creates / updates the bbt(s) if neccecary
- * Creation is neccecary if no bbt was found for the chip/device
- * Update is neccecary if one of the tables is missing or the
+ * and creates / updates the bbt(s) if necessary
+ * Creation is necessary if no bbt was found for the chip/device
+ * Update is necessary if one of the tables is missing or the
  * version nr. of one table is less than the other
 */
-static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
+static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
 {
        int i, chips, writeops, chipsel, res;
        struct nand_chip *this = mtd->priv;
@@ -732,35 +729,35 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
                        rd = td;
                        goto writecheck;
                }
-create:
+       create:
                /* Create the bad block table by scanning the device ? */
                if (!(td->options & NAND_BBT_CREATE))
                        continue;
 
                /* Create the table in memory by scanning the chip(s) */
-               create_bbt (mtd, buf, bd, chipsel);
+               create_bbt(mtd, buf, bd, chipsel);
 
                td->version[i] = 1;
                if (md)
                        md->version[i] = 1;
-writecheck:
+       writecheck:
                /* read back first ? */
                if (rd)
-                       read_abs_bbt (mtd, buf, rd, chipsel);
+                       read_abs_bbt(mtd, buf, rd, chipsel);
                /* If they weren't versioned, read both. */
                if (rd2)
-                       read_abs_bbt (mtd, buf, rd2, chipsel);
+                       read_abs_bbt(mtd, buf, rd2, chipsel);
 
                /* Write the bad block table to the device ? */
                if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
-                       res = write_bbt (mtd, buf, td, md, chipsel);
+                       res = write_bbt(mtd, buf, td, md, chipsel);
                        if (res < 0)
                                return res;
                }
 
                /* Write the mirror bad block table to the device ? */
                if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
-                       res = write_bbt (mtd, buf, md, td, chipsel);
+                       res = write_bbt(mtd, buf, md, td, chipsel);
                        if (res < 0)
                                return res;
                }
@@ -777,7 +774,7 @@ writecheck:
  * accidental erasures / writes. The regions are identified by
  * the mark 0x02.
 */
-static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
+static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 {
        struct nand_chip *this = mtd->priv;
        int i, j, chips, block, nrblocks, update;
@@ -795,7 +792,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
        for (i = 0; i < chips; i++) {
                if ((td->options & NAND_BBT_ABSPAGE) ||
                    !(td->options & NAND_BBT_WRITE)) {
-                       if (td->pages[i] == -1) continue;
+                       if (td->pages[i] == -1)
+                               continue;
                        block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
                        block <<= 1;
                        oldval = this->bbt[(block >> 3)];
@@ -815,7 +813,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
                        oldval = this->bbt[(block >> 3)];
                        newval = oldval | (0x2 << (block & 0x06));
                        this->bbt[(block >> 3)] = newval;
-                       if (oldval != newval) update = 1;
+                       if (oldval != newval)
+                               update = 1;
                        block += 2;
                }
                /* If we want reserved blocks to be recorded to flash, and some
@@ -840,7 +839,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
  * by calling the nand_free_bbt function.
  *
 */
-int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
        int len, res = 0;
@@ -850,21 +849,21 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
        len = mtd->size >> (this->bbt_erase_shift + 2);
        /* Allocate memory (2bit per block) */
-       this->bbt = kmalloc (len, GFP_KERNEL);
+       this->bbt = kmalloc(len, GFP_KERNEL);
        if (!this->bbt) {
-               printk (KERN_ERR "nand_scan_bbt: Out of memory\n");
+               printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
                return -ENOMEM;
        }
        /* Clear the memory bad block table */
-       memset (this->bbt, 0x00, len);
+       memset(this->bbt, 0x00, len);
 
        /* If no primary table decriptor is given, scan the device
         * to build a memory based bad block table
         */
        if (!td) {
                if ((res = nand_memory_bbt(mtd, bd))) {
-                       printk (KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
-                       kfree (this->bbt);
+                       printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
+                       kfree(this->bbt);
                        this->bbt = NULL;
                }
                return res;
@@ -873,35 +872,34 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
        /* Allocate a temporary buffer for one eraseblock incl. oob */
        len = (1 << this->bbt_erase_shift);
        len += (len >> this->page_shift) * mtd->oobsize;
-       buf = kmalloc (len, GFP_KERNEL);
+       buf = vmalloc(len);
        if (!buf) {
-               printk (KERN_ERR "nand_bbt: Out of memory\n");
-               kfree (this->bbt);
+               printk(KERN_ERR "nand_bbt: Out of memory\n");
+               kfree(this->bbt);
                this->bbt = NULL;
                return -ENOMEM;
        }
 
        /* Is the bbt at a given page ? */
        if (td->options & NAND_BBT_ABSPAGE) {
-               res = read_abs_bbts (mtd, buf, td, md);
+               res = read_abs_bbts(mtd, buf, td, md);
        } else {
                /* Search the bad block table using a pattern in oob */
-               res = search_read_bbts (mtd, buf, td, md);
+               res = search_read_bbts(mtd, buf, td, md);
        }
 
        if (res)
-               res = check_create (mtd, buf, bd);
+               res = check_create(mtd, buf, bd);
 
        /* Prevent the bbt regions from erasing / writing */
-       mark_bbt_region (mtd, td);
+       mark_bbt_region(mtd, td);
        if (md)
-               mark_bbt_region (mtd, md);
+               mark_bbt_region(mtd, md);
 
-       kfree (buf);
+       vfree(buf);
        return res;
 }
 
-
 /**
  * nand_update_bbt - [NAND Interface] update bad block table(s)
  * @mtd:       MTD device structure
@@ -909,7 +907,7 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
  *
  * The function updates the bad block table(s)
 */
-int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
+int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 {
        struct nand_chip *this = mtd->priv;
        int len, res = 0, writeops = 0;
@@ -925,9 +923,9 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
        /* Allocate a temporary buffer for one eraseblock incl. oob */
        len = (1 << this->bbt_erase_shift);
        len += (len >> this->page_shift) * mtd->oobsize;
-       buf = kmalloc (len, GFP_KERNEL);
+       buf = kmalloc(len, GFP_KERNEL);
        if (!buf) {
-               printk (KERN_ERR "nand_update_bbt: Out of memory\n");
+               printk(KERN_ERR "nand_update_bbt: Out of memory\n");
                return -ENOMEM;
        }
 
@@ -935,7 +933,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
 
        /* Do we have a bbt per chip ? */
        if (td->options & NAND_BBT_PERCHIP) {
-               chip = (int) (offs >> this->chip_shift);
+               chip = (int)(offs >> this->chip_shift);
                chipsel = chip;
        } else {
                chip = 0;
@@ -948,17 +946,17 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
 
        /* Write the bad block table to the device ? */
        if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
-               res = write_bbt (mtd, buf, td, md, chipsel);
+               res = write_bbt(mtd, buf, td, md, chipsel);
                if (res < 0)
                        goto out;
        }
        /* Write the mirror bad block table to the device ? */
        if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
-               res = write_bbt (mtd, buf, md, td, chipsel);
+               res = write_bbt(mtd, buf, md, td, chipsel);
        }
 
-out:
-       kfree (buf);
+ out:
+       kfree(buf);
        return res;
 }
 
@@ -981,14 +979,14 @@ static struct nand_bbt_descr largepage_memorybased = {
 };
 
 static struct nand_bbt_descr smallpage_flashbased = {
-       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
+       .options = NAND_BBT_SCAN2NDPAGE,
        .offs = 5,
        .len = 1,
        .pattern = scan_ff_pattern
 };
 
 static struct nand_bbt_descr largepage_flashbased = {
-       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
+       .options = NAND_BBT_SCAN2NDPAGE,
        .offs = 0,
        .len = 2,
        .pattern = scan_ff_pattern
@@ -1036,7 +1034,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
  * support for the device and calls the nand_scan_bbt function
  *
 */
-int nand_default_bbt (struct mtd_info *mtd)
+int nand_default_bbt(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
@@ -1046,7 +1044,7 @@ int nand_default_bbt (struct mtd_info *mtd)
         * of the good / bad information, so we _must_ store
         * this information in a good / bad table during
         * startup
-       */
+        */
        if (this->options & NAND_IS_AND) {
                /* Use the default pattern descriptors */
                if (!this->bbt_td) {
@@ -1054,10 +1052,9 @@ int nand_default_bbt (struct mtd_info *mtd)
                        this->bbt_md = &bbt_mirror_descr;
                }
                this->options |= NAND_USE_FLASH_BBT;
-               return nand_scan_bbt (mtd, &agand_flashbased);
+               return nand_scan_bbt(mtd, &agand_flashbased);
        }
 
-
        /* Is a flash based bad block table requested ? */
        if (this->options & NAND_USE_FLASH_BBT) {
                /* Use the default pattern descriptors */
@@ -1066,18 +1063,17 @@ int nand_default_bbt (struct mtd_info *mtd)
                        this->bbt_md = &bbt_mirror_descr;
                }
                if (!this->badblock_pattern) {
-                       this->badblock_pattern = (mtd->oobblock > 512) ?
-                               &largepage_flashbased : &smallpage_flashbased;
+                       this->badblock_pattern = (mtd->oobblock > 512) ? &largepage_flashbased : &smallpage_flashbased;
                }
        } else {
                this->bbt_td = NULL;
                this->bbt_md = NULL;
                if (!this->badblock_pattern) {
                        this->badblock_pattern = (mtd->oobblock > 512) ?
-                               &largepage_memorybased : &smallpage_memorybased;
+                           &largepage_memorybased : &smallpage_memorybased;
                }
        }
-       return nand_scan_bbt (mtd, this->badblock_pattern);
+       return nand_scan_bbt(mtd, this->badblock_pattern);
 }
 
 /**
@@ -1087,26 +1083,29 @@ int nand_default_bbt (struct mtd_info *mtd)
  * @allowbbt:  allow access to bad block table region
  *
 */
-int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
+int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
 {
        struct nand_chip *this = mtd->priv;
        int block;
-       uint8_t res;
+       uint8_t res;
 
        /* Get block number * 2 */
-       block = (int) (offs >> (this->bbt_erase_shift - 1));
+       block = (int)(offs >> (this->bbt_erase_shift - 1));
        res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
-       DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
-               (unsigned int)offs, block >> 1, res);
+       DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+             (unsigned int)offs, block >> 1, res);
 
        switch ((int)res) {
-       case 0x00:      return 0;
-       case 0x01:      return 1;
-       case 0x02:      return allowbbt ? 0 : 1;
+       case 0x00:
+               return 0;
+       case 0x01:
+               return 1;
+       case 0x02:
+               return allowbbt ? 0 : 1;
        }
        return 1;
 }
 
-EXPORT_SYMBOL (nand_scan_bbt);
-EXPORT_SYMBOL (nand_default_bbt);
+EXPORT_SYMBOL(nand_scan_bbt);
+EXPORT_SYMBOL(nand_default_bbt);
index 40ac909..1018929 100644 (file)
@@ -62,7 +62,6 @@ static const u_char nand_ecc_precalc_table[] = {
        0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
 };
 
-
 /**
  * nand_trans_result - [GENERIC] create non-inverted ECC
  * @reg2:      line parity reg 2
@@ -71,8 +70,7 @@ static const u_char nand_ecc_precalc_table[] = {
  *
  * Creates non-inverted ECC code from line parity
  */
-static void nand_trans_result(u_char reg2, u_char reg3,
-       u_char *ecc_code)
+static void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code)
 {
        u_char a, b, i, tmp1, tmp2;
 
@@ -82,10 +80,10 @@ static void nand_trans_result(u_char reg2, u_char reg3,
 
        /* Calculate first ECC byte */
        for (i = 0; i < 4; i++) {
-               if (reg3 & a)           /* LP15,13,11,9 --> ecc_code[0] */
+               if (reg3 & a)   /* LP15,13,11,9 --> ecc_code[0] */
                        tmp1 |= b;
                b >>= 1;
-               if (reg2 & a)           /* LP14,12,10,8 --> ecc_code[0] */
+               if (reg2 & a)   /* LP14,12,10,8 --> ecc_code[0] */
                        tmp1 |= b;
                b >>= 1;
                a >>= 1;
@@ -94,10 +92,10 @@ static void nand_trans_result(u_char reg2, u_char reg3,
        /* Calculate second ECC byte */
        b = 0x80;
        for (i = 0; i < 4; i++) {
-               if (reg3 & a)           /* LP7,5,3,1 --> ecc_code[1] */
+               if (reg3 & a)   /* LP7,5,3,1 --> ecc_code[1] */
                        tmp2 |= b;
                b >>= 1;
-               if (reg2 & a)           /* LP6,4,2,0 --> ecc_code[1] */
+               if (reg2 & a)   /* LP6,4,2,0 --> ecc_code[1] */
                        tmp2 |= b;
                b >>= 1;
                a >>= 1;
@@ -124,7 +122,7 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
        ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
 
        /* Build up column parity */
-       for(j = 0; j < 256; j++) {
+       for (j = 0; j < 256; j++) {
 
                /* Get CP0 - CP5 from table */
                idx = nand_ecc_precalc_table[dat[j]];
@@ -168,8 +166,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
        if ((d1 | d2 | d3) == 0) {
                /* No errors */
                return 0;
-       }
-       else {
+       } else {
                a = (d1 ^ (d1 >> 1)) & 0x55;
                b = (d2 ^ (d2 >> 1)) & 0x55;
                c = (d3 ^ (d3 >> 1)) & 0x54;
@@ -179,14 +176,14 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                        c = 0x80;
                        add = 0;
                        a = 0x80;
-                       for (i=0; i<4; i++) {
+                       for (i = 0; i < 4; i++) {
                                if (d1 & c)
                                        add |= a;
                                c >>= 2;
                                a >>= 1;
                        }
                        c = 0x80;
-                       for (i=0; i<4; i++) {
+                       for (i = 0; i < 4; i++) {
                                if (d2 & c)
                                        add |= a;
                                c >>= 2;
@@ -195,7 +192,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                        bit = 0;
                        b = 0x04;
                        c = 0x80;
-                       for (i=0; i<3; i++) {
+                       for (i = 0; i < 3; i++) {
                                if (d3 & c)
                                        bit |= b;
                                c >>= 2;
@@ -206,8 +203,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                        a ^= (b << bit);
                        dat[add] = a;
                        return 1;
-               }
-               else {
+               } else {
                        i = 0;
                        while (d1) {
                                if (d1 & 0x01)
@@ -230,8 +226,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                                read_ecc[1] = calc_ecc[1];
                                read_ecc[2] = calc_ecc[2];
                                return 2;
-                       }
-                       else {
+                       } else {
                                /* Uncorrectable Error */
                                return -1;
                        }
index dbc7e55..a9d52fc 100644 (file)
@@ -125,13 +125,13 @@ struct nand_manufacturers nand_manuf_ids[] = {
        {NAND_MFR_NATIONAL, "National"},
        {NAND_MFR_RENESAS, "Renesas"},
        {NAND_MFR_STMICRO, "ST Micro"},
-        {NAND_MFR_HYNIX, "Hynix"},
+       {NAND_MFR_HYNIX, "Hynix"},
        {0x0, "Unknown"}
 };
 
-EXPORT_SYMBOL (nand_manuf_ids);
-EXPORT_SYMBOL (nand_flash_ids);
+EXPORT_SYMBOL(nand_manuf_ids);
+EXPORT_SYMBOL(nand_flash_ids);
 
-MODULE_LICENSE ("GPL");
-MODULE_AUTHOR ("Thomas Gleixner <tglx@linutronix.de>");
-MODULE_DESCRIPTION ("Nand device & manufacturer ID's");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
+MODULE_DESCRIPTION("Nand device & manufacturer IDs");
index a0af92c..6903f5b 100644 (file)
@@ -1546,6 +1546,8 @@ static int __init ns_init_module(void)
                chip->options |= NAND_BUSWIDTH_16;
        }
 
+       nsmtd->owner = THIS_MODULE;
+
        if ((retval = nand_scan(nsmtd, 1)) != 0) {
                NS_ERR("can't register NAND Simulator\n");
                if (retval > 0)
index 91a95f3..5d4d16f 100644 (file)
 /*
  * MTD structure for PPChameleonEVB board
  */
-static struct mtd_info *ppchameleon_mtd        = NULL;
+static struct mtd_info *ppchameleon_mtd = NULL;
 static struct mtd_info *ppchameleonevb_mtd = NULL;
 
 /*
  * Module stuff
  */
-static unsigned long ppchameleon_fio_pbase     = CFG_NAND0_PADDR;
+static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR;
 static unsigned long ppchameleonevb_fio_pbase = CFG_NAND1_PADDR;
 
 #ifdef MODULE
 module_param(ppchameleon_fio_pbase, ulong, 0);
 module_param(ppchameleonevb_fio_pbase, ulong, 0);
 #else
-__setup("ppchameleon_fio_pbase=",ppchameleon_fio_pbase);
-__setup("ppchameleonevb_fio_pbase=",ppchameleonevb_fio_pbase);
+__setup("ppchameleon_fio_pbase=", ppchameleon_fio_pbase);
+__setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
 #endif
 
 #ifdef CONFIG_MTD_PARTITIONS
@@ -80,80 +80,80 @@ __setup("ppchameleonevb_fio_pbase=",ppchameleonevb_fio_pbase);
  * Define static partitions for flash devices
  */
 static struct mtd_partition partition_info_hi[] = {
-       { name: "PPChameleon HI Nand Flash",
-                 offset: 0,
-                 size: 128*1024*1024 }
+      { .name = "PPChameleon HI Nand Flash",
+       offset = 0,
+       .size = 128 * 1024 * 1024
+      }
 };
 
 static struct mtd_partition partition_info_me[] = {
-       { name: "PPChameleon ME Nand Flash",
-                 offset: 0,
-                 size: 32*1024*1024 }
+      { .name = "PPChameleon ME Nand Flash",
+       .offset = 0,
+       .size = 32 * 1024 * 1024
+      }
 };
 
 static struct mtd_partition partition_info_evb[] = {
-       { name: "PPChameleonEVB Nand Flash",
-                 offset: 0,
-                 size: 32*1024*1024 }
+      { .name = "PPChameleonEVB Nand Flash",
+       .offset = 0,
+       .size = 32 * 1024 * 1024
+      }
 };
 
 #define NUM_PARTITIONS 1
 
-extern int parse_cmdline_partitions(struct mtd_info *master,
-                                   struct mtd_partition **pparts,
-                                   const char *mtd_id);
+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id);
 #endif
 
-
 /*
  *     hardware specific access to control-lines
  */
 static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd)
 {
-       switch(cmd) {
+       switch (cmd) {
 
        case NAND_CTL_SETCLE:
-               MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
+               MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
                break;
        case NAND_CTL_CLRCLE:
-               MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
+               MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
                break;
        case NAND_CTL_SETALE:
-               MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
+               MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
                break;
        case NAND_CTL_CLRALE:
-               MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
+               MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
                break;
        case NAND_CTL_SETNCE:
-                       MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
+               MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
                break;
        case NAND_CTL_CLRNCE:
-                       MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
+               MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
                break;
        }
 }
 
 static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd)
 {
-       switch(cmd) {
+       switch (cmd) {
 
        case NAND_CTL_SETCLE:
-               MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
+               MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
                break;
        case NAND_CTL_CLRCLE:
-               MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
+               MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
                break;
        case NAND_CTL_SETALE:
-               MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
+               MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
                break;
        case NAND_CTL_CLRALE:
-               MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
+               MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
                break;
        case NAND_CTL_SETNCE:
-               MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
+               MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
                break;
        case NAND_CTL_CLRNCE:
-               MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
+               MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
                break;
        }
 }
@@ -164,15 +164,15 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd)
  */
 static int ppchameleon_device_ready(struct mtd_info *minfo)
 {
-       if (in_be32((volatile unsigned*)GPIO0_IR) & NAND_RB_GPIO_PIN)
+       if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_RB_GPIO_PIN)
                return 1;
        return 0;
 }
 
 static int ppchameleonevb_device_ready(struct mtd_info *minfo)
 {
-       if (in_be32((volatile unsigned*)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN)
-       return 1;
+       if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN)
+               return 1;
        return 0;
 }
 #endif
@@ -185,7 +185,7 @@ const char *part_probes_evb[] = { "cmdlinepart", NULL };
 /*
  * Main initialization routine
  */
-static int __init ppchameleonevb_init (void)
+static int __init ppchameleonevb_init(void)
 {
        struct nand_chip *this;
        const char *part_type = 0;
@@ -194,13 +194,11 @@ static int __init ppchameleonevb_init (void)
        void __iomem *ppchameleon_fio_base;
        void __iomem *ppchameleonevb_fio_base;
 
-
        /*********************************
        * Processor module NAND (if any) *
        *********************************/
        /* Allocate memory for MTD device structure and private data */
-       ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) +
-                                                     sizeof(struct nand_chip), GFP_KERNEL);
+       ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!ppchameleon_mtd) {
                printk("Unable to allocate PPChameleon NAND MTD device structure.\n");
                return -ENOMEM;
@@ -208,43 +206,46 @@ static int __init ppchameleonevb_init (void)
 
        /* map physical address */
        ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M);
-       if(!ppchameleon_fio_base) {
+       if (!ppchameleon_fio_base) {
                printk("ioremap PPChameleon NAND flash failed\n");
                kfree(ppchameleon_mtd);
                return -EIO;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&ppchameleon_mtd[1]);
+       this = (struct nand_chip *)(&ppchameleon_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) ppchameleon_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(ppchameleon_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        ppchameleon_mtd->priv = this;
+       ppchameleon_mtd->owner = THIS_MODULE;
 
-        /* Initialize GPIOs */
+       /* Initialize GPIOs */
        /* Pin mapping for NAND chip */
        /*
-               CE      GPIO_01
-               CLE     GPIO_02
-               ALE     GPIO_03
-               R/B     GPIO_04
-       */
+          CE   GPIO_01
+          CLE  GPIO_02
+          ALE  GPIO_03
+          R/B  GPIO_04
+        */
        /* output select */
-       out_be32((volatile unsigned*)GPIO0_OSRH, in_be32((volatile unsigned*)GPIO0_OSRH) & 0xC0FFFFFF);
+       out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xC0FFFFFF);
        /* three-state select */
-       out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xC0FFFFFF);
+       out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xC0FFFFFF);
        /* enable output driver */
-       out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN);
+       out_be32((volatile unsigned *)GPIO0_TCR,
+                in_be32((volatile unsigned *)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN);
 #ifdef USE_READY_BUSY_PIN
        /* three-state select */
-       out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFF3FFFFF);
+       out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFF3FFFFF);
        /* high-impedecence */
-       out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) & (~NAND_RB_GPIO_PIN));
+       out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_RB_GPIO_PIN));
        /* input select */
-       out_be32((volatile unsigned*)GPIO0_ISR1H, (in_be32((volatile unsigned*)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000);
+       out_be32((volatile unsigned *)GPIO0_ISR1H,
+                (in_be32((volatile unsigned *)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000);
 #endif
 
        /* insert callbacks */
@@ -259,12 +260,11 @@ static int __init ppchameleonevb_init (void)
        this->eccmode = NAND_ECC_SOFT;
 
        /* Scan to find existence of the device (it could not be mounted) */
-       if (nand_scan (ppchameleon_mtd, 1)) {
+       if (nand_scan(ppchameleon_mtd, 1)) {
                iounmap((void *)ppchameleon_fio_base);
-               kfree (ppchameleon_mtd);
+               kfree(ppchameleon_mtd);
                goto nand_evb_init;
        }
-
 #ifndef USE_READY_BUSY_PIN
        /* Adjust delay if necessary */
        if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
@@ -275,12 +275,11 @@ static int __init ppchameleonevb_init (void)
        ppchameleon_mtd->name = "ppchameleon-nand";
        mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0);
        if (mtd_parts_nb > 0)
-         part_type = "command line";
+               part_type = "command line";
        else
-         mtd_parts_nb = 0;
+               mtd_parts_nb = 0;
 #endif
-       if (mtd_parts_nb == 0)
-       {
+       if (mtd_parts_nb == 0) {
                if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
                        mtd_parts = partition_info_me;
                else
@@ -293,13 +292,12 @@ static int __init ppchameleonevb_init (void)
        printk(KERN_NOTICE "Using %s partition definition\n", part_type);
        add_mtd_partitions(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
 
-nand_evb_init:
+ nand_evb_init:
        /****************************
        * EVB NAND (always present) *
        ****************************/
        /* Allocate memory for MTD device structure and private data */
-       ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) +
-                                                        sizeof(struct nand_chip), GFP_KERNEL);
+       ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!ppchameleonevb_mtd) {
                printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n");
                return -ENOMEM;
@@ -307,46 +305,47 @@ nand_evb_init:
 
        /* map physical address */
        ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M);
-       if(!ppchameleonevb_fio_base) {
+       if (!ppchameleonevb_fio_base) {
                printk("ioremap PPChameleonEVB NAND flash failed\n");
                kfree(ppchameleonevb_mtd);
                return -EIO;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&ppchameleonevb_mtd[1]);
+       this = (struct nand_chip *)(&ppchameleonevb_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) ppchameleonevb_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(ppchameleonevb_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        ppchameleonevb_mtd->priv = this;
 
-        /* Initialize GPIOs */
+       /* Initialize GPIOs */
        /* Pin mapping for NAND chip */
        /*
-               CE      GPIO_14
-               CLE     GPIO_15
-               ALE     GPIO_16
-               R/B     GPIO_31
-       */
+          CE   GPIO_14
+          CLE  GPIO_15
+          ALE  GPIO_16
+          R/B  GPIO_31
+        */
        /* output select */
-       out_be32((volatile unsigned*)GPIO0_OSRH, in_be32((volatile unsigned*)GPIO0_OSRH) & 0xFFFFFFF0);
-       out_be32((volatile unsigned*)GPIO0_OSRL, in_be32((volatile unsigned*)GPIO0_OSRL) & 0x3FFFFFFF);
+       out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xFFFFFFF0);
+       out_be32((volatile unsigned *)GPIO0_OSRL, in_be32((volatile unsigned *)GPIO0_OSRL) & 0x3FFFFFFF);
        /* three-state select */
-       out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
-       out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
+       out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFFFFFFF0);
+       out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0x3FFFFFFF);
        /* enable output driver */
-       out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
+       out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
                 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
 #ifdef USE_READY_BUSY_PIN
        /* three-state select */
-       out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0xFFFFFFFC);
+       out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0xFFFFFFFC);
        /* high-impedecence */
-       out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN));
+       out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN));
        /* input select */
-       out_be32((volatile unsigned*)GPIO0_ISR1L, (in_be32((volatile unsigned*)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001);
+       out_be32((volatile unsigned *)GPIO0_ISR1L,
+                (in_be32((volatile unsigned *)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001);
 #endif
 
        /* insert callbacks */
@@ -362,22 +361,20 @@ nand_evb_init:
        this->eccmode = NAND_ECC_SOFT;
 
        /* Scan to find existence of the device */
-       if (nand_scan (ppchameleonevb_mtd, 1)) {
+       if (nand_scan(ppchameleonevb_mtd, 1)) {
                iounmap((void *)ppchameleonevb_fio_base);
-               kfree (ppchameleonevb_mtd);
+               kfree(ppchameleonevb_mtd);
                return -ENXIO;
        }
-
 #ifdef CONFIG_MTD_PARTITIONS
        ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
        mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0);
        if (mtd_parts_nb > 0)
-         part_type = "command line";
+               part_type = "command line";
        else
-         mtd_parts_nb = 0;
+               mtd_parts_nb = 0;
 #endif
-       if (mtd_parts_nb == 0)
-       {
+       if (mtd_parts_nb == 0) {
                mtd_parts = partition_info_evb;
                mtd_parts_nb = NUM_PARTITIONS;
                part_type = "static";
@@ -390,18 +387,19 @@ nand_evb_init:
        /* Return happy */
        return 0;
 }
+
 module_init(ppchameleonevb_init);
 
 /*
  * Clean up routine
  */
-static void __exit ppchameleonevb_cleanup (void)
+static void __exit ppchameleonevb_cleanup(void)
 {
        struct nand_chip *this;
 
        /* Release resources, unregister device(s) */
-       nand_release (ppchameleon_mtd);
-       nand_release (ppchameleonevb_mtd);
+       nand_release(ppchameleon_mtd);
+       nand_release(ppchameleonevb_mtd);
 
        /* Release iomaps */
        this = (struct nand_chip *) &ppchameleon_mtd[1];
index 4129c03..bc9d849 100644 (file)
@@ -97,12 +97,12 @@ static struct mtd_info *rtc_from4_mtd = NULL;
 static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
 
 static const struct mtd_partition partition_info[] = {
-        {
-                .name   = "Renesas flash partition 1",
-                .offset = 0,
-                .size   = MTDPART_SIZ_FULL
-        },
+       {
+        .name = "Renesas flash partition 1",
+        .offset = 0,
+        .size = MTDPART_SIZ_FULL},
 };
+
 #define NUM_PARTITIONS 1
 
 /*
@@ -111,8 +111,8 @@ static const struct mtd_partition partition_info[] = {
  *             NAND_BBT_CREATE and/or NAND_BBT_WRITE
  *
  */
-static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
-static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
 
 static struct nand_bbt_descr rtc_from4_bbt_main_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
@@ -134,8 +134,6 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
        .pattern = mirror_pattern
 };
 
-
-
 #ifdef RTC_FROM4_HWECC
 
 /* the Reed Solomon control structure */
@@ -148,11 +146,11 @@ static struct nand_oobinfo rtc_from4_nand_oobinfo = {
        .useecc = MTD_NANDECC_AUTOPLACE,
        .eccbytes = 32,
        .eccpos = {
-                0,  1,  2,  3,  4,  5,  6,  7,
-                8,  9, 10, 11, 12, 13, 14, 15,
-               16, 17, 18, 19, 20, 21, 22, 23,
-               24, 25, 26, 27, 28, 29, 30, 31},
-       .oobfree = { {32, 32} }
+                  0, 1, 2, 3, 4, 5, 6, 7,
+                  8, 9, 10, 11, 12, 13, 14, 15,
+                  16, 17, 18, 19, 20, 21, 22, 23,
+                  24, 25, 26, 27, 28, 29, 30, 31},
+       .oobfree = {{32, 32}}
 };
 
 /* Aargh. I missed the reversed bit order, when I
@@ -162,44 +160,42 @@ static struct nand_oobinfo rtc_from4_nand_oobinfo = {
  * of the ecc byte which we get from the FPGA
  */
 static uint8_t revbits[256] = {
-        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+       0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+       0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+       0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+       0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+       0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+       0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+       0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+       0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+       0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+       0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+       0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+       0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+       0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+       0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+       0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+       0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+       0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+       0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+       0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+       0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+       0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+       0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+       0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+       0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+       0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+       0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+       0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+       0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+       0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+       0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+       0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+       0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
 };
 
 #endif
 
-
-
 /*
  * rtc_from4_hwcontrol - hardware specific access to control-lines
  * @mtd:       MTD device structure
@@ -214,9 +210,9 @@ static uint8_t revbits[256] = {
  */
 static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
 {
-       struct nand_chip* this = (struct nand_chip *) (mtd->priv);
+       struct nand_chip *this = (struct nand_chip *)(mtd->priv);
 
-       switch(cmd) {
+       switch (cmd) {
 
        case NAND_CTL_SETCLE:
                this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
@@ -240,7 +236,6 @@ static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
        }
 }
 
-
 /*
  * rtc_from4_nand_select_chip - hardware specific chip select
  * @mtd:       MTD device structure
@@ -252,26 +247,25 @@ static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
  */
 static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
 {
-        struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd->priv;
 
        this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK);
        this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK);
 
-        switch(chip) {
+       switch (chip) {
 
-        case 0:                /* select slot 3 chip */
+       case 0:         /* select slot 3 chip */
                this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3);
                this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3);
-                break;
-        case 1:                /* select slot 4 chip */
+               break;
+       case 1:         /* select slot 4 chip */
                this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4);
                this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4);
-                break;
+               break;
 
-        }
+       }
 }
 
-
 /*
  * rtc_from4_nand_device_ready - hardware specific ready/busy check
  * @mtd:       MTD device structure
@@ -290,7 +284,6 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
 
 }
 
-
 /*
  * deplete - code to perform device recovery in case there was a power loss
  * @mtd:       MTD device structure
@@ -306,24 +299,23 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
  */
 static void deplete(struct mtd_info *mtd, int chip)
 {
-        struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd->priv;
 
-        /* wait until device is ready */
-        while (!this->dev_ready(mtd));
+       /* wait until device is ready */
+       while (!this->dev_ready(mtd)) ;
 
        this->select_chip(mtd, chip);
 
        /* Send the commands for device recovery, phase 1 */
-       this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
-       this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
+       this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
 
        /* Send the commands for device recovery, phase 2 */
-       this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
-       this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
+       this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
 
 }
 
-
 #ifdef RTC_FROM4_HWECC
 /*
  * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@@ -335,39 +327,35 @@ static void deplete(struct mtd_info *mtd, int chip)
  */
 static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
 {
-       volatile unsigned short * rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
+       volatile unsigned short *rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
        unsigned short status;
 
        switch (mode) {
-           case NAND_ECC_READ :
-               status =  RTC_FROM4_RS_ECC_CTL_CLR
-                       | RTC_FROM4_RS_ECC_CTL_FD_E;
+       case NAND_ECC_READ:
+               status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_FD_E;
 
                *rs_ecc_ctl = status;
                break;
 
-           case NAND_ECC_READSYN :
-               status =  0x00;
+       case NAND_ECC_READSYN:
+               status = 0x00;
 
                *rs_ecc_ctl = status;
                break;
 
-           case NAND_ECC_WRITE :
-               status =  RTC_FROM4_RS_ECC_CTL_CLR
-                       | RTC_FROM4_RS_ECC_CTL_GEN
-                       | RTC_FROM4_RS_ECC_CTL_FD_E;
+       case NAND_ECC_WRITE:
+               status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_FD_E;
 
                *rs_ecc_ctl = status;
                break;
 
-           default:
+       default:
                BUG();
                break;
        }
 
 }
 
-
 /*
  * rtc_from4_calculate_ecc - hardware specific code to read ECC code
  * @mtd:       MTD device structure
@@ -383,7 +371,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
  */
 static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
 {
-       volatile unsigned short * rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
+       volatile unsigned short *rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
        unsigned short value;
        int i;
 
@@ -395,7 +383,6 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
        ecc_code[7] |= 0x0f;    /* set the last four bits (not used) */
 }
 
-
 /*
  * rtc_from4_correct_data - hardware specific code to correct data using ECC code
  * @mtd:       MTD device structure
@@ -414,7 +401,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
        unsigned short status;
        uint16_t par[6], syn[6];
        uint8_t ecc[8];
-        volatile unsigned short *rs_ecc;
+       volatile unsigned short *rs_ecc;
 
        status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK));
 
@@ -424,23 +411,18 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
 
        /* Read the syndrom pattern from the FPGA and correct the bitorder */
        rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
-        for (i = 0; i < 8; i++) {
-                ecc[i] = revbits[(*rs_ecc) & 0xFF];
-                rs_ecc++;
-        }
+       for (i = 0; i < 8; i++) {
+               ecc[i] = revbits[(*rs_ecc) & 0xFF];
+               rs_ecc++;
+       }
 
        /* convert into 6 10bit syndrome fields */
-       par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
-                                     (((uint16_t)ecc[1] << 8) & 0x300)];
-       par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
-                                     (((uint16_t)ecc[2] << 6) & 0x3c0)];
-       par[3] = rs_decoder->index_of[(((uint16_t)ecc[2] >> 4) & 0x00f) |
-                                     (((uint16_t)ecc[3] << 4) & 0x3f0)];
-       par[2] = rs_decoder->index_of[(((uint16_t)ecc[3] >> 6) & 0x003) |
-                                     (((uint16_t)ecc[4] << 2) & 0x3fc)];
-       par[1] = rs_decoder->index_of[(((uint16_t)ecc[5] >> 0) & 0x0ff) |
-                                     (((uint16_t)ecc[6] << 8) & 0x300)];
-       par[0] = (((uint16_t)ecc[6] >> 2) & 0x03f) | (((uint16_t)ecc[7] << 6) & 0x3c0);
+       par[5] = rs_decoder->index_of[(((uint16_t) ecc[0] >> 0) & 0x0ff) | (((uint16_t) ecc[1] << 8) & 0x300)];
+       par[4] = rs_decoder->index_of[(((uint16_t) ecc[1] >> 2) & 0x03f) | (((uint16_t) ecc[2] << 6) & 0x3c0)];
+       par[3] = rs_decoder->index_of[(((uint16_t) ecc[2] >> 4) & 0x00f) | (((uint16_t) ecc[3] << 4) & 0x3f0)];
+       par[2] = rs_decoder->index_of[(((uint16_t) ecc[3] >> 6) & 0x003) | (((uint16_t) ecc[4] << 2) & 0x3fc)];
+       par[1] = rs_decoder->index_of[(((uint16_t) ecc[5] >> 0) & 0x0ff) | (((uint16_t) ecc[6] << 8) & 0x300)];
+       par[0] = (((uint16_t) ecc[6] >> 2) & 0x03f) | (((uint16_t) ecc[7] << 6) & 0x3c0);
 
        /* Convert to computable syndrome */
        for (i = 0; i < 6; i++) {
@@ -453,16 +435,14 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
                syn[i] = rs_decoder->index_of[syn[i]];
        }
 
-       /* Let the library code do its magic.*/
-       res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
+       /* Let the library code do its magic. */
+       res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
        if (res > 0) {
-               DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
-                       "ECC corrected %d errors on read\n", res);
+               DEBUG(MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
        }
        return res;
 }
 
-
 /**
  * rtc_from4_errstat - perform additional error status checks
  * @mtd:       MTD device structure
@@ -480,44 +460,44 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
  */
 static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page)
 {
-       int     er_stat=0;
-       int     rtn, retlen;
-       size_t  len;
+       int er_stat = 0;
+       int rtn, retlen;
+       size_t len;
        uint8_t *buf;
-       int     i;
+       int i;
 
-       this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
+       this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
 
-        if (state == FL_ERASING) {
-               for (i=0; i<4; i++) {
-                       if (status & 1<<(i+1)) {
-                               this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
+       if (state == FL_ERASING) {
+               for (i = 0; i < 4; i++) {
+                       if (status & 1 << (i + 1)) {
+                               this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
                                rtn = this->read_byte(mtd);
-                               this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
+                               this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
                                if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
-                                       er_stat |= 1<<(i+1);    /* err_ecc_not_avail */
+                                       er_stat |= 1 << (i + 1);        /* err_ecc_not_avail */
                                }
                        }
                }
        } else if (state == FL_WRITING) {
                /* single bank write logic */
-               this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1);
+               this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1);
                rtn = this->read_byte(mtd);
-               this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
+               this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
                if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
-                       er_stat |= 1<<1;        /* err_ecc_not_avail */
+                       er_stat |= 1 << 1;      /* err_ecc_not_avail */
                } else {
                        len = mtd->oobblock;
-                       buf = kmalloc (len, GFP_KERNEL);
+                       buf = kmalloc(len, GFP_KERNEL);
                        if (!buf) {
-                               printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n");
-                               er_stat = 1;                    /* if we can't check, assume failed */
+                               printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
+                               er_stat = 1;    /* if we can't check, assume failed */
                        } else {
                                /* recovery read */
                                /* page read */
-                               rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
+                               rtn = nand_do_read_ecc(mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
                                if (rtn) {      /* if read failed or > 1-bit error corrected */
-                                       er_stat |= 1<<1;        /* ECC read failed */
+                                       er_stat |= 1 << 1;      /* ECC read failed */
                                }
                                kfree(buf);
                        }
@@ -525,7 +505,7 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
        }
 
        rtn = status;
-       if (er_stat == 0) {                             /* if ECC is available   */
+       if (er_stat == 0) {     /* if ECC is available   */
                rtn = (status & ~NAND_STATUS_FAIL);     /*   clear the error bit */
        }
 
@@ -533,33 +513,32 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
 }
 #endif
 
-
 /*
  * Main initialization routine
  */
-int __init rtc_from4_init (void)
+static int __init rtc_from4_init(void)
 {
        struct nand_chip *this;
        unsigned short bcr1, bcr2, wcr2;
        int i;
 
        /* Allocate memory for MTD device structure and private data */
-       rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),
-                               GFP_KERNEL);
+       rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!rtc_from4_mtd) {
-               printk ("Unable to allocate Renesas NAND MTD device structure.\n");
+               printk("Unable to allocate Renesas NAND MTD device structure.\n");
                return -ENOMEM;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&rtc_from4_mtd[1]);
+       this = (struct nand_chip *)(&rtc_from4_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) rtc_from4_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(rtc_from4_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        rtc_from4_mtd->priv = this;
+       rtc_from4_mtd->owner = THIS_MODULE;
 
        /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */
        bcr1 = *SH77X9_BCR1 & ~0x0002;
@@ -582,7 +561,7 @@ int __init rtc_from4_init (void)
        /* Set address of hardware control function */
        this->hwcontrol = rtc_from4_hwcontrol;
        /* Set address of chip select function */
-        this->select_chip = rtc_from4_nand_select_chip;
+       this->select_chip = rtc_from4_nand_select_chip;
        /* command delay time (in us) */
        this->chip_delay = 100;
        /* return the status of the Ready/Busy line */
@@ -591,7 +570,7 @@ int __init rtc_from4_init (void)
 #ifdef RTC_FROM4_HWECC
        printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n");
 
-        this->eccmode = NAND_ECC_HW8_512;
+       this->eccmode = NAND_ECC_HW8_512;
        this->options |= NAND_HWECC_SYNDROME;
        /* return the status of extra status and ECC checks */
        this->errstat = rtc_from4_errstat;
@@ -617,7 +596,7 @@ int __init rtc_from4_init (void)
        }
 
        /* Perform 'device recovery' for each chip in case there was a power loss. */
-       for (i=0; i < this->numchips; i++) {
+       for (i = 0; i < this->numchips; i++) {
                deplete(rtc_from4_mtd, i);
        }
 
@@ -643,7 +622,7 @@ int __init rtc_from4_init (void)
         */
        rs_decoder = init_rs(10, 0x409, 0, 1, 6);
        if (!rs_decoder) {
-               printk (KERN_ERR "Could not create a RS decoder\n");
+               printk(KERN_ERR "Could not create a RS decoder\n");
                nand_release(rtc_from4_mtd);
                kfree(rtc_from4_mtd);
                return -ENOMEM;
@@ -652,20 +631,19 @@ int __init rtc_from4_init (void)
        /* Return happy */
        return 0;
 }
-module_init(rtc_from4_init);
 
+module_init(rtc_from4_init);
 
 /*
  * Clean up routine
  */
-#ifdef MODULE
-static void __exit rtc_from4_cleanup (void)
+static void __exit rtc_from4_cleanup(void)
 {
        /* Release resource, unregister partitions */
        nand_release(rtc_from4_mtd);
 
        /* Free the MTD device structure */
-       kfree (rtc_from4_mtd);
+       kfree(rtc_from4_mtd);
 
 #ifdef RTC_FROM4_HWECC
        /* Free the reed solomon resources */
@@ -674,10 +652,9 @@ static void __exit rtc_from4_cleanup (void)
        }
 #endif
 }
+
 module_exit(rtc_from4_cleanup);
-#endif
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("d.marlin <dmarlin@redhat.com");
 MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4");
-
index 5b55599..f800259 100644 (file)
@@ -77,10 +77,10 @@ static int hardware_ecc = 0;
  */
 
 static struct nand_oobinfo nand_hw_eccoob = {
-       .useecc         = MTD_NANDECC_AUTOPLACE,
-       .eccbytes       = 3,
-       .eccpos         = {0, 1, 2 },
-       .oobfree        = { {8, 8} }
+       .useecc = MTD_NANDECC_AUTOPLACE,
+       .eccbytes = 3,
+       .eccpos = {0, 1, 2},
+       .oobfree = {{8, 8}}
 };
 
 /* controller and mtd information */
@@ -149,8 +149,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
        pr_debug("result %d from %ld, %d\n", result, clk, wanted);
 
        if (result > max) {
-               printk("%d ns is too big for current clock rate %ld\n",
-                      wanted, clk);
+               printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
                return -1;
        }
 
@@ -164,8 +163,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
 
 /* controller setup */
 
-static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
-                              struct platform_device *pdev)
+static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, struct platform_device *pdev)
 {
        struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
        unsigned long clkrate = clk_get_rate(info->clk);
@@ -177,7 +175,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
        clkrate /= 1000;        /* turn clock into kHz for ease of use */
 
        if (plat != NULL) {
-               tacls  = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
+               tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
                twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
                twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
        } else {
@@ -193,19 +191,17 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
        }
 
        printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
-              tacls, to_ns(tacls, clkrate),
-              twrph0, to_ns(twrph0, clkrate),
-              twrph1, to_ns(twrph1, clkrate));
+              tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
 
        if (!info->is_s3c2440) {
-               cfg  = S3C2410_NFCONF_EN;
-               cfg |= S3C2410_NFCONF_TACLS(tacls-1);
-               cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
-               cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
+               cfg = S3C2410_NFCONF_EN;
+               cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
+               cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
+               cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
        } else {
-               cfg   = S3C2440_NFCONF_TACLS(tacls-1);
-               cfg  |= S3C2440_NFCONF_TWRPH0(twrph0-1);
-               cfg  |= S3C2440_NFCONF_TWRPH1(twrph1-1);
+               cfg = S3C2440_NFCONF_TACLS(tacls - 1);
+               cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
+               cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
        }
 
        pr_debug(PFX "NF_CONF is 0x%lx\n", cfg);
@@ -229,7 +225,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
        info = nmtd->info;
 
        bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
-       reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF);
+       reg = info->regs + ((info->is_s3c2440) ? S3C2440_NFCONT : S3C2410_NFCONF);
 
        cur = readl(reg);
 
@@ -243,7 +239,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
 
                if (info->platform != NULL) {
                        if (info->platform->select_chip != NULL)
-                               (info->platform->select_chip)(nmtd->set, chip);
+                               (info->platform->select_chip) (nmtd->set, chip);
                }
 
                cur &= ~bit;
@@ -330,22 +326,16 @@ static int s3c2410_nand_devready(struct mtd_info *mtd)
        return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
 }
 
-
 /* ECC handling functions */
 
-static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
-                                    u_char *read_ecc, u_char *calc_ecc)
+static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
 {
-       pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n",
-                mtd, dat, read_ecc, calc_ecc);
+       pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc);
 
        pr_debug("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n",
-                read_ecc[0], read_ecc[1], read_ecc[2],
-                calc_ecc[0], calc_ecc[1], calc_ecc[2]);
+                read_ecc[0], read_ecc[1], read_ecc[2], calc_ecc[0], calc_ecc[1], calc_ecc[2]);
 
-       if (read_ecc[0] == calc_ecc[0] &&
-           read_ecc[1] == calc_ecc[1] &&
-           read_ecc[2] == calc_ecc[2])
+       if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2])
                return 0;
 
        /* we curently have no method for correcting the error */
@@ -378,8 +368,7 @@ static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
        writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
 }
 
-static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
-                                     const u_char *dat, u_char *ecc_code)
+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
 {
        struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
 
@@ -387,15 +376,12 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
        ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
        ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
 
-       pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
-                ecc_code[0], ecc_code[1], ecc_code[2]);
+       pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
 
        return 0;
 }
 
-
-static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
-                                     const u_char *dat, u_char *ecc_code)
+static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
 {
        struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
        unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
@@ -404,13 +390,11 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
        ecc_code[1] = ecc >> 8;
        ecc_code[2] = ecc >> 16;
 
-       pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
-                ecc_code[0], ecc_code[1], ecc_code[2]);
+       pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
 
        return 0;
 }
 
-
 /* over-ride the standard functions for a little more speed. We can
  * use read/write block to move the data buffers to/from the controller
 */
@@ -421,8 +405,7 @@ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
        readsb(this->IO_ADDR_R, buf, len);
 }
 
-static void s3c2410_nand_write_buf(struct mtd_info *mtd,
-                                  const u_char *buf, int len)
+static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        writesb(this->IO_ADDR_W, buf, len);
@@ -488,9 +471,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
                return add_mtd_device(&mtd->mtd);
 
        if (set->nr_partitions > 0 && set->partitions != NULL) {
-               return add_mtd_partitions(&mtd->mtd,
-                                         set->partitions,
-                                         set->nr_partitions);
+               return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);
        }
 
        return add_mtd_device(&mtd->mtd);
@@ -535,6 +516,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
 
        nmtd->info         = info;
        nmtd->mtd.priv     = chip;
+       nmtd->mtd.owner    = THIS_MODULE;
        nmtd->set          = set;
 
        if (hardware_ecc) {
@@ -654,13 +636,11 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
        nmtd = info->mtds;
 
        for (setno = 0; setno < nr_sets; setno++, nmtd++) {
-               pr_debug("initialising set %d (%p, info %p)\n",
-                        setno, nmtd, info);
+               pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info);
 
                s3c2410_nand_init_chip(info, nmtd, sets);
 
-               nmtd->scan_res = nand_scan(&nmtd->mtd,
-                                          (sets) ? sets->nr_chips : 1);
+               nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);
 
                if (nmtd->scan_res == 0) {
                        s3c2410_nand_add_partition(info, nmtd, sets);
index c294374..60e10c0 100644 (file)
@@ -46,7 +46,6 @@ static int sharpsl_phys_base = 0x0C000000;
 #define FLCLE          (1 << 1)
 #define FLCE0          (1 << 0)
 
-
 /*
  * MTD structure for SharpSL
  */
@@ -60,27 +59,26 @@ static struct mtd_info *sharpsl_mtd = NULL;
 static int nr_partitions;
 static struct mtd_partition sharpsl_nand_default_partition_info[] = {
        {
-       .name = "System Area",
-       .offset = 0,
-       .size = 7 * 1024 * 1024,
-       },
+        .name = "System Area",
+        .offset = 0,
+        .size = 7 * 1024 * 1024,
+        },
        {
-       .name = "Root Filesystem",
-       .offset = 7 * 1024 * 1024,
-       .size = 30 * 1024 * 1024,
-       },
+        .name = "Root Filesystem",
+        .offset = 7 * 1024 * 1024,
+        .size = 30 * 1024 * 1024,
+        },
        {
-       .name = "Home Filesystem",
-       .offset = MTDPART_OFS_APPEND ,
-       .size = MTDPART_SIZ_FULL ,
-       },
+        .name = "Home Filesystem",
+        .offset = MTDPART_OFS_APPEND,
+        .size = MTDPART_SIZ_FULL,
+        },
 };
 
 /*
  *     hardware specific access to control-lines
  */
-static void
-sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
+static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd)
 {
        switch (cmd) {
        case NAND_CTL_SETCLE:
@@ -98,10 +96,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
                break;
 
        case NAND_CTL_SETNCE:
-               writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
+               writeb(readb(FLASHCTL) & ~(FLCE0 | FLCE1), FLASHCTL);
                break;
        case NAND_CTL_CLRNCE:
-               writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
+               writeb(readb(FLASHCTL) | (FLCE0 | FLCE1), FLASHCTL);
                break;
        }
 }
@@ -126,27 +124,23 @@ static struct nand_oobinfo akita_oobinfo = {
        .useecc = MTD_NANDECC_AUTOPLACE,
        .eccbytes = 24,
        .eccpos = {
-               0x5,  0x1,  0x2,  0x3,  0x6,  0x7,  0x15, 0x11,
-               0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
-               0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
-       .oobfree = { {0x08, 0x09} }
+                  0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
+                  0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
+                  0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
+       .oobfree = {{0x08, 0x09}}
 };
 
-static int
-sharpsl_nand_dev_ready(struct mtd_info* mtd)
+static int sharpsl_nand_dev_ready(struct mtd_info *mtd)
 {
        return !((readb(FLASHCTL) & FLRYBY) == 0);
 }
 
-static void
-sharpsl_nand_enable_hwecc(struct mtd_info* mtd, int mode)
+static void sharpsl_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 {
-       writeb(0 ,ECCCLRR);
+       writeb(0ECCCLRR);
 }
 
-static int
-sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
-                               u_char* ecc_code)
+static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, u_char * ecc_code)
 {
        ecc_code[0] = ~readb(ECCLPUB);
        ecc_code[1] = ~readb(ECCLPLB);
@@ -154,47 +148,44 @@ sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
        return readb(ECCCNTR) != 0;
 }
 
-
 #ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
 #endif
 
-
 /*
  * Main initialization routine
  */
-int __init
-sharpsl_nand_init(void)
+static int __init sharpsl_nand_init(void)
 {
        struct nand_chip *this;
-       struct mtd_partitionsharpsl_partition_info;
+       struct mtd_partition *sharpsl_partition_info;
        int err = 0;
 
        /* Allocate memory for MTD device structure and private data */
-       sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
-                               GFP_KERNEL);
+       sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!sharpsl_mtd) {
-               printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
+               printk("Unable to allocate SharpSL NAND MTD device structure.\n");
                return -ENOMEM;
        }
 
        /* map physical adress */
        sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
-       if(!sharpsl_io_base){
+       if (!sharpsl_io_base) {
                printk("ioremap to access Sharp SL NAND chip failed\n");
                kfree(sharpsl_mtd);
                return -EIO;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&sharpsl_mtd[1]);
+       this = (struct nand_chip *)(&sharpsl_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) sharpsl_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(sharpsl_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        sharpsl_mtd->priv = this;
+       sharpsl_mtd->owner = THIS_MODULE;
 
        /*
         * PXA initialize
@@ -221,7 +212,7 @@ sharpsl_nand_init(void)
        this->correct_data = nand_correct_data;
 
        /* Scan to find existence of the device */
-       err=nand_scan(sharpsl_mtd,1);
+       err = nand_scan(sharpsl_mtd, 1);
        if (err) {
                iounmap(sharpsl_io_base);
                kfree(sharpsl_mtd);
@@ -230,24 +221,23 @@ sharpsl_nand_init(void)
 
        /* Register the partitions */
        sharpsl_mtd->name = "sharpsl-nand";
-       nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
-                                               &sharpsl_partition_info, 0);
+       nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, &sharpsl_partition_info, 0);
 
        if (nr_partitions <= 0) {
                nr_partitions = DEFAULT_NUM_PARTITIONS;
                sharpsl_partition_info = sharpsl_nand_default_partition_info;
                if (machine_is_poodle()) {
-                       sharpsl_partition_info[1].size=22 * 1024 * 1024;
+                       sharpsl_partition_info[1].size = 22 * 1024 * 1024;
                } else if (machine_is_corgi() || machine_is_shepherd()) {
-                       sharpsl_partition_info[1].size=25 * 1024 * 1024;
+                       sharpsl_partition_info[1].size = 25 * 1024 * 1024;
                } else if (machine_is_husky()) {
-                       sharpsl_partition_info[1].size=53 * 1024 * 1024;
+                       sharpsl_partition_info[1].size = 53 * 1024 * 1024;
                } else if (machine_is_spitz()) {
-                       sharpsl_partition_info[1].size=5 * 1024 * 1024;
+                       sharpsl_partition_info[1].size = 5 * 1024 * 1024;
                } else if (machine_is_akita()) {
-                       sharpsl_partition_info[1].size=58 * 1024 * 1024;
+                       sharpsl_partition_info[1].size = 58 * 1024 * 1024;
                } else if (machine_is_borzoi()) {
-                       sharpsl_partition_info[1].size=32 * 1024 * 1024;
+                       sharpsl_partition_info[1].size = 32 * 1024 * 1024;
                }
        }
 
@@ -261,15 +251,15 @@ sharpsl_nand_init(void)
        /* Return happy */
        return 0;
 }
+
 module_init(sharpsl_nand_init);
 
 /*
  * Clean up routine
  */
-#ifdef MODULE
 static void __exit sharpsl_nand_cleanup(void)
 {
-       struct nand_chip *this = (struct nand_chip *) &sharpsl_mtd[1];
+       struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1];
 
        /* Release resources, unregister device */
        nand_release(sharpsl_mtd);
@@ -279,8 +269,8 @@ static void __exit sharpsl_nand_cleanup(void)
        /* Free the MTD device structure */
        kfree(sharpsl_mtd);
 }
+
 module_exit(sharpsl_nand_cleanup);
-#endif
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
index 9cf1ce7..9737f1d 100644 (file)
@@ -39,16 +39,16 @@ static struct mtd_info *spia_mtd = NULL;
  */
 #define SPIA_IO_BASE   0xd0000000      /* Start of EP7212 IO address space */
 #define SPIA_FIO_BASE  0xf0000000      /* Address where flash is mapped */
-#define SPIA_PEDR      0x0080          /*
-                                        * IO offset to Port E data register
-                                        * where the CLE, ALE and NCE pins
-                                        * are wired to.
-                                        */
-#define SPIA_PEDDR     0x00c0          /*
-                                        * IO offset to Port E data direction
-                                        * register so we can control the IO
-                                        * lines.
-                                        */
+#define SPIA_PEDR      0x0080  /*
+                                * IO offset to Port E data register
+                                * where the CLE, ALE and NCE pins
+                                * are wired to.
+                                */
+#define SPIA_PEDDR     0x00c0  /*
+                                * IO offset to Port E data direction
+                                * register so we can control the IO
+                                * lines.
+                                */
 
 /*
  * Module stuff
@@ -69,25 +69,23 @@ module_param(spia_peddr, int, 0);
  */
 static const struct mtd_partition partition_info[] = {
        {
-               .name   = "SPIA flash partition 1",
-               .offset = 0,
-               .size   = 2*1024*1024
-       },
+        .name = "SPIA flash partition 1",
+        .offset = 0,
+        .size = 2 * 1024 * 1024},
        {
-               .name   = "SPIA flash partition 2",
-               .offset = 2*1024*1024,
-               .size   = 6*1024*1024
-       }
+        .name = "SPIA flash partition 2",
+        .offset = 2 * 1024 * 1024,
+        .size = 6 * 1024 * 1024}
 };
-#define NUM_PARTITIONS 2
 
+#define NUM_PARTITIONS 2
 
 /*
  *     hardware specific access to control-lines
 */
-static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
-
-    switch(cmd){
+static void spia_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+       switch (cmd) {
 
        case NAND_CTL_SETCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |=  0x01; break;
        case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x01; break;
@@ -97,51 +95,51 @@ static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
 
        case NAND_CTL_SETNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x04; break;
        case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |=  0x04; break;
-    }
+       }
 }
 
 /*
  * Main initialization routine
  */
-int __init spia_init (void)
+static int __init spia_init(void)
 {
        struct nand_chip *this;
 
        /* Allocate memory for MTD device structure and private data */
-       spia_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-                               GFP_KERNEL);
+       spia_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!spia_mtd) {
-               printk ("Unable to allocate SPIA NAND MTD device structure.\n");
+               printk("Unable to allocate SPIA NAND MTD device structure.\n");
                return -ENOMEM;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&spia_mtd[1]);
+       this = (struct nand_chip *)(&spia_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) spia_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(spia_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        spia_mtd->priv = this;
+       spia_mtd->owner = THIS_MODULE;
 
        /*
         * Set GPIO Port E control register so that the pins are configured
         * to be outputs for controlling the NAND flash.
         */
-       (*(volatile unsigned char *) (spia_io_base + spia_peddr)) = 0x07;
+       (*(volatile unsigned char *)(spia_io_base + spia_peddr)) = 0x07;
 
        /* Set address of NAND IO lines */
-       this->IO_ADDR_R = (void __iomem *) spia_fio_base;
-       this->IO_ADDR_W = (void __iomem *) spia_fio_base;
+       this->IO_ADDR_R = (void __iomem *)spia_fio_base;
+       this->IO_ADDR_W = (void __iomem *)spia_fio_base;
        /* Set address of hardware control function */
        this->hwcontrol = spia_hwcontrol;
        /* 15 us command delay time */
        this->chip_delay = 15;
 
        /* Scan to find existence of the device */
-       if (nand_scan (spia_mtd, 1)) {
-               kfree (spia_mtd);
+       if (nand_scan(spia_mtd, 1)) {
+               kfree(spia_mtd);
                return -ENXIO;
        }
 
@@ -151,22 +149,22 @@ int __init spia_init (void)
        /* Return happy */
        return 0;
 }
+
 module_init(spia_init);
 
 /*
  * Clean up routine
  */
-#ifdef MODULE
-static void __exit spia_cleanup (void)
+static void __exit spia_cleanup(void)
 {
        /* Release resources, unregister device */
-       nand_release (spia_mtd);
+       nand_release(spia_mtd);
 
        /* Free the MTD device structure */
-       kfree (spia_mtd);
+       kfree(spia_mtd);
 }
+
 module_exit(spia_cleanup);
-#endif
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com");
index 7609c43..c51c895 100644 (file)
@@ -48,7 +48,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
 
 #define T_NAND_CTL_CLRALE(iob)  gpiosetout(NAND_ALE, 0)
 #define T_NAND_CTL_SETALE(iob)  gpiosetout(NAND_ALE, NAND_ALE)
-#ifdef CONFIG_NAND_WORKAROUND     /* "some" dev boards busted, blue wired to rts2 :( */
+#ifdef CONFIG_NAND_WORKAROUND  /* "some" dev boards busted, blue wired to rts2 :( */
 #define T_NAND_CTL_CLRCLE(iob)  gpiosetout(NAND_CLE, 0); rts2setout(2, 2)
 #define T_NAND_CTL_SETCLE(iob)  gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0)
 #else
@@ -98,9 +98,8 @@ static struct mtd_partition partition_info32M[] = {
 static void toto_hwcontrol(struct mtd_info *mtd, int cmd)
 {
 
-       udelay(1); /* hopefully enough time for tc make proceding write to clear */
-       switch(cmd){
-
+       udelay(1);              /* hopefully enough time for tc make proceding write to clear */
+       switch (cmd) {
                case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break;
                case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break;
 
@@ -110,35 +109,35 @@ static void toto_hwcontrol(struct mtd_info *mtd, int cmd)
                case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break;
                case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break;
        }
-       udelay(1); /* allow time to ensure gpio state to over take memory write */
+       udelay(1);              /* allow time to ensure gpio state to over take memory write */
 }
 
 /*
  * Main initialization routine
  */
-int __init toto_init (void)
+static int __init toto_init(void)
 {
        struct nand_chip *this;
        int err = 0;
 
        /* Allocate memory for MTD device structure and private data */
-       toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-                               GFP_KERNEL);
+       toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!toto_mtd) {
-               printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
+               printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
                err = -ENOMEM;
                goto out;
        }
 
        /* Get pointer to private data */
-       this = (struct nand_chip *) (&toto_mtd[1]);
+       this = (struct nand_chip *)(&toto_mtd[1]);
 
        /* Initialize structures */
-       memset((char *) toto_mtd, 0, sizeof(struct mtd_info));
-       memset((char *) this, 0, sizeof(struct nand_chip));
+       memset(toto_mtd, 0, sizeof(struct mtd_info));
+       memset(this, 0, sizeof(struct nand_chip));
 
        /* Link the private data with the MTD structure */
        toto_mtd->priv = this;
+       toto_mtd->owner = THIS_MODULE;
 
        /* Set address of NAND IO lines */
        this->IO_ADDR_R = toto_io_base;
@@ -149,33 +148,37 @@ int __init toto_init (void)
        this->chip_delay = 30;
        this->eccmode = NAND_ECC_SOFT;
 
-        /* Scan to find existance of the device */
-       if (nand_scan (toto_mtd, 1)) {
+       /* Scan to find existance of the device */
+       if (nand_scan(toto_mtd, 1)) {
                err = -ENXIO;
                goto out_mtd;
        }
 
        /* Register the partitions */
-       switch(toto_mtd->size){
-               case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
-               case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
-               default: {
-                       printk (KERN_WARNING "Unsupported Nand device\n");
+       switch (toto_mtd->size) {
+       case SZ_64M:
+               add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M);
+               break;
+       case SZ_32M:
+               add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M);
+               break;
+       default:{
+                       printk(KERN_WARNING "Unsupported Nand device\n");
                        err = -ENXIO;
                        goto out_buf;
                }
        }
 
-       gpioreserve(NAND_MASK);  /* claim our gpios */
-       archflashwp(0,0);        /* open up flash for writing */
+       gpioreserve(NAND_MASK); /* claim our gpios */
+       archflashwp(0, 0);      /* open up flash for writing */
 
        goto out;
 
-out_buf:
-       kfree (this->data_buf);
-out_mtd:
-       kfree (toto_mtd);
-out:
+ out_buf:
+       kfree(this->data_buf);
+ out_mtd:
+       kfree(toto_mtd);
+ out:
        return err;
 }
 
@@ -184,20 +187,21 @@ module_init(toto_init);
 /*
  * Clean up routine
  */
-static void __exit toto_cleanup (void)
+static void __exit toto_cleanup(void)
 {
        /* Release resources, unregister device */
-       nand_release (toto_mtd);
+       nand_release(toto_mtd);
 
        /* Free the MTD device structure */
-       kfree (toto_mtd);
+       kfree(toto_mtd);
 
        /* stop flash writes */
-        archflashwp(0,1);
+       archflashwp(0, 1);
 
        /* release gpios to system */
-        gpiorelease(NAND_MASK);
+       gpiorelease(NAND_MASK);
 }
+
 module_exit(toto_cleanup);
 
 MODULE_LICENSE("GPL");
index 643633d..622db31 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2004 Technologic Systems (support@embeddedARM.com)
  *
  * Derived from drivers/mtd/nand/edb7312.c
- *   Copyright (C) 2004 Marius Gröger (mag@sysgo.de)
+ *   Copyright (C) 2004 Marius Gröger (mag@sysgo.de)
  *
  * Derived from drivers/mtd/nand/autcpu12.c
  *   Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
@@ -88,7 +88,7 @@ static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd)
 {
        unsigned long ctrl = TS72XX_NAND_CONTROL_VIRT_BASE;
 
-       switch(cmd) {
+       switch (cmd) {
        case NAND_CTL_SETCLE:
                __raw_writeb(__raw_readb(ctrl) | 0x2, ctrl);
                break;
@@ -132,8 +132,7 @@ static int __init ts7250_init(void)
                return -ENXIO;
 
        /* Allocate memory for MTD device structure and private data */
-       ts7250_mtd = kmalloc(sizeof(struct mtd_info) +
-                               sizeof(struct nand_chip), GFP_KERNEL);
+       ts7250_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
        if (!ts7250_mtd) {
                printk("Unable to allocate TS7250 NAND MTD device structure.\n");
                return -ENOMEM;
@@ -148,6 +147,7 @@ static int __init ts7250_init(void)
 
        /* Link the private data with the MTD structure */
        ts7250_mtd->priv = this;
+       ts7250_mtd->owner = THIS_MODULE;
 
        /* insert callbacks */
        this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE;
@@ -163,11 +163,9 @@ static int __init ts7250_init(void)
                kfree(ts7250_mtd);
                return -ENXIO;
        }
-
 #ifdef CONFIG_MTD_PARTITIONS
        ts7250_mtd->name = "ts7250-nand";
-       mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes,
-                                               &mtd_parts, 0);
+       mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes, &mtd_parts, 0);
        if (mtd_parts_nb > 0)
                part_type = "command line";
        else
@@ -188,6 +186,7 @@ static int __init ts7250_init(void)
        /* Return happy */
        return 0;
 }
+
 module_init(ts7250_init);
 
 /*
@@ -201,6 +200,7 @@ static void __exit ts7250_cleanup(void)
        /* Free the MTD device structure */
        kfree(ts7250_mtd);
 }
+
 module_exit(ts7250_cleanup);
 
 MODULE_LICENSE("GPL");
index c077d2e..5b58523 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: redboot.c,v 1.19 2005/12/01 10:03:51 dwmw2 Exp $
+ * $Id: redboot.c,v 1.21 2006/03/30 18:34:37 bjd Exp $
  *
  * Parse RedBoot-style Flash Image System (FIS) tables and
  * produce a Linux partition array to match.
 
 struct fis_image_desc {
     unsigned char name[16];      // Null terminated name
-    unsigned long flash_base;    // Address within FLASH of image
-    unsigned long mem_base;      // Address in memory where it executes
-    unsigned long size;          // Length of image
-    unsigned long entry_point;   // Execution entry point
-    unsigned long data_length;   // Length of actual data
-    unsigned char _pad[256-(16+7*sizeof(unsigned long))];
-    unsigned long desc_cksum;    // Checksum over image descriptor
-    unsigned long file_cksum;    // Checksum over image data
+    uint32_t     flash_base;    // Address within FLASH of image
+    uint32_t     mem_base;      // Address in memory where it executes
+    uint32_t     size;          // Length of image
+    uint32_t     entry_point;   // Execution entry point
+    uint32_t     data_length;   // Length of actual data
+    unsigned char _pad[256-(16+7*sizeof(uint32_t))];
+    uint32_t     desc_cksum;    // Checksum over image descriptor
+    uint32_t     file_cksum;    // Checksum over image data
 };
 
 struct fis_list {
index a3e00a4..fa4362f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2005  Sean Young <sean@mess.org>
  *
- * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $
+ * $Id: rfd_ftl.c,v 1.8 2006/01/15 12:51:44 sean Exp $
  *
  * This type of flash translation layer (FTL) is used by the Embedded BIOS
  * by General Software. It is known as the Resident Flash Disk (RFD), see:
@@ -61,6 +61,7 @@ struct block {
                BLOCK_OK,
                BLOCK_ERASING,
                BLOCK_ERASED,
+               BLOCK_UNUSED,
                BLOCK_FAILED
        } state;
        int free_sectors;
@@ -99,10 +100,8 @@ static int build_block_map(struct partition *part, int block_no)
        block->offset = part->block_size * block_no;
 
        if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
-               block->state = BLOCK_ERASED; /* assumption */
-               block->free_sectors = part->data_sectors_per_block;
-               part->reserved_block = block_no;
-               return 1;
+               block->state = BLOCK_UNUSED;
+               return -ENOENT;
        }
 
        block->state = BLOCK_OK;
@@ -124,7 +123,7 @@ static int build_block_map(struct partition *part, int block_no)
                        entry = 0;
 
                if (entry >= part->sector_count) {
-                       printk(KERN_NOTICE PREFIX
+                       printk(KERN_WARNING PREFIX
                                "'%s': unit #%d: entry %d corrupt, "
                                "sector %d out of range\n",
                                part->mbd.mtd->name, block_no, i, entry);
@@ -132,7 +131,7 @@ static int build_block_map(struct partition *part, int block_no)
                }
 
                if (part->sector_map[entry] != -1) {
-                       printk(KERN_NOTICE PREFIX
+                       printk(KERN_WARNING PREFIX
                                "'%s': more than one entry for sector %d\n",
                                part->mbd.mtd->name, entry);
                        part->errors = 1;
@@ -167,7 +166,7 @@ static int scan_header(struct partition *part)
        /* each erase block has three bytes header, followed by the map */
        part->header_sectors_per_block =
                        ((HEADER_MAP_OFFSET + sectors_per_block) *
-                       sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
+                       sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
 
        part->data_sectors_per_block = sectors_per_block -
                        part->header_sectors_per_block;
@@ -226,7 +225,7 @@ static int scan_header(struct partition *part)
        }
 
        if (part->reserved_block == -1) {
-               printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n",
+               printk(KERN_WARNING PREFIX "'%s': no empty erase unit found\n",
                                part->mbd.mtd->name);
 
                part->errors = 1;
@@ -315,7 +314,7 @@ static void erase_callback(struct erase_info *erase)
                rc = -EIO;
 
        if (rc) {
-               printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
+               printk(KERN_ERR PREFIX "'%s': unable to write RFD "
                                "header at 0x%lx\n",
                                part->mbd.mtd->name,
                                part->blocks[i].offset);
@@ -348,7 +347,7 @@ static int erase_block(struct partition *part, int block)
        rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
 
        if (rc) {
-               printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' "
+               printk(KERN_ERR PREFIX "erase of region %x,%x on '%s' "
                                "failed\n", erase->addr, erase->len,
                                part->mbd.mtd->name);
                kfree(erase);
@@ -383,7 +382,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
                rc = -EIO;
 
        if (rc) {
-               printk(KERN_NOTICE PREFIX "error reading '%s' at "
+               printk(KERN_ERR PREFIX "error reading '%s' at "
                        "0x%lx\n", part->mbd.mtd->name,
                        part->blocks[block_no].offset);
 
@@ -423,7 +422,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
                        rc = -EIO;
 
                if (rc) {
-                       printk(KERN_NOTICE PREFIX "'%s': Unable to "
+                       printk(KERN_ERR PREFIX "'%s': Unable to "
                                "read sector for relocation\n",
                                part->mbd.mtd->name);
 
@@ -520,7 +519,7 @@ static int reclaim_block(struct partition *part, u_long *old_sector)
  * because if we fill that one up first it'll have the most chance of having
  * the least live sectors at reclaim.
  */
-static int find_free_block(const struct partition *part)
+static int find_free_block(struct partition *part)
 {
        int block, stop;
 
@@ -533,6 +532,9 @@ static int find_free_block(const struct partition *part)
                                block != part->reserved_block)
                        return block;
 
+               if (part->blocks[block].state == BLOCK_UNUSED)
+                       erase_block(part, block);
+
                if (++block >= part->total_blocks)
                        block = 0;
 
@@ -541,7 +543,7 @@ static int find_free_block(const struct partition *part)
        return -1;
 }
 
-static int find_writeable_block(struct partition *part, u_long *old_sector)
+static int find_writable_block(struct partition *part, u_long *old_sector)
 {
        int rc, block;
        size_t retlen;
@@ -570,7 +572,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector)
                rc = -EIO;
 
        if (rc) {
-               printk(KERN_NOTICE PREFIX "'%s': unable to read header at "
+               printk(KERN_ERR PREFIX "'%s': unable to read header at "
                                "0x%lx\n", part->mbd.mtd->name,
                                part->blocks[block].offset);
                goto err;
@@ -602,7 +604,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
                rc = -EIO;
 
        if (rc) {
-               printk(KERN_WARNING PREFIX "error writing '%s' at "
+               printk(KERN_ERR PREFIX "error writing '%s' at "
                        "0x%lx\n", part->mbd.mtd->name, addr);
                if (rc)
                        goto err;
@@ -652,7 +654,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
        if (part->current_block == -1 ||
                !part->blocks[part->current_block].free_sectors) {
 
-               rc = find_writeable_block(part, old_addr);
+               rc = find_writable_block(part, old_addr);
                if (rc)
                        goto err;
        }
@@ -675,7 +677,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
                rc = -EIO;
 
        if (rc) {
-               printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
+               printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
                                part->mbd.mtd->name, addr);
                if (rc)
                        goto err;
@@ -695,7 +697,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
                rc = -EIO;
 
        if (rc) {
-               printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
+               printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
                                part->mbd.mtd->name, addr);
                if (rc)
                        goto err;
@@ -776,7 +778,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                part->block_size = block_size;
        else {
                if (!mtd->erasesize) {
-                       printk(KERN_NOTICE PREFIX "please provide block_size");
+                       printk(KERN_WARNING PREFIX "please provide block_size");
                        return;
                }
                else
@@ -791,8 +793,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                if (!(mtd->flags & MTD_WRITEABLE))
                        part->mbd.readonly = 1;
                else if (part->errors) {
-                       printk(KERN_NOTICE PREFIX "'%s': errors found, "
-                                       "setting read-only", mtd->name);
+                       printk(KERN_WARNING PREFIX "'%s': errors found, "
+                                       "setting read-only\n", mtd->name);
                        part->mbd.readonly = 1;
                }
 
index 1363083..14dbad1 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/mii.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <linux/crc32.h>
 #include <asm/mipsregs.h>
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -2070,23 +2071,6 @@ static void au1000_tx_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 }
 
-
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-               unsigned char 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 crc;
-}
-
 static void set_rx_mode(struct net_device *dev)
 {
        struct au1000_private *aup = (struct au1000_private *) dev->priv;
index 1f36274..038447f 100644 (file)
@@ -53,6 +53,7 @@
 #define DRV_VERSION    "v1.17b"
 #define DRV_RELDATE    "2006/03/10"
 #include "dl2k.h"
+#include <linux/dma-mapping.h>
 
 static char version[] __devinitdata =
       KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n"; 
@@ -765,7 +766,7 @@ rio_free_tx (struct net_device *dev, int irq)
                        break;
                skb = np->tx_skbuff[entry];
                pci_unmap_single (np->pdev,
-                                 np->tx_ring[entry].fraginfo & 0xffffffffffff,
+                                 np->tx_ring[entry].fraginfo & DMA_48BIT_MASK,
                                  skb->len, PCI_DMA_TODEVICE);
                if (irq)
                        dev_kfree_skb_irq (skb);
@@ -893,7 +894,7 @@ receive_packet (struct net_device *dev)
                        /* Small skbuffs for short packets */
                        if (pkt_len > copy_thresh) {
                                pci_unmap_single (np->pdev,
-                                                 desc->fraginfo & 0xffffffffffff,
+                                                 desc->fraginfo & DMA_48BIT_MASK,
                                                  np->rx_buf_sz,
                                                  PCI_DMA_FROMDEVICE);
                                skb_put (skb = np->rx_skbuff[entry], pkt_len);
@@ -901,7 +902,7 @@ receive_packet (struct net_device *dev)
                        } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) {
                                pci_dma_sync_single_for_cpu(np->pdev,
                                                            desc->fraginfo & 
-                                                               0xffffffffffff,
+                                                               DMA_48BIT_MASK,
                                                            np->rx_buf_sz,
                                                            PCI_DMA_FROMDEVICE);
                                skb->dev = dev;
@@ -913,7 +914,7 @@ receive_packet (struct net_device *dev)
                                skb_put (skb, pkt_len);
                                pci_dma_sync_single_for_device(np->pdev,
                                                               desc->fraginfo &
-                                                                0xffffffffffff,
+                                                                DMA_48BIT_MASK,
                                                               np->rx_buf_sz,
                                                               PCI_DMA_FROMDEVICE);
                        }
@@ -1800,7 +1801,7 @@ rio_close (struct net_device *dev)
                skb = np->rx_skbuff[i];
                if (skb) {
                        pci_unmap_single(np->pdev, 
-                                        np->rx_ring[i].fraginfo & 0xffffffffffff,
+                                        np->rx_ring[i].fraginfo & DMA_48BIT_MASK,
                                         skb->len, PCI_DMA_FROMDEVICE);
                        dev_kfree_skb (skb);
                        np->rx_skbuff[i] = NULL;
@@ -1810,7 +1811,7 @@ rio_close (struct net_device *dev)
                skb = np->tx_skbuff[i];
                if (skb) {
                        pci_unmap_single(np->pdev, 
-                                        np->tx_ring[i].fraginfo & 0xffffffffffff,
+                                        np->tx_ring[i].fraginfo & DMA_48BIT_MASK,
                                         skb->len, PCI_DMA_TODEVICE);
                        dev_kfree_skb (skb);
                        np->tx_skbuff[i] = NULL;
index 79a8fbc..0d5fccc 100644 (file)
@@ -582,7 +582,6 @@ static int __init setup_adapter(int card_base, int type, int n)
                INIT_WORK(&priv->rx_work, rx_bh, priv);
                dev->priv = priv;
                sprintf(dev->name, "dmascc%i", 2 * n + i);
-               SET_MODULE_OWNER(dev);
                dev->base_addr = card_base;
                dev->irq = irq;
                dev->open = scc_open;
index 6ace0e9..5927784 100644 (file)
@@ -1550,7 +1550,6 @@ static unsigned char ax25_nocall[AX25_ADDR_LEN] =
 
 static void scc_net_setup(struct net_device *dev)
 {
-       SET_MODULE_OWNER(dev);
        dev->tx_queue_len    = 16;      /* should be enough... */
 
        dev->open            = scc_net_open;
index fe22479..b498840 100644 (file)
@@ -1098,7 +1098,6 @@ static void yam_setup(struct net_device *dev)
 
        dev->base_addr = yp->iobase;
        dev->irq = yp->irq;
-       SET_MODULE_OWNER(dev);
 
        dev->open = yam_open;
        dev->stop = yam_close;
index 27ab75f..c1ce239 100644 (file)
@@ -46,4 +46,4 @@ obj-$(CONFIG_MA600_DONGLE)    += ma600-sir.o
 obj-$(CONFIG_TOIM3232_DONGLE)  += toim3232-sir.o
 
 # The SIR helper module
-sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o
+sir-dev-objs := sir_dev.o sir_dongle.o
index 96bdb73..cd87593 100644 (file)
@@ -1778,7 +1778,7 @@ static int irda_usb_probe(struct usb_interface *intf,
 
        if (self->needspatch) {
                ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0),
-                                      0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500));
+                                      0x02, 0x40, 0, 0, NULL, 0, 500);
                if (ret < 0) {
                        IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret);
                        goto err_out_3;
index f69fb4c..9fa294a 100644 (file)
 #define IRDA_SIR_H
 
 #include <linux/netdevice.h>
+#include <linux/workqueue.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>              // iobuff_t
 
-/* FIXME: unify irda_request with sir_fsm! */
-
-struct irda_request {
-       struct list_head lh_request;
-       unsigned long pending;
-       void (*func)(void *);
-       void *data;
-       struct timer_list timer;
-};
-
 struct sir_fsm {
        struct semaphore        sem;
-       struct irda_request     rq;
+       struct work_struct      work;
        unsigned                state, substate;
        int                     param;
        int                     result;
index ea7c946..3b5854d 100644 (file)
 
 #include "sir-dev.h"
 
+
+static struct workqueue_struct *irda_sir_wq;
+
+/* STATE MACHINE */
+
+/* substate handler of the config-fsm to handle the cases where we want
+ * to wait for transmit completion before changing the port configuration
+ */
+
+static int sirdev_tx_complete_fsm(struct sir_dev *dev)
+{
+       struct sir_fsm *fsm = &dev->fsm;
+       unsigned next_state, delay;
+       unsigned bytes_left;
+
+       do {
+               next_state = fsm->substate;     /* default: stay in current substate */
+               delay = 0;
+
+               switch(fsm->substate) {
+
+               case SIRDEV_STATE_WAIT_XMIT:
+                       if (dev->drv->chars_in_buffer)
+                               bytes_left = dev->drv->chars_in_buffer(dev);
+                       else
+                               bytes_left = 0;
+                       if (!bytes_left) {
+                               next_state = SIRDEV_STATE_WAIT_UNTIL_SENT;
+                               break;
+                       }
+
+                       if (dev->speed > 115200)
+                               delay = (bytes_left*8*10000) / (dev->speed/100);
+                       else if (dev->speed > 0)
+                               delay = (bytes_left*10*10000) / (dev->speed/100);
+                       else
+                               delay = 0;
+                       /* expected delay (usec) until remaining bytes are sent */
+                       if (delay < 100) {
+                               udelay(delay);
+                               delay = 0;
+                               break;
+                       }
+                       /* sleep some longer delay (msec) */
+                       delay = (delay+999) / 1000;
+                       break;
+
+               case SIRDEV_STATE_WAIT_UNTIL_SENT:
+                       /* block until underlaying hardware buffer are empty */
+                       if (dev->drv->wait_until_sent)
+                               dev->drv->wait_until_sent(dev);
+                       next_state = SIRDEV_STATE_TX_DONE;
+                       break;
+
+               case SIRDEV_STATE_TX_DONE:
+                       return 0;
+
+               default:
+                       IRDA_ERROR("%s - undefined state\n", __FUNCTION__);
+                       return -EINVAL;
+               }
+               fsm->substate = next_state;
+       } while (delay == 0);
+       return delay;
+}
+
+/*
+ * Function sirdev_config_fsm
+ *
+ * State machine to handle the configuration of the device (and attached dongle, if any).
+ * This handler is scheduled for execution in kIrDAd context, so we can sleep.
+ * however, kIrDAd is shared by all sir_dev devices so we better don't sleep there too
+ * long. Instead, for longer delays we start a timer to reschedule us later.
+ * On entry, fsm->sem is always locked and the netdev xmit queue stopped.
+ * Both must be unlocked/restarted on completion - but only on final exit.
+ */
+
+static void sirdev_config_fsm(void *data)
+{
+       struct sir_dev *dev = data;
+       struct sir_fsm *fsm = &dev->fsm;
+       int next_state;
+       int ret = -1;
+       unsigned delay;
+
+       IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies);
+
+       do {
+               IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n",
+                       __FUNCTION__, fsm->state, fsm->substate);
+
+               next_state = fsm->state;
+               delay = 0;
+
+               switch(fsm->state) {
+
+               case SIRDEV_STATE_DONGLE_OPEN:
+                       if (dev->dongle_drv != NULL) {
+                               ret = sirdev_put_dongle(dev);
+                               if (ret) {
+                                       fsm->result = -EINVAL;
+                                       next_state = SIRDEV_STATE_ERROR;
+                                       break;
+                               }
+                       }
+
+                       /* Initialize dongle */
+                       ret = sirdev_get_dongle(dev, fsm->param);
+                       if (ret) {
+                               fsm->result = ret;
+                               next_state = SIRDEV_STATE_ERROR;
+                               break;
+                       }
+
+                       /* Dongles are powered through the modem control lines which
+                        * were just set during open. Before resetting, let's wait for
+                        * the power to stabilize. This is what some dongle drivers did
+                        * in open before, while others didn't - should be safe anyway.
+                        */
+
+                       delay = 50;
+                       fsm->substate = SIRDEV_STATE_DONGLE_RESET;
+                       next_state = SIRDEV_STATE_DONGLE_RESET;
+
+                       fsm->param = 9600;
+
+                       break;
+
+               case SIRDEV_STATE_DONGLE_CLOSE:
+                       /* shouldn't we just treat this as success=? */
+                       if (dev->dongle_drv == NULL) {
+                               fsm->result = -EINVAL;
+                               next_state = SIRDEV_STATE_ERROR;
+                               break;
+                       }
+
+                       ret = sirdev_put_dongle(dev);
+                       if (ret) {
+                               fsm->result = ret;
+                               next_state = SIRDEV_STATE_ERROR;
+                               break;
+                       }
+                       next_state = SIRDEV_STATE_DONE;
+                       break;
+
+               case SIRDEV_STATE_SET_DTR_RTS:
+                       ret = sirdev_set_dtr_rts(dev,
+                               (fsm->param&0x02) ? TRUE : FALSE,
+                               (fsm->param&0x01) ? TRUE : FALSE);
+                       next_state = SIRDEV_STATE_DONE;
+                       break;
+
+               case SIRDEV_STATE_SET_SPEED:
+                       fsm->substate = SIRDEV_STATE_WAIT_XMIT;
+                       next_state = SIRDEV_STATE_DONGLE_CHECK;
+                       break;
+
+               case SIRDEV_STATE_DONGLE_CHECK:
+                       ret = sirdev_tx_complete_fsm(dev);
+                       if (ret < 0) {
+                               fsm->result = ret;
+                               next_state = SIRDEV_STATE_ERROR;
+                               break;
+                       }
+                       if ((delay=ret) != 0)
+                               break;
+
+                       if (dev->dongle_drv) {
+                               fsm->substate = SIRDEV_STATE_DONGLE_RESET;
+                               next_state = SIRDEV_STATE_DONGLE_RESET;
+                       }
+                       else {
+                               dev->speed = fsm->param;
+                               next_state = SIRDEV_STATE_PORT_SPEED;
+                       }
+                       break;
+
+               case SIRDEV_STATE_DONGLE_RESET:
+                       if (dev->dongle_drv->reset) {
+                               ret = dev->dongle_drv->reset(dev);
+                               if (ret < 0) {
+                                       fsm->result = ret;
+                                       next_state = SIRDEV_STATE_ERROR;
+                                       break;
+                               }
+                       }
+                       else
+                               ret = 0;
+                       if ((delay=ret) == 0) {
+                               /* set serial port according to dongle default speed */
+                               if (dev->drv->set_speed)
+                                       dev->drv->set_speed(dev, dev->speed);
+                               fsm->substate = SIRDEV_STATE_DONGLE_SPEED;
+                               next_state = SIRDEV_STATE_DONGLE_SPEED;
+                       }
+                       break;
+
+               case SIRDEV_STATE_DONGLE_SPEED:
+                       if (dev->dongle_drv->reset) {
+                               ret = dev->dongle_drv->set_speed(dev, fsm->param);
+                               if (ret < 0) {
+                                       fsm->result = ret;
+                                       next_state = SIRDEV_STATE_ERROR;
+                                       break;
+                               }
+                       }
+                       else
+                               ret = 0;
+                       if ((delay=ret) == 0)
+                               next_state = SIRDEV_STATE_PORT_SPEED;
+                       break;
+
+               case SIRDEV_STATE_PORT_SPEED:
+                       /* Finally we are ready to change the serial port speed */
+                       if (dev->drv->set_speed)
+                               dev->drv->set_speed(dev, dev->speed);
+                       dev->new_speed = 0;
+                       next_state = SIRDEV_STATE_DONE;
+                       break;
+
+               case SIRDEV_STATE_DONE:
+                       /* Signal network layer so it can send more frames */
+                       netif_wake_queue(dev->netdev);
+                       next_state = SIRDEV_STATE_COMPLETE;
+                       break;
+
+               default:
+                       IRDA_ERROR("%s - undefined state\n", __FUNCTION__);
+                       fsm->result = -EINVAL;
+                       /* fall thru */
+
+               case SIRDEV_STATE_ERROR:
+                       IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result);
+
+#if 0  /* don't enable this before we have netdev->tx_timeout to recover */
+                       netif_stop_queue(dev->netdev);
+#else
+                       netif_wake_queue(dev->netdev);
+#endif
+                       /* fall thru */
+
+               case SIRDEV_STATE_COMPLETE:
+                       /* config change finished, so we are not busy any longer */
+                       sirdev_enable_rx(dev);
+                       up(&fsm->sem);
+                       return;
+               }
+               fsm->state = next_state;
+       } while(!delay);
+
+       queue_delayed_work(irda_sir_wq, &fsm->work, msecs_to_jiffies(delay));
+}
+
+/* schedule some device configuration task for execution by kIrDAd
+ * on behalf of the above state machine.
+ * can be called from process or interrupt/tasklet context.
+ */
+
+int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param)
+{
+       struct sir_fsm *fsm = &dev->fsm;
+
+       IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param);
+
+       if (down_trylock(&fsm->sem)) {
+               if (in_interrupt()  ||  in_atomic()  ||  irqs_disabled()) {
+                       IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__);
+                       return -EWOULDBLOCK;
+               } else
+                       down(&fsm->sem);
+       }
+
+       if (fsm->state == SIRDEV_STATE_DEAD) {
+               /* race with sirdev_close should never happen */
+               IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__);
+               up(&fsm->sem);
+               return -ESTALE;         /* or better EPIPE? */
+       }
+
+       netif_stop_queue(dev->netdev);
+       atomic_set(&dev->enable_rx, 0);
+
+       fsm->state = initial_state;
+       fsm->param = param;
+       fsm->result = 0;
+
+       INIT_WORK(&fsm->work, sirdev_config_fsm, dev);
+       queue_work(irda_sir_wq, &fsm->work);
+       return 0;
+}
+
+
 /***************************************************************************/
 
 void sirdev_enable_rx(struct sir_dev *dev)
@@ -619,10 +911,6 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n
        spin_lock_init(&dev->tx_lock);
        init_MUTEX(&dev->fsm.sem);
 
-       INIT_LIST_HEAD(&dev->fsm.rq.lh_request);
-       dev->fsm.rq.pending = 0;
-       init_timer(&dev->fsm.rq.timer);
-
        dev->drv = drv;
        dev->netdev = ndev;
 
@@ -682,3 +970,22 @@ int sirdev_put_instance(struct sir_dev *dev)
 }
 EXPORT_SYMBOL(sirdev_put_instance);
 
+static int __init sir_wq_init(void)
+{
+       irda_sir_wq = create_singlethread_workqueue("irda_sir_wq");
+       if (!irda_sir_wq)
+               return -ENOMEM;
+       return 0;
+}
+
+static void __exit sir_wq_exit(void)
+{
+       destroy_workqueue(irda_sir_wq);
+}
+
+module_init(sir_wq_init);
+module_exit(sir_wq_exit);
+
+MODULE_AUTHOR("Martin Diehl <info@mdiehl.de>");
+MODULE_DESCRIPTION("IrDA SIR core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
deleted file mode 100644 (file)
index e3904d6..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/*********************************************************************
- *
- *     sir_kthread.c:          dedicated thread to process scheduled
- *                             sir device setup requests
- *
- *     Copyright (c) 2002 Martin Diehl
- *
- *     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/module.h>
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-
-#include <net/irda/irda.h>
-
-#include "sir-dev.h"
-
-/**************************************************************************
- *
- * kIrDAd kernel thread and config state machine
- *
- */
-
-struct irda_request_queue {
-       struct list_head request_list;
-       spinlock_t lock;
-       task_t *thread;
-       struct completion exit;
-       wait_queue_head_t kick, done;
-       atomic_t num_pending;
-};
-
-static struct irda_request_queue irda_rq_queue;
-
-static int irda_queue_request(struct irda_request *rq)
-{
-       int ret = 0;
-       unsigned long flags;
-
-       if (!test_and_set_bit(0, &rq->pending)) {
-               spin_lock_irqsave(&irda_rq_queue.lock, flags);
-               list_add_tail(&rq->lh_request, &irda_rq_queue.request_list);
-               wake_up(&irda_rq_queue.kick);
-               atomic_inc(&irda_rq_queue.num_pending);
-               spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
-               ret = 1;
-       }
-       return ret;
-}
-
-static void irda_request_timer(unsigned long data)
-{
-       struct irda_request *rq = (struct irda_request *)data;
-       unsigned long flags;
-       
-       spin_lock_irqsave(&irda_rq_queue.lock, flags);
-       list_add_tail(&rq->lh_request, &irda_rq_queue.request_list);
-       wake_up(&irda_rq_queue.kick);
-       spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
-}
-
-static int irda_queue_delayed_request(struct irda_request *rq, unsigned long delay)
-{
-       int ret = 0;
-       struct timer_list *timer = &rq->timer;
-
-       if (!test_and_set_bit(0, &rq->pending)) {
-               timer->expires = jiffies + delay;
-               timer->function = irda_request_timer;
-               timer->data = (unsigned long)rq;
-               atomic_inc(&irda_rq_queue.num_pending);
-               add_timer(timer);
-               ret = 1;
-       }
-       return ret;
-}
-
-static void run_irda_queue(void)
-{
-       unsigned long flags;
-       struct list_head *entry, *tmp;
-       struct irda_request *rq;
-
-       spin_lock_irqsave(&irda_rq_queue.lock, flags);
-       list_for_each_safe(entry, tmp, &irda_rq_queue.request_list) {
-               rq = list_entry(entry, struct irda_request, lh_request);
-               list_del_init(entry);
-               spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
-
-               clear_bit(0, &rq->pending);
-               rq->func(rq->data);
-
-               if (atomic_dec_and_test(&irda_rq_queue.num_pending))
-                       wake_up(&irda_rq_queue.done);
-
-               spin_lock_irqsave(&irda_rq_queue.lock, flags);
-       }
-       spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
-}              
-
-static int irda_thread(void *startup)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       daemonize("kIrDAd");
-
-       irda_rq_queue.thread = current;
-
-       complete((struct completion *)startup);
-
-       while (irda_rq_queue.thread != NULL) {
-
-               /* We use TASK_INTERRUPTIBLE, rather than
-                * TASK_UNINTERRUPTIBLE.  Andrew Morton made this
-                * change ; he told me that it is safe, because "signal
-                * blocking is now handled in daemonize()", he added
-                * that the problem is that "uninterruptible sleep
-                * contributes to load average", making user worry.
-                * Jean II */
-               set_task_state(current, TASK_INTERRUPTIBLE);
-               add_wait_queue(&irda_rq_queue.kick, &wait);
-               if (list_empty(&irda_rq_queue.request_list))
-                       schedule();
-               else
-                       __set_task_state(current, TASK_RUNNING);
-               remove_wait_queue(&irda_rq_queue.kick, &wait);
-
-               /* make swsusp happy with our thread */
-               try_to_freeze();
-
-               run_irda_queue();
-       }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,35)
-       reparent_to_init();
-#endif
-       complete_and_exit(&irda_rq_queue.exit, 0);
-       /* never reached */
-       return 0;
-}
-
-
-static void flush_irda_queue(void)
-{
-       if (atomic_read(&irda_rq_queue.num_pending)) {
-
-               DECLARE_WAITQUEUE(wait, current);
-
-               if (!list_empty(&irda_rq_queue.request_list))
-                       run_irda_queue();
-
-               set_task_state(current, TASK_UNINTERRUPTIBLE);
-               add_wait_queue(&irda_rq_queue.done, &wait);
-               if (atomic_read(&irda_rq_queue.num_pending))
-                       schedule();
-               else
-                       __set_task_state(current, TASK_RUNNING);
-               remove_wait_queue(&irda_rq_queue.done, &wait);
-       }
-}
-
-/* substate handler of the config-fsm to handle the cases where we want
- * to wait for transmit completion before changing the port configuration
- */
-
-static int irda_tx_complete_fsm(struct sir_dev *dev)
-{
-       struct sir_fsm *fsm = &dev->fsm;
-       unsigned next_state, delay;
-       unsigned bytes_left;
-
-       do {
-               next_state = fsm->substate;     /* default: stay in current substate */
-               delay = 0;
-
-               switch(fsm->substate) {
-
-               case SIRDEV_STATE_WAIT_XMIT:
-                       if (dev->drv->chars_in_buffer)
-                               bytes_left = dev->drv->chars_in_buffer(dev);
-                       else
-                               bytes_left = 0;
-                       if (!bytes_left) {
-                               next_state = SIRDEV_STATE_WAIT_UNTIL_SENT;
-                               break;
-                       }
-
-                       if (dev->speed > 115200)
-                               delay = (bytes_left*8*10000) / (dev->speed/100);
-                       else if (dev->speed > 0)
-                               delay = (bytes_left*10*10000) / (dev->speed/100);
-                       else
-                               delay = 0;
-                       /* expected delay (usec) until remaining bytes are sent */
-                       if (delay < 100) {
-                               udelay(delay);
-                               delay = 0;
-                               break;
-                       }
-                       /* sleep some longer delay (msec) */
-                       delay = (delay+999) / 1000;
-                       break;
-
-               case SIRDEV_STATE_WAIT_UNTIL_SENT:
-                       /* block until underlaying hardware buffer are empty */
-                       if (dev->drv->wait_until_sent)
-                               dev->drv->wait_until_sent(dev);
-                       next_state = SIRDEV_STATE_TX_DONE;
-                       break;
-
-               case SIRDEV_STATE_TX_DONE:
-                       return 0;
-
-               default:
-                       IRDA_ERROR("%s - undefined state\n", __FUNCTION__);
-                       return -EINVAL;
-               }
-               fsm->substate = next_state;
-       } while (delay == 0);
-       return delay;
-}
-
-/*
- * Function irda_config_fsm
- *
- * State machine to handle the configuration of the device (and attached dongle, if any).
- * This handler is scheduled for execution in kIrDAd context, so we can sleep.
- * however, kIrDAd is shared by all sir_dev devices so we better don't sleep there too
- * long. Instead, for longer delays we start a timer to reschedule us later.
- * On entry, fsm->sem is always locked and the netdev xmit queue stopped.
- * Both must be unlocked/restarted on completion - but only on final exit.
- */
-
-static void irda_config_fsm(void *data)
-{
-       struct sir_dev *dev = data;
-       struct sir_fsm *fsm = &dev->fsm;
-       int next_state;
-       int ret = -1;
-       unsigned delay;
-
-       IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); 
-
-       do {
-               IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n",
-                       __FUNCTION__, fsm->state, fsm->substate);
-
-               next_state = fsm->state;
-               delay = 0;
-
-               switch(fsm->state) {
-
-               case SIRDEV_STATE_DONGLE_OPEN:
-                       if (dev->dongle_drv != NULL) {
-                               ret = sirdev_put_dongle(dev);
-                               if (ret) {
-                                       fsm->result = -EINVAL;
-                                       next_state = SIRDEV_STATE_ERROR;
-                                       break;
-                               }
-                       }
-
-                       /* Initialize dongle */
-                       ret = sirdev_get_dongle(dev, fsm->param);
-                       if (ret) {
-                               fsm->result = ret;
-                               next_state = SIRDEV_STATE_ERROR;
-                               break;
-                       }
-
-                       /* Dongles are powered through the modem control lines which
-                        * were just set during open. Before resetting, let's wait for
-                        * the power to stabilize. This is what some dongle drivers did
-                        * in open before, while others didn't - should be safe anyway.
-                        */
-
-                       delay = 50;
-                       fsm->substate = SIRDEV_STATE_DONGLE_RESET;
-                       next_state = SIRDEV_STATE_DONGLE_RESET;
-
-                       fsm->param = 9600;
-
-                       break;
-
-               case SIRDEV_STATE_DONGLE_CLOSE:
-                       /* shouldn't we just treat this as success=? */
-                       if (dev->dongle_drv == NULL) {
-                               fsm->result = -EINVAL;
-                               next_state = SIRDEV_STATE_ERROR;
-                               break;
-                       }
-
-                       ret = sirdev_put_dongle(dev);
-                       if (ret) {
-                               fsm->result = ret;
-                               next_state = SIRDEV_STATE_ERROR;
-                               break;
-                       }
-                       next_state = SIRDEV_STATE_DONE;
-                       break;
-
-               case SIRDEV_STATE_SET_DTR_RTS:
-                       ret = sirdev_set_dtr_rts(dev,
-                               (fsm->param&0x02) ? TRUE : FALSE,
-                               (fsm->param&0x01) ? TRUE : FALSE);
-                       next_state = SIRDEV_STATE_DONE;
-                       break;
-
-               case SIRDEV_STATE_SET_SPEED:
-                       fsm->substate = SIRDEV_STATE_WAIT_XMIT;
-                       next_state = SIRDEV_STATE_DONGLE_CHECK;
-                       break;
-
-               case SIRDEV_STATE_DONGLE_CHECK:
-                       ret = irda_tx_complete_fsm(dev);
-                       if (ret < 0) {
-                               fsm->result = ret;
-                               next_state = SIRDEV_STATE_ERROR;
-                               break;
-                       }
-                       if ((delay=ret) != 0)
-                               break;
-
-                       if (dev->dongle_drv) {
-                               fsm->substate = SIRDEV_STATE_DONGLE_RESET;
-                               next_state = SIRDEV_STATE_DONGLE_RESET;
-                       }
-                       else {
-                               dev->speed = fsm->param;
-                               next_state = SIRDEV_STATE_PORT_SPEED;
-                       }
-                       break;
-
-               case SIRDEV_STATE_DONGLE_RESET:
-                       if (dev->dongle_drv->reset) {
-                               ret = dev->dongle_drv->reset(dev);      
-                               if (ret < 0) {
-                                       fsm->result = ret;
-                                       next_state = SIRDEV_STATE_ERROR;
-                                       break;
-                               }
-                       }
-                       else
-                               ret = 0;
-                       if ((delay=ret) == 0) {
-                               /* set serial port according to dongle default speed */
-                               if (dev->drv->set_speed)
-                                       dev->drv->set_speed(dev, dev->speed);
-                               fsm->substate = SIRDEV_STATE_DONGLE_SPEED;
-                               next_state = SIRDEV_STATE_DONGLE_SPEED;
-                       }
-                       break;
-
-               case SIRDEV_STATE_DONGLE_SPEED:                         
-                       if (dev->dongle_drv->reset) {
-                               ret = dev->dongle_drv->set_speed(dev, fsm->param);
-                               if (ret < 0) {
-                                       fsm->result = ret;
-                                       next_state = SIRDEV_STATE_ERROR;
-                                       break;
-                               }
-                       }
-                       else
-                               ret = 0;
-                       if ((delay=ret) == 0)
-                               next_state = SIRDEV_STATE_PORT_SPEED;
-                       break;
-
-               case SIRDEV_STATE_PORT_SPEED:
-                       /* Finally we are ready to change the serial port speed */
-                       if (dev->drv->set_speed)
-                               dev->drv->set_speed(dev, dev->speed);
-                       dev->new_speed = 0;
-                       next_state = SIRDEV_STATE_DONE;
-                       break;
-
-               case SIRDEV_STATE_DONE:
-                       /* Signal network layer so it can send more frames */
-                       netif_wake_queue(dev->netdev);
-                       next_state = SIRDEV_STATE_COMPLETE;
-                       break;
-
-               default:
-                       IRDA_ERROR("%s - undefined state\n", __FUNCTION__);
-                       fsm->result = -EINVAL;
-                       /* fall thru */
-
-               case SIRDEV_STATE_ERROR:
-                       IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result);
-
-#if 0  /* don't enable this before we have netdev->tx_timeout to recover */
-                       netif_stop_queue(dev->netdev);
-#else
-                       netif_wake_queue(dev->netdev);
-#endif
-                       /* fall thru */
-
-               case SIRDEV_STATE_COMPLETE:
-                       /* config change finished, so we are not busy any longer */
-                       sirdev_enable_rx(dev);
-                       up(&fsm->sem);
-                       return;
-               }
-               fsm->state = next_state;
-       } while(!delay);
-
-       irda_queue_delayed_request(&fsm->rq, msecs_to_jiffies(delay));
-}
-
-/* schedule some device configuration task for execution by kIrDAd
- * on behalf of the above state machine.
- * can be called from process or interrupt/tasklet context.
- */
-
-int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param)
-{
-       struct sir_fsm *fsm = &dev->fsm;
-       int xmit_was_down;
-
-       IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param);
-
-       if (down_trylock(&fsm->sem)) {
-               if (in_interrupt()  ||  in_atomic()  ||  irqs_disabled()) {
-                       IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__);
-                       return -EWOULDBLOCK;
-               } else
-                       down(&fsm->sem);
-       }
-
-       if (fsm->state == SIRDEV_STATE_DEAD) {
-               /* race with sirdev_close should never happen */
-               IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__);
-               up(&fsm->sem);
-               return -ESTALE;         /* or better EPIPE? */
-       }
-
-       xmit_was_down = netif_queue_stopped(dev->netdev);
-       netif_stop_queue(dev->netdev);
-       atomic_set(&dev->enable_rx, 0);
-
-       fsm->state = initial_state;
-       fsm->param = param;
-       fsm->result = 0;
-
-       INIT_LIST_HEAD(&fsm->rq.lh_request);
-       fsm->rq.pending = 0;
-       fsm->rq.func = irda_config_fsm;
-       fsm->rq.data = dev;
-
-       if (!irda_queue_request(&fsm->rq)) {    /* returns 0 on error! */
-               atomic_set(&dev->enable_rx, 1);
-               if (!xmit_was_down)
-                       netif_wake_queue(dev->netdev);          
-               up(&fsm->sem);
-               return -EAGAIN;
-       }
-       return 0;
-}
-
-static int __init irda_thread_create(void)
-{
-       struct completion startup;
-       int pid;
-
-       spin_lock_init(&irda_rq_queue.lock);
-       irda_rq_queue.thread = NULL;
-       INIT_LIST_HEAD(&irda_rq_queue.request_list);
-       init_waitqueue_head(&irda_rq_queue.kick);
-       init_waitqueue_head(&irda_rq_queue.done);
-       atomic_set(&irda_rq_queue.num_pending, 0);
-
-       init_completion(&startup);
-       pid = kernel_thread(irda_thread, &startup, CLONE_FS|CLONE_FILES);
-       if (pid <= 0)
-               return -EAGAIN;
-       else
-               wait_for_completion(&startup);
-
-       return 0;
-}
-
-static void __exit irda_thread_join(void)
-{
-       if (irda_rq_queue.thread) {
-               flush_irda_queue();
-               init_completion(&irda_rq_queue.exit);
-               irda_rq_queue.thread = NULL;
-               wake_up(&irda_rq_queue.kick);           
-               wait_for_completion(&irda_rq_queue.exit);
-       }
-}
-
-module_init(irda_thread_create);
-module_exit(irda_thread_join);
-
-MODULE_AUTHOR("Martin Diehl <info@mdiehl.de>");
-MODULE_DESCRIPTION("IrDA SIR core");
-MODULE_LICENSE("GPL");
-
index 58f76ce..a467404 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
 #include <linux/dma-mapping.h>
+#include <linux/pnp.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
@@ -358,6 +359,16 @@ static inline void register_bank(int iobase, int bank)
                iobase + IRCC_MASTER);
 }
 
+#ifdef CONFIG_PNP
+/* PNP hotplug support */
+static const struct pnp_device_id smsc_ircc_pnp_table[] = {
+       { .id = "SMCf010", .driver_data = 0 },
+       /* and presumably others */
+       { }
+};
+MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
+#endif
+
 
 /*******************************************************************************
  *
@@ -2072,7 +2083,8 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self)
 
 /* PROBING
  *
- *
+ * REVISIT we can be told about the device by PNP, and should use that info
+ * instead of probing hardware and creating a platform_device ...
  */
 
 static int __init smsc_ircc_look_for_chips(void)
index 93c494b..b327652 100644 (file)
@@ -139,8 +139,9 @@ bad_clone_list[] __initdata = {
 
 #if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
-#elif defined(CONFIG_PLAT_OAKS32R)
-#  define DCR_VAL 0x48
+#elif defined(CONFIG_PLAT_OAKS32R)  || \
+   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#  define DCR_VAL 0x48         /* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
 #endif
@@ -396,10 +397,22 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                /* We must set the 8390 for word mode. */
                outb_p(DCR_VAL, ioaddr + EN0_DCFG);
                start_page = NESM_START_PG;
-               stop_page = NESM_STOP_PG;
+
+               /*
+                * Realtek RTL8019AS datasheet says that the PSTOP register
+                * shouldn't exceed 0x60 in 8-bit mode.
+                * This chip can be identified by reading the signature from
+                * the  remote byte count registers (otherwise write-only)...
+                */
+               if ((DCR_VAL & 0x01) == 0 &&            /* 8-bit mode */
+                   inb(ioaddr + EN0_RCNTLO) == 0x50 &&
+                   inb(ioaddr + EN0_RCNTHI) == 0x70)
+                       stop_page = 0x60;
+               else
+                       stop_page = NESM_STOP_PG;
        } else {
                start_page = NE1SM_START_PG;
-               stop_page = NE1SM_STOP_PG;
+               stop_page  = NE1SM_STOP_PG;
        }
 
 #if  defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R)
@@ -509,15 +522,9 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        ei_status.name = name;
        ei_status.tx_start_page = start_page;
        ei_status.stop_page = stop_page;
-#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
-       wordlength = 1;
-#endif
 
-#ifdef CONFIG_PLAT_OAKS32R
-       ei_status.word16 = 0;
-#else
-       ei_status.word16 = (wordlength == 2);
-#endif
+       /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */
+       ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01));
 
        ei_status.rx_start_page = start_page + TX_PAGES;
 #ifdef PACKETBUF_MEMSIZE
index 459443b..1b236bd 100644 (file)
@@ -60,8 +60,10 @@ int mdiobus_register(struct mii_bus *bus)
        for (i = 0; i < PHY_MAX_ADDR; i++) {
                struct phy_device *phydev;
 
-               if (bus->phy_mask & (1 << i))
+               if (bus->phy_mask & (1 << i)) {
+                       bus->phy_map[i] = NULL;
                        continue;
+               }
 
                phydev = get_phy_device(bus, i);
 
index b82191d..f5a3bf4 100644 (file)
@@ -127,6 +127,7 @@ static const struct mii_chip_info {
 } mii_chip_table[] = {
        { "SiS 900 Internal MII PHY",           0x001d, 0x8000, LAN },
        { "SiS 7014 Physical Layer Solution",   0x0016, 0xf830, LAN },
+       { "SiS 900 on Foxconn 661 7MI",         0x0143, 0xBC70, LAN },
        { "Altimata AC101LF PHY",               0x0022, 0x5520, LAN },
        { "ADM 7001 LAN PHY",                   0x002e, 0xcc60, LAN },
        { "AMD 79C901 10BASE-T PHY",            0x0000, 0x6B70, LAN },
index 227df98..ffd267f 100644 (file)
@@ -51,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.2"
+#define DRV_VERSION            "1.3"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -79,6 +79,8 @@
 #define NAPI_WEIGHT            64
 #define PHY_RETRIES            1000
 
+#define RING_NEXT(x,s) (((x)+1) & ((s)-1))
+
 static const u32 default_msg =
     NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
     | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
@@ -96,6 +98,10 @@ static int disable_msi = 0;
 module_param(disable_msi, int, 0);
 MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
 
+static int idle_timeout = 100;
+module_param(idle_timeout, int, 0);
+MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)");
+
 static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
@@ -122,6 +128,7 @@ MODULE_DEVICE_TABLE(pci, sky2_id_table);
 /* Avoid conditionals by using array */
 static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
 static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
+static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
 
 /* This driver supports yukon2 chipset only */
 static const char *yukon2_name[] = {
@@ -298,7 +305,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
        struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
        u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
 
-       if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) {
+       if (sky2->autoneg == AUTONEG_ENABLE &&
+           (hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
                u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
                ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -326,7 +334,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                        ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
 
                        if (sky2->autoneg == AUTONEG_ENABLE &&
-                           hw->chip_id == CHIP_ID_YUKON_XL) {
+                           (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
                                ctrl &= ~PHY_M_PC_DSC_MSK;
                                ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
                        }
@@ -442,10 +450,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
 
                /* set LED Function Control register */
-               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) |     /* LINK/ACT */
-                                                          PHY_M_LEDC_INIT_CTRL(7) |    /* 10 Mbps */
-                                                          PHY_M_LEDC_STA1_CTRL(7) |    /* 100 Mbps */
-                                                          PHY_M_LEDC_STA0_CTRL(7)));   /* 1000 Mbps */
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                            (PHY_M_LEDC_LOS_CTRL(1) |  /* LINK/ACT */
+                             PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */
+                             PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
+                             PHY_M_LEDC_STA0_CTRL(7)));        /* 1000 Mbps */
 
                /* set Polarity Control register */
                gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
@@ -459,6 +468,25 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                /* restore page register */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
                break;
+       case CHIP_ID_YUKON_EC_U:
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+               /* select page 3 to access LED control register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+
+               /* set LED Function Control register */
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                            (PHY_M_LEDC_LOS_CTRL(1) |  /* LINK/ACT */
+                             PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */
+                             PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
+                             PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */
+
+               /* set Blink Rate in LED Timer Control Register */
+               gm_phy_write(hw, port, PHY_MARV_INT_MASK,
+                            ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
+               /* restore page register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+               break;
 
        default:
                /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
@@ -467,19 +495,21 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
        }
 
-       if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) {
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
                /* apply fixes in PHY AFE */
-               gm_phy_write(hw, port, 22, 255);
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
+
                /* increase differential signal amplitude in 10BASE-T */
-               gm_phy_write(hw, port, 24, 0xaa99);
-               gm_phy_write(hw, port, 23, 0x2011);
+               gm_phy_write(hw, port, 0x18, 0xaa99);
+               gm_phy_write(hw, port, 0x17, 0x2011);
 
                /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
-               gm_phy_write(hw, port, 24, 0xa204);
-               gm_phy_write(hw, port, 23, 0x2002);
+               gm_phy_write(hw, port, 0x18, 0xa204);
+               gm_phy_write(hw, port, 0x17, 0x2002);
 
                /* set page register to 0 */
-               gm_phy_write(hw, port, 22, 0);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
        } else {
                gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
 
@@ -553,6 +583,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
 
                if (sky2->duplex == DUPLEX_FULL)
                        reg |= GM_GPCR_DUP_FULL;
+
+               /* turn off pause in 10/100mbps half duplex */
+               else if (sky2->speed != SPEED_1000 &&
+                        hw->chip_id != CHIP_ID_YUKON_EC_U)
+                       sky2->tx_pause = sky2->rx_pause = 0;
        } else
                reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
 
@@ -719,7 +754,7 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
 {
        struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
 
-       sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE;
+       sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
        return le;
 }
 
@@ -735,7 +770,7 @@ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
 static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
 {
        struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
-       sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE;
+       sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
        return le;
 }
 
@@ -1050,7 +1085,7 @@ static int sky2_up(struct net_device *dev)
 
        /* Enable interrupts from phy/mac for port */
        imask = sky2_read32(hw, B0_IMSK);
-       imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
+       imask |= portirq_msk[port];
        sky2_write32(hw, B0_IMSK, imask);
 
        return 0;
@@ -1078,7 +1113,7 @@ err_out:
 /* Modular subtraction in ring */
 static inline int tx_dist(unsigned tail, unsigned head)
 {
-       return (head - tail) % TX_RING_SIZE;
+       return (head - tail) & (TX_RING_SIZE - 1);
 }
 
 /* Number of list elements available for next tx */
@@ -1255,7 +1290,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                le->opcode = OP_BUFFER | HW_OWNER;
 
                fre = sky2->tx_ring
-                   + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
+                   + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
                pci_unmap_addr_set(fre, mapaddr, mapping);
        }
 
@@ -1315,7 +1350,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        struct tx_ring_info *fre;
-                       fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE;
+                       fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
                        pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
                                       skb_shinfo(skb)->frags[i].size,
                                       PCI_DMA_TODEVICE);
@@ -1401,7 +1436,7 @@ static int sky2_down(struct net_device *dev)
 
        /* Disable port IRQ */
        imask = sky2_read32(hw, B0_IMSK);
-       imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
+       imask &= ~portirq_msk[port];
        sky2_write32(hw, B0_IMSK, imask);
 
        /* turn off LED's */
@@ -1498,17 +1533,26 @@ static void sky2_link_up(struct sky2_port *sky2)
        sky2_write8(hw, SK_REG(port, LNK_LED_REG),
                    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
 
-       if (hw->chip_id == CHIP_ID_YUKON_XL) {
+       if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) {
                u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               u16 led = PHY_M_LEDC_LOS_CTRL(1);       /* link active */
+
+               switch(sky2->speed) {
+               case SPEED_10:
+                       led |= PHY_M_LEDC_INIT_CTRL(7);
+                       break;
+
+               case SPEED_100:
+                       led |= PHY_M_LEDC_STA1_CTRL(7);
+                       break;
+
+               case SPEED_1000:
+                       led |= PHY_M_LEDC_STA0_CTRL(7);
+                       break;
+               }
 
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) |      /* LINK/ACT */
-                            PHY_M_LEDC_INIT_CTRL(sky2->speed ==
-                                                 SPEED_10 ? 7 : 0) |
-                            PHY_M_LEDC_STA1_CTRL(sky2->speed ==
-                                                 SPEED_100 ? 7 : 0) |
-                            PHY_M_LEDC_STA0_CTRL(sky2->speed ==
-                                                 SPEED_1000 ? 7 : 0));
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led);
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
        }
 
@@ -1583,7 +1627,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
        sky2->speed = sky2_phy_speed(hw, aux);
 
        /* Pause bits are offset (9..8) */
-       if (hw->chip_id == CHIP_ID_YUKON_XL)
+       if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
                aux >>= 6;
 
        sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
@@ -1859,35 +1903,28 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
 static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 {
        int work_done = 0;
+       u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
 
        rmb();
 
-       for(;;) {
+       while (hw->st_idx != hwidx) {
                struct sky2_status_le *le  = hw->st_le + hw->st_idx;
                struct net_device *dev;
                struct sky2_port *sky2;
                struct sk_buff *skb;
                u32 status;
                u16 length;
-               u8  link, opcode;
 
-               opcode = le->opcode;
-               if (!opcode)
-                       break;
-               opcode &= ~HW_OWNER;
-
-               hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
-               le->opcode = 0;
+               hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
 
-               link = le->link;
-               BUG_ON(link >= 2);
-               dev = hw->dev[link];
+               BUG_ON(le->link >= 2);
+               dev = hw->dev[le->link];
 
                sky2 = netdev_priv(dev);
                length = le->length;
                status = le->status;
 
-               switch (opcode) {
+               switch (le->opcode & ~HW_OWNER) {
                case OP_RXSTAT:
                        skb = sky2_receive(sky2, length, status);
                        if (!skb)
@@ -1927,7 +1964,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 
                case OP_TXINDEXLE:
                        /* TX index reports status for both ports */
-                       sky2_tx_done(hw->dev[0], status & 0xffff);
+                       BUILD_BUG_ON(TX_RING_SIZE > 0x1000);
+                       sky2_tx_done(hw->dev[0], status & 0xfff);
                        if (hw->dev[1])
                                sky2_tx_done(hw->dev[1],
                                     ((status >> 24) & 0xff)
@@ -1937,8 +1975,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
                default:
                        if (net_ratelimit())
                                printk(KERN_WARNING PFX
-                                      "unknown status opcode 0x%x\n", opcode);
-                       break;
+                                      "unknown status opcode 0x%x\n", le->opcode);
+                       goto exit_loop;
                }
        }
 
@@ -2089,12 +2127,13 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
  */
 static void sky2_idle(unsigned long arg)
 {
-       struct net_device *dev = (struct net_device *) arg;
+       struct sky2_hw *hw = (struct sky2_hw *) arg;
+       struct net_device *dev = hw->dev[0];
 
-       local_irq_disable();
        if (__netif_rx_schedule_prep(dev))
                __netif_rx_schedule(dev);
-       local_irq_enable();
+
+       mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout));
 }
 
 
@@ -2105,65 +2144,46 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        int work_done = 0;
        u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
 
- restart_poll:
-       if (unlikely(status & ~Y2_IS_STAT_BMU)) {
-               if (status & Y2_IS_HW_ERR)
-                       sky2_hw_intr(hw);
-
-               if (status & Y2_IS_IRQ_PHY1)
-                       sky2_phy_intr(hw, 0);
-
-               if (status & Y2_IS_IRQ_PHY2)
-                       sky2_phy_intr(hw, 1);
+       if (status & Y2_IS_HW_ERR)
+               sky2_hw_intr(hw);
 
-               if (status & Y2_IS_IRQ_MAC1)
-                       sky2_mac_intr(hw, 0);
+       if (status & Y2_IS_IRQ_PHY1)
+               sky2_phy_intr(hw, 0);
 
-               if (status & Y2_IS_IRQ_MAC2)
-                       sky2_mac_intr(hw, 1);
+       if (status & Y2_IS_IRQ_PHY2)
+               sky2_phy_intr(hw, 1);
 
-               if (status & Y2_IS_CHK_RX1)
-                       sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
+       if (status & Y2_IS_IRQ_MAC1)
+               sky2_mac_intr(hw, 0);
 
-               if (status & Y2_IS_CHK_RX2)
-                       sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
+       if (status & Y2_IS_IRQ_MAC2)
+               sky2_mac_intr(hw, 1);
 
-               if (status & Y2_IS_CHK_TXA1)
-                       sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
+       if (status & Y2_IS_CHK_RX1)
+               sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
 
-               if (status & Y2_IS_CHK_TXA2)
-                       sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
-       }
+       if (status & Y2_IS_CHK_RX2)
+               sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
 
-       if (status & Y2_IS_STAT_BMU) {
-               work_done += sky2_status_intr(hw, work_limit - work_done);
-               *budget -= work_done;
-               dev0->quota -= work_done;
+       if (status & Y2_IS_CHK_TXA1)
+               sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
 
-               if (work_done >= work_limit)
-                       return 1;
+       if (status & Y2_IS_CHK_TXA2)
+               sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
 
+       if (status & Y2_IS_STAT_BMU)
                sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-       }
-
-       mod_timer(&hw->idle_timer, jiffies + HZ);
 
-       local_irq_disable();
-       __netif_rx_complete(dev0);
+       work_done = sky2_status_intr(hw, work_limit);
+       *budget -= work_done;
+       dev0->quota -= work_done;
 
-       status = sky2_read32(hw, B0_Y2_SP_LISR);
+       if (work_done >= work_limit)
+               return 1;
 
-       if (unlikely(status)) {
-               /* More work pending, try and keep going */
-               if (__netif_rx_schedule_prep(dev0)) {
-                       __netif_rx_reschedule(dev0, work_done);
-                       status = sky2_read32(hw, B0_Y2_SP_EISR);
-                       local_irq_enable();
-                       goto restart_poll;
-               }
-       }
+       netif_rx_complete(dev0);
 
-       local_irq_enable();
+       status = sky2_read32(hw, B0_Y2_SP_LISR);
        return 0;
 }
 
@@ -2244,13 +2264,6 @@ static int __devinit sky2_reset(struct sky2_hw *hw)
                return -EOPNOTSUPP;
        }
 
-       /* This chip is new and not tested yet */
-       if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-               pr_info(PFX "%s: is a version of Yukon 2 chipset that has not been tested yet.\n",
-                       pci_name(hw->pdev));
-               pr_info("Please report success/failure to maintainer <shemminger@osdl.org>\n");
-       }
-
        /* disable ASF */
        if (hw->chip_id <= CHIP_ID_YUKON_EC) {
                sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -3302,7 +3315,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 
        sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
 
-       setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev);
+       setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
+       if (idle_timeout > 0)
+               mod_timer(&hw->idle_timer,
+                         jiffies + msecs_to_jiffies(idle_timeout));
 
        pci_set_drvdata(pdev, hw);
 
@@ -3342,6 +3358,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
        del_timer_sync(&hw->idle_timer);
 
        sky2_write32(hw, B0_IMSK, 0);
+       synchronize_irq(hw->pdev->irq);
+
        dev0 = hw->dev[0];
        dev1 = hw->dev[1];
        if (dev1)
index b026f56..8012994 100644 (file)
@@ -378,6 +378,9 @@ enum {
        CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
        CHIP_REV_YU_EC_A2    = 1,  /* Chip Rev. for Yukon-EC A2 */
        CHIP_REV_YU_EC_A3    = 2,  /* Chip Rev. for Yukon-EC A3 */
+
+       CHIP_REV_YU_EC_U_A0  = 0,
+       CHIP_REV_YU_EC_U_A1  = 1,
 };
 
 /*     B2_Y2_CLK_GATE   8 bit  Clock Gating (Yukon-2 only) */
index 43f5e86..394339d 100644 (file)
@@ -1652,6 +1652,8 @@ spider_net_enable_card(struct spider_net_card *card)
                { SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE },
 
                { SPIDER_NET_GMRWOLCTRL, 0 },
+               { SPIDER_NET_GTESTMD, 0x10000000 },
+               { SPIDER_NET_GTTQMSK, 0x00400040 },
                { SPIDER_NET_GTESTMD, 0 },
 
                { SPIDER_NET_GMACINTEN, 0 },
@@ -1792,15 +1794,7 @@ spider_net_setup_phy(struct spider_net_card *card)
        if (phy->def->ops->setup_forced)
                phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL);
 
-       /* the following two writes could be moved to sungem_phy.c */
-       /* enable fiber mode */
-       spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x9020);
-       /* LEDs active in both modes, autosense prio = fiber */
-       spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x945f);
-
-       /* switch off fibre autoneg */
-       spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0xfc01);
-       spider_net_write_phy(card->netdev, 1, 0x0b, 0x0004);
+       phy->def->ops->enable_fiber(phy);
 
        phy->def->ops->read_link(phy);
        pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name,
index 5922b52..3b8d951 100644 (file)
@@ -120,6 +120,8 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_GMRUAFILnR          0x00000500
 #define SPIDER_NET_GMRUA0FIL15R                0x00000578
 
+#define SPIDER_NET_GTTQMSK             0x00000934
+
 /* RX DMA controller registers, all 0x00000a.. are for DMA controller A,
  * 0x00000b.. for DMA controller B, etc. */
 #define SPIDER_NET_GDADCHA             0x00000a00
index 046371e..b2ddd5e 100644 (file)
@@ -329,6 +329,30 @@ static int bcm5421_init(struct mii_phy* phy)
        return 0;
 }
 
+static int bcm5421_enable_fiber(struct mii_phy* phy)
+{
+       /* enable fiber mode */
+       phy_write(phy, MII_NCONFIG, 0x9020);
+       /* LEDs active in both modes, autosense prio = fiber */
+       phy_write(phy, MII_NCONFIG, 0x945f);
+
+       /* switch off fibre autoneg */
+       phy_write(phy, MII_NCONFIG, 0xfc01);
+       phy_write(phy, 0x0b, 0x0004);
+
+       return 0;
+}
+
+static int bcm5461_enable_fiber(struct mii_phy* phy)
+{
+        phy_write(phy, MII_NCONFIG, 0xfc0c);
+        phy_write(phy, MII_BMCR, 0x4140);
+        phy_write(phy, MII_NCONFIG, 0xfc0b);
+       phy_write(phy, MII_BMCR, 0x0140);
+
+       return 0;
+}
+
 static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise)
 {
        u16 ctl, adv;
@@ -762,6 +786,7 @@ static struct mii_phy_ops bcm5421_phy_ops = {
        .setup_forced   = bcm54xx_setup_forced,
        .poll_link      = genmii_poll_link,
        .read_link      = bcm54xx_read_link,
+       .enable_fiber   = bcm5421_enable_fiber,
 };
 
 static struct mii_phy_def bcm5421_phy_def = {
@@ -792,6 +817,25 @@ static struct mii_phy_def bcm5421k2_phy_def = {
        .ops            = &bcm5421k2_phy_ops
 };
 
+static struct mii_phy_ops bcm5461_phy_ops = {
+       .init           = bcm5421_init,
+       .suspend        = generic_suspend,
+       .setup_aneg     = bcm54xx_setup_aneg,
+       .setup_forced   = bcm54xx_setup_forced,
+       .poll_link      = genmii_poll_link,
+       .read_link      = bcm54xx_read_link,
+       .enable_fiber   = bcm5461_enable_fiber,
+};
+
+static struct mii_phy_def bcm5461_phy_def = {
+       .phy_id         = 0x002060c0,
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "BCM5461",
+       .features       = MII_GBIT_FEATURES,
+       .magic_aneg     = 1,
+       .ops            = &bcm5461_phy_ops
+};
+
 /* Broadcom BCM 5462 built-in Vesta */
 static struct mii_phy_ops bcm5462V_phy_ops = {
        .init           = bcm5421_init,
@@ -857,6 +901,7 @@ static struct mii_phy_def* mii_phy_table[] = {
        &bcm5411_phy_def,
        &bcm5421_phy_def,
        &bcm5421k2_phy_def,
+       &bcm5461_phy_def,
        &bcm5462V_phy_def,
        &marvell_phy_def,
        &genmii_phy_def,
index 4305444..69e1251 100644 (file)
@@ -12,6 +12,7 @@ struct mii_phy_ops
        int             (*setup_forced)(struct mii_phy *phy, int speed, int fd);
        int             (*poll_link)(struct mii_phy *phy);
        int             (*read_link)(struct mii_phy *phy);
+       int             (*enable_fiber)(struct mii_phy *phy);
 };
 
 /* Structure used to statically define an mii/gii based PHY */
index beeb612..e1b33a2 100644 (file)
@@ -7653,21 +7653,23 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->supported |= (SUPPORTED_1000baseT_Half |
                                   SUPPORTED_1000baseT_Full);
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
                cmd->supported |= (SUPPORTED_100baseT_Half |
                                  SUPPORTED_100baseT_Full |
                                  SUPPORTED_10baseT_Half |
                                  SUPPORTED_10baseT_Full |
                                  SUPPORTED_MII);
-       else
+               cmd->port = PORT_TP;
+       } else {
                cmd->supported |= SUPPORTED_FIBRE;
+               cmd->port = PORT_FIBRE;
+       }
   
        cmd->advertising = tp->link_config.advertising;
        if (netif_running(dev)) {
                cmd->speed = tp->link_config.active_speed;
                cmd->duplex = tp->link_config.active_duplex;
        }
-       cmd->port = 0;
        cmd->phy_address = PHY_ADDR;
        cmd->transceiver = 0;
        cmd->autoneg = tp->link_config.autoneg;
@@ -8454,6 +8456,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 
        tx_len = 1514;
        skb = dev_alloc_skb(tx_len);
+       if (!skb)
+               return -ENOMEM;
+
        tx_data = skb_put(skb, tx_len);
        memcpy(tx_data, tp->dev->dev_addr, 6);
        memset(tx_data + 6, 0x0, 8);
index 9a06e61..e2982a8 100644 (file)
@@ -939,9 +939,9 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
        return 0;
 }
 
-static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
+static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
 {
-       struct ieee80211_geo geo;
+       struct ieee80211_geo *geo;
        struct ieee80211_channel *chan;
        int have_a = 0, have_bg = 0;
        int i;
@@ -949,7 +949,10 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
        struct bcm43xx_phyinfo *phy;
        const char *iso_country;
 
-       memset(&geo, 0, sizeof(geo));
+       geo = kzalloc(sizeof(*geo), GFP_KERNEL);
+       if (!geo)
+               return -ENOMEM;
+
        for (i = 0; i < bcm->nr_80211_available; i++) {
                phy = &(bcm->core_80211_ext[i].phy);
                switch (phy->type) {
@@ -967,31 +970,36 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
        iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
 
        if (have_a) {
-               for (i = 0, channel = 0; channel < 201; channel++) {
-                       chan = &geo.a[i++];
+               for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
+                     channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
+                       chan = &geo->a[i++];
                        chan->freq = bcm43xx_channel_to_freq_a(channel);
                        chan->channel = channel;
                }
-               geo.a_channels = i;
+               geo->a_channels = i;
        }
        if (have_bg) {
-               for (i = 0, channel = 1; channel < 15; channel++) {
-                       chan = &geo.bg[i++];
+               for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
+                     channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
+                       chan = &geo->bg[i++];
                        chan->freq = bcm43xx_channel_to_freq_bg(channel);
                        chan->channel = channel;
                }
-               geo.bg_channels = i;
+               geo->bg_channels = i;
        }
-       memcpy(geo.name, iso_country, 2);
+       memcpy(geo->name, iso_country, 2);
        if (0 /*TODO: Outdoor use only */)
-               geo.name[2] = 'O';
+               geo->name[2] = 'O';
        else if (0 /*TODO: Indoor use only */)
-               geo.name[2] = 'I';
+               geo->name[2] = 'I';
        else
-               geo.name[2] = ' ';
-       geo.name[3] = '\0';
+               geo->name[2] = ' ';
+       geo->name[3] = '\0';
+
+       ieee80211_set_geo(bcm->ieee, geo);
+       kfree(geo);
 
-       ieee80211_set_geo(bcm->ieee, &geo);
+       return 0;
 }
 
 /* DummyTransmission function, as documented on 
@@ -3479,16 +3487,17 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
                        goto err_80211_unwind;
                bcm43xx_wireless_core_disable(bcm);
        }
+       err = bcm43xx_geo_init(bcm);
+       if (err)
+               goto err_80211_unwind;
        bcm43xx_pctl_set_crystal(bcm, 0);
 
        /* Set the MAC address in the networking subsystem */
-       if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
+       if (is_valid_ether_addr(bcm->sprom.et1macaddr))
                memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
        else
                memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
 
-       bcm43xx_geo_init(bcm);
-
        snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
                 "Broadcom %04X", bcm->chip_id);
 
index eca79a3..30a202b 100644 (file)
@@ -118,12 +118,14 @@ int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm,
 static inline
 int bcm43xx_is_valid_channel_a(u8 channel)
 {
-       return (channel <= 200);
+       return (channel >= IEEE80211_52GHZ_MIN_CHANNEL
+              && channel <= IEEE80211_52GHZ_MAX_CHANNEL);
 }
 static inline
 int bcm43xx_is_valid_channel_bg(u8 channel)
 {
-       return (channel >= 1 && channel <= 14);
+       return (channel >= IEEE80211_24GHZ_MIN_CHANNEL
+              && channel <= IEEE80211_24GHZ_MAX_CHANNEL);
 }
 static inline
 int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
index 3313716..b0abac5 100644 (file)
@@ -1287,7 +1287,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
        if (radio->revision == 8)
                bcm43xx_phy_write(bcm, 0x0805, 0x3230);
        bcm43xx_phy_init_pctl(bcm);
-       if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) {
+       if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) {
                bcm43xx_phy_write(bcm, 0x0429,
                                  bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
                bcm43xx_phy_write(bcm, 0x04C3,
index 3edbb48..b450639 100644 (file)
@@ -182,8 +182,11 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev,
                mode = BCM43xx_INITIAL_IWMODE;
 
        bcm43xx_lock_mmio(bcm, flags);
-       if (bcm->ieee->iw_mode != mode)
-               bcm43xx_set_iwmode(bcm, mode);
+       if (bcm->initialized) {
+               if (bcm->ieee->iw_mode != mode)
+                       bcm43xx_set_iwmode(bcm, mode);
+       } else
+               bcm->ieee->iw_mode = mode;
        bcm43xx_unlock_mmio(bcm, flags);
 
        return 0;
index 19e2b17..d378478 100644 (file)
@@ -634,6 +634,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4,     quirk_vi
  * non-x86 architectures (yes Via exists on PPC among other places),
  * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
  * interrupts delivered properly.
+ *
+ * Some of the on-chip devices are actually '586 devices' so they are
+ * listed here.
  */
 static void quirk_via_irq(struct pci_dev *dev)
 {
@@ -648,6 +651,10 @@ static void quirk_via_irq(struct pci_dev *dev)
                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
        }
 }
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq);
 DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq);
 DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq);
 DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq);
@@ -895,6 +902,7 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
 
+#ifndef CONFIG_ACPI_SLEEP
 /*
  * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
  * is not activated. The myth is that Asus said that they do not want the
@@ -906,8 +914,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
  * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it 
  * becomes necessary to do this tweak in two steps -- I've chosen the Host
  * bridge as trigger.
+ *
+ * Actually, leaving it unhidden and not redoing the quirk over suspend2ram
+ * will cause thermal management to break down, and causing machine to
+ * overheat.
  */
-static int __initdata asus_hides_smbus = 0;
+static int __initdata asus_hides_smbus;
 
 static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 {
@@ -1050,6 +1062,8 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6 );
 
+#endif
+
 /*
  * SiS 96x south bridge: BIOS typically hides SMBus device...
  */
index c53db7c..738b1ef 100644 (file)
@@ -426,7 +426,7 @@ static int ds_open(struct inode *inode, struct file *file)
 
     if (!warning_printed) {
            printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
-                       "usage.\n");
+                       "usage from process: %s.\n", current->comm);
            printk(KERN_INFO "pcmcia: This interface will soon be removed from "
                        "the kernel; please expect breakage unless you upgrade "
                        "to new tools.\n");
@@ -601,8 +601,12 @@ static int ds_ioctl(struct inode * inode, struct file * file,
            ret = CS_BAD_ARGS;
        else {
            struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
-           ret = pccard_get_configuration_info(s, p_dev, &buf->config);
-           pcmcia_put_dev(p_dev);
+           if (p_dev == NULL)
+                   ret = CS_BAD_ARGS;
+           else {
+                   ret = pccard_get_configuration_info(s, p_dev, &buf->config);
+                   pcmcia_put_dev(p_dev);
+           }
        }
        break;
     case DS_GET_FIRST_TUPLE:
@@ -632,8 +636,12 @@ static int ds_ioctl(struct inode * inode, struct file * file,
                    ret = CS_BAD_ARGS;
            else {
                    struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
-                   ret = pccard_get_status(s, p_dev, &buf->status);
-                   pcmcia_put_dev(p_dev);
+                   if (p_dev == NULL)
+                           ret = CS_BAD_ARGS;
+                   else {
+                           ret = pccard_get_status(s, p_dev, &buf->status);
+                           pcmcia_put_dev(p_dev);
+                   }
            }
            break;
     case DS_VALIDATE_CIS:
@@ -665,9 +673,10 @@ static int ds_ioctl(struct inode * inode, struct file * file,
        if (!(buf->conf_reg.Function &&
             (buf->conf_reg.Function >= s->functions))) {
                struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
-               if (p_dev)
+               if (p_dev) {
                        ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
-               pcmcia_put_dev(p_dev);
+                       pcmcia_put_dev(p_dev);
+               }
        }
        break;
     case DS_GET_FIRST_REGION:
index a23ec54..2bc8aad 100644 (file)
@@ -178,9 +178,9 @@ static int sa1100_rtc_open(struct device *dev)
        return 0;
 
  fail_pi:
-       free_irq(IRQ_RTCAlrm, NULL);
+       free_irq(IRQ_RTCAlrm, dev);
  fail_ai:
-       free_irq(IRQ_RTC1Hz, NULL);
+       free_irq(IRQ_RTC1Hz, dev);
  fail_ui:
        return ret;
 }
@@ -295,7 +295,7 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       seq_printf(seq, "trim/divider\t: 0x%08x\n", RTTR);
+       seq_printf(seq, "trim/divider\t: 0x%08lx\n", RTTR);
        seq_printf(seq, "alarm_IRQ\t: %s\n",
                        (RTSR & RTSR_ALE) ? "yes" : "no" );
        seq_printf(seq, "update_IRQ\t: %s\n",
index 5d6b7a5..e65da92 100644 (file)
@@ -1348,7 +1348,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) 
                        - channel->ccws;
                if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) ||
-                   (irb->scsw.cstat | SCHN_STAT_PCI))
+                   (irb->scsw.cstat & SCHN_STAT_PCI))
                        /* Bloody io subsystem tells us lies about cpa... */
                        index = (index - 1) & (LCS_NUM_BUFFS - 1);
                while (channel->io_idx != index) {
index 383a95f..239e108 100644 (file)
@@ -392,13 +392,16 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
                        return -ENOMEM;
                }
 
-               prom_getproperty(op.op_nodeid, str, tmp, len);
-
-               tmp[len] = '\0';
+               cnt = prom_getproperty(op.op_nodeid, str, tmp, len);
+               if (cnt <= 0) {
+                       error = -EINVAL;
+               } else {
+                       tmp[len] = '\0';
 
-               if (__copy_to_user(argp, &op, sizeof(op)) != 0
-                   || copy_to_user(op.op_buf, tmp, len) != 0)
-                       error = -EFAULT;
+                       if (__copy_to_user(argp, &op, sizeof(op)) != 0 ||
+                           copy_to_user(op.op_buf, tmp, len) != 0)
+                               error = -EFAULT;
+               }
 
                kfree(tmp);
                kfree(str);
index cb30d9c..0c9c2f4 100644 (file)
@@ -219,6 +219,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                ahc->flags |= AHC_39BIT_ADDRESSING;
        } else {
                if (dma_set_mask(dev, DMA_32BIT_MASK)) {
+                       ahc_free(ahc);
                        printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
                        return (-ENODEV);
                }
index 5f58614..3adecef 100644 (file)
@@ -2036,12 +2036,12 @@ ahc_pci_resume(struct ahc_softc *ahc)
         * that the OS doesn't know about and rely on our chip
         * reset handler to handle the rest.
         */
-       ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
-                            ahc->bus_softc.pci_softc.devconfig);
-       ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
-                            ahc->bus_softc.pci_softc.command);
-       ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
-                            ahc->bus_softc.pci_softc.csize_lattime);
+       ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
+                            ahc->bus_softc.pci_softc.devconfig, /*bytes*/4);
+       ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
+                            ahc->bus_softc.pci_softc.command, /*bytes*/1);
+       ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
+                            ahc->bus_softc.pci_softc.csize_lattime, /*bytes*/1);
        if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
                struct  seeprom_descriptor sd;
                u_int   sxfrctl1;
index 0a8ad37..2e9be83 100644 (file)
@@ -739,7 +739,8 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata)
 {
        struct viosrp_adapter_info *req;
        struct srp_event_struct *evt_struct;
-       
+       dma_addr_t addr;
+
        evt_struct = get_event_struct(&hostdata->pool);
        if (!evt_struct) {
                printk(KERN_ERR "ibmvscsi: couldn't allocate an event "
@@ -757,10 +758,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata)
        
        req->common.type = VIOSRP_ADAPTER_INFO_TYPE;
        req->common.length = sizeof(hostdata->madapter_info);
-       req->buffer = dma_map_single(hostdata->dev,
-                                    &hostdata->madapter_info,
-                                    sizeof(hostdata->madapter_info),
-                                    DMA_BIDIRECTIONAL);
+       req->buffer = addr = dma_map_single(hostdata->dev,
+                                           &hostdata->madapter_info,
+                                           sizeof(hostdata->madapter_info),
+                                           DMA_BIDIRECTIONAL);
 
        if (dma_mapping_error(req->buffer)) {
                printk(KERN_ERR
@@ -770,8 +771,13 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata)
                return;
        }
        
-       if (ibmvscsi_send_srp_event(evt_struct, hostdata))
+       if (ibmvscsi_send_srp_event(evt_struct, hostdata)) {
                printk(KERN_ERR "ibmvscsi: couldn't send ADAPTER_INFO_REQ!\n");
+               dma_unmap_single(hostdata->dev,
+                                addr,
+                                sizeof(hostdata->madapter_info),
+                                DMA_BIDIRECTIONAL);
+       }
 };
 
 /**
@@ -1259,6 +1265,7 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,
 {
        struct viosrp_host_config *host_config;
        struct srp_event_struct *evt_struct;
+       dma_addr_t addr;
        int rc;
 
        evt_struct = get_event_struct(&hostdata->pool);
@@ -1279,8 +1286,9 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,
        memset(host_config, 0x00, sizeof(*host_config));
        host_config->common.type = VIOSRP_HOST_CONFIG_TYPE;
        host_config->common.length = length;
-       host_config->buffer = dma_map_single(hostdata->dev, buffer, length,
-                                           DMA_BIDIRECTIONAL);
+       host_config->buffer = addr = dma_map_single(hostdata->dev, buffer,
+                                                   length,
+                                                   DMA_BIDIRECTIONAL);
 
        if (dma_mapping_error(host_config->buffer)) {
                printk(KERN_ERR
@@ -1291,11 +1299,9 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,
 
        init_completion(&evt_struct->comp);
        rc = ibmvscsi_send_srp_event(evt_struct, hostdata);
-       if (rc == 0) {
+       if (rc == 0)
                wait_for_completion(&evt_struct->comp);
-               dma_unmap_single(hostdata->dev, host_config->buffer,
-                                length, DMA_BIDIRECTIONAL);
-       }
+       dma_unmap_single(hostdata->dev, addr, length, DMA_BIDIRECTIONAL);
 
        return rc;
 }
index fad607b..ee22173 100644 (file)
@@ -27,7 +27,6 @@ void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
-void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
 int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *,
                   uint32_t);
 void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
index 8932b1b..41cf5d3 100644 (file)
@@ -113,6 +113,7 @@ struct lpfc_nodelist {
 #define NLP_NPR_ADISC      0x2000000   /* Issue ADISC when dq'ed from
                                           NPR list */
 #define NLP_DELAY_REMOVE   0x4000000   /* Defer removal till end of DSM */
+#define NLP_NODEV_REMOVE   0x8000000   /* Defer removal till discovery ends */
 
 /* Defines for list searchs */
 #define NLP_SEARCH_MAPPED    0x1       /* search mapped */
index 4813bea..283b7d8 100644 (file)
@@ -302,10 +302,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
        if (lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0))
                goto fail_free_mbox;
 
-       /*
-        * set_slim mailbox command needs to execute first,
-        * queue this command to be processed later.
-        */
        mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
        mbox->context2 = ndlp;
 
@@ -781,25 +777,26 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        if (disc && phba->num_disc_nodes) {
                /* Check to see if there are more PLOGIs to be sent */
                lpfc_more_plogi(phba);
-       }
 
-       if (phba->num_disc_nodes == 0) {
-               spin_lock_irq(phba->host->host_lock);
-               phba->fc_flag &= ~FC_NDISC_ACTIVE;
-               spin_unlock_irq(phba->host->host_lock);
+               if (phba->num_disc_nodes == 0) {
+                       spin_lock_irq(phba->host->host_lock);
+                       phba->fc_flag &= ~FC_NDISC_ACTIVE;
+                       spin_unlock_irq(phba->host->host_lock);
 
-               lpfc_can_disctmo(phba);
-               if (phba->fc_flag & FC_RSCN_MODE) {
-                       /* Check to see if more RSCNs came in while we were
-                        * processing this one.
-                        */
-                       if ((phba->fc_rscn_id_cnt == 0) &&
-                           (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {
-                               spin_lock_irq(phba->host->host_lock);
-                               phba->fc_flag &= ~FC_RSCN_MODE;
-                               spin_unlock_irq(phba->host->host_lock);
-                       } else {
-                               lpfc_els_handle_rscn(phba);
+                       lpfc_can_disctmo(phba);
+                       if (phba->fc_flag & FC_RSCN_MODE) {
+                               /*
+                                * Check to see if more RSCNs came in while
+                                * we were processing this one.
+                                */
+                               if ((phba->fc_rscn_id_cnt == 0) &&
+                               (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {
+                                       spin_lock_irq(phba->host->host_lock);
+                                       phba->fc_flag &= ~FC_RSCN_MODE;
+                                       spin_unlock_irq(phba->host->host_lock);
+                               } else {
+                                       lpfc_els_handle_rscn(phba);
+                               }
                        }
                }
        }
@@ -1263,7 +1260,7 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        psli = &phba->sli;
        pring = &psli->ring[LPFC_ELS_RING];
 
-       cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name));
+       cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name);
        elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
                                                ndlp->nlp_DID, ELS_CMD_LOGO);
        if (!elsiocb)
@@ -1451,22 +1448,23 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp)
                         * PLOGIs to be sent
                         */
                        lpfc_more_plogi(phba);
-               }
 
-               if (phba->num_disc_nodes == 0) {
-                       phba->fc_flag &= ~FC_NDISC_ACTIVE;
-                       lpfc_can_disctmo(phba);
-                       if (phba->fc_flag & FC_RSCN_MODE) {
-                               /* Check to see if more RSCNs
-                                * came in while we were
-                                * processing this one.
-                                */
-                               if((phba->fc_rscn_id_cnt==0) &&
-                                  (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {
-                                       phba->fc_flag &= ~FC_RSCN_MODE;
-                               }
-                               else {
-                                       lpfc_els_handle_rscn(phba);
+                       if (phba->num_disc_nodes == 0) {
+                               phba->fc_flag &= ~FC_NDISC_ACTIVE;
+                               lpfc_can_disctmo(phba);
+                               if (phba->fc_flag & FC_RSCN_MODE) {
+                                       /*
+                                        * Check to see if more RSCNs
+                                        * came in while we were
+                                        * processing this one.
+                                        */
+                                       if((phba->fc_rscn_id_cnt==0) &&
+                                        !(phba->fc_flag & FC_RSCN_DISCOVERY)) {
+                                               phba->fc_flag &= ~FC_RSCN_MODE;
+                                       }
+                                       else {
+                                               lpfc_els_handle_rscn(phba);
+                                       }
                                }
                        }
                }
@@ -1872,9 +1870,6 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        if (mbox) {
                if ((rspiocb->iocb.ulpStatus == 0)
                    && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
-                       /* set_slim mailbox command needs to execute first,
-                        * queue this command to be processed later.
-                        */
                        lpfc_unreg_rpi(phba, ndlp);
                        mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
                        mbox->context2 = ndlp;
@@ -1920,6 +1915,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
+       ELS_PKT *els_pkt_ptr;
 
        psli = &phba->sli;
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
@@ -1958,6 +1954,23 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
                pcmd += sizeof (uint32_t);
                memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
                break;
+       case ELS_CMD_PRLO:
+               cmdsize = sizeof (uint32_t) + sizeof (PRLO);
+               elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                            ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
+               if (!elsiocb)
+                       return 1;
+
+               icmd = &elsiocb->iocb;
+               icmd->ulpContext = oldcmd->ulpContext; /* Xri */
+               pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+
+               memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
+                      sizeof (uint32_t) + sizeof (PRLO));
+               *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
+               els_pkt_ptr = (ELS_PKT *) pcmd;
+               els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
+               break;
        default:
                return 1;
        }
@@ -2498,7 +2511,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
        /* If we are about to begin discovery, just ACC the RSCN.
         * Discovery processing will satisfy it.
         */
-       if (phba->hba_state < LPFC_NS_QRY) {
+       if (phba->hba_state <= LPFC_NS_QRY) {
                lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
                                                                newnode);
                return 0;
index 6721e67..adb0860 100644 (file)
@@ -311,8 +311,8 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
        evtp->evt_arg2  = arg2;
        evtp->evt       = evt;
 
-       list_add_tail(&evtp->evt_listp, &phba->work_list);
        spin_lock_irq(phba->host->host_lock);
+       list_add_tail(&evtp->evt_listp, &phba->work_list);
        if (phba->work_wait)
                wake_up(phba->work_wait);
        spin_unlock_irq(phba->host->host_lock);
@@ -1071,10 +1071,6 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
        /* initialize static port data */
        rport->maxframe_size = ndlp->nlp_maxframe;
        rport->supported_classes = ndlp->nlp_class_sup;
-       if ((rport->scsi_target_id != -1) &&
-               (rport->scsi_target_id < MAX_FCP_TARGET)) {
-               ndlp->nlp_sid = rport->scsi_target_id;
-       }
        rdata = rport->dd_data;
        rdata->pnode = ndlp;
 
@@ -1087,6 +1083,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
        if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
                fc_remote_port_rolechg(rport, rport_ids.roles);
 
+       if ((rport->scsi_target_id != -1) &&
+               (rport->scsi_target_id < MAX_FCP_TARGET)) {
+               ndlp->nlp_sid = rport->scsi_target_id;
+       }
 
        return;
 }
@@ -1238,6 +1238,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
                                                evt_listp);
 
                }
+               nlp->nlp_flag &= ~NLP_NODEV_REMOVE;
                nlp->nlp_type |= NLP_FC_NODE;
                break;
        case NLP_MAPPED_LIST:
@@ -1258,6 +1259,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
                                                evt_listp);
 
                }
+               nlp->nlp_flag &= ~NLP_NODEV_REMOVE;
                break;
        case NLP_NPR_LIST:
                nlp->nlp_flag |= list;
@@ -1402,6 +1404,8 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
                        if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi)
                                return 1;
                case CMD_ELS_REQUEST64_CR:
+                       if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID)
+                               return 1;
                case CMD_XMIT_ELS_RSP64_CX:
                        if (iocb->context1 == (uint8_t *) ndlp)
                                return 1;
@@ -1901,10 +1905,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
                         */
                        if (ndlp->nlp_flag & NLP_DELAY_TMO)
                                lpfc_cancel_retry_delay_tmo(phba, ndlp);
-               } else {
-                       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+               } else
                        ndlp = NULL;
-               }
        } else {
                flg = ndlp->nlp_flag & NLP_LIST_MASK;
                if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST))
index 54d0418..eedf988 100644 (file)
@@ -449,6 +449,7 @@ struct serv_parm {  /* Structure is in Big Endian format */
 #define ELS_CMD_RRQ       0x12000000
 #define ELS_CMD_PRLI      0x20100014
 #define ELS_CMD_PRLO      0x21100014
+#define ELS_CMD_PRLO_ACC  0x02100014
 #define ELS_CMD_PDISC     0x50000000
 #define ELS_CMD_FDISC     0x51000000
 #define ELS_CMD_ADISC     0x52000000
@@ -484,6 +485,7 @@ struct serv_parm {  /* Structure is in Big Endian format */
 #define ELS_CMD_RRQ       0x12
 #define ELS_CMD_PRLI      0x14001020
 #define ELS_CMD_PRLO      0x14001021
+#define ELS_CMD_PRLO_ACC  0x14001002
 #define ELS_CMD_PDISC     0x50
 #define ELS_CMD_FDISC     0x51
 #define ELS_CMD_ADISC     0x52
@@ -1539,6 +1541,7 @@ typedef struct {
 
 #define FLAGS_TOPOLOGY_FAILOVER      0x0400    /* Bit 10 */
 #define FLAGS_LINK_SPEED             0x0800    /* Bit 11 */
+#define FLAGS_IMED_ABORT             0x04000   /* Bit 14 */
 
        uint32_t link_speed;
 #define LINK_SPEED_AUTO 0       /* Auto selection */
index 66d5d00..908d0f2 100644 (file)
@@ -294,15 +294,6 @@ lpfc_config_port_post(struct lpfc_hba * phba)
                }
        }
 
-       /* This should turn on DELAYED ABTS for ELS timeouts */
-       lpfc_set_slim(phba, pmb, 0x052198, 0x1);
-       if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
-               phba->hba_state = LPFC_HBA_ERROR;
-               mempool_free( pmb, phba->mbox_mem_pool);
-               return -EIO;
-       }
-
-
        lpfc_read_config(phba, pmb);
        if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
                lpfc_printf_log(phba,
@@ -804,7 +795,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
                int    max_speed;
                char * ports;
                char * bus;
-       } m;
+       } m = {"<Unknown>", 0, "", ""};
 
        pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
        ports = (hdrtype == 0x80) ? "2-port " : "";
@@ -1627,7 +1618,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 
        error = lpfc_alloc_sysfs_attr(phba);
        if (error)
-               goto out_kthread_stop;
+               goto out_remove_host;
 
        error = request_irq(phba->pcidev->irq, lpfc_intr_handler, SA_SHIRQ,
                                                        LPFC_DRIVER_NAME, phba);
@@ -1644,8 +1635,10 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
        phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
 
        error = lpfc_sli_hba_setup(phba);
-       if (error)
+       if (error) {
+               error = -ENODEV;
                goto out_free_irq;
+       }
 
        if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
                spin_lock_irq(phba->host->host_lock);
@@ -1700,6 +1693,9 @@ out_free_irq:
        free_irq(phba->pcidev->irq, phba);
 out_free_sysfs_attr:
        lpfc_free_sysfs_attr(phba);
+out_remove_host:
+       fc_remove_host(phba->host);
+       scsi_remove_host(phba->host);
 out_kthread_stop:
        kthread_stop(phba->worker_thread);
 out_free_iocbq:
@@ -1721,12 +1717,14 @@ out_iounmap_slim:
 out_idr_remove:
        idr_remove(&lpfc_hba_index, phba->brd_no);
 out_put_host:
+       phba->host = NULL;
        scsi_host_put(host);
 out_release_regions:
        pci_release_regions(pdev);
 out_disable_device:
        pci_disable_device(pdev);
 out:
+       pci_set_drvdata(pdev, NULL);
        return error;
 }
 
index c585e2b..e42f22a 100644 (file)
@@ -200,6 +200,9 @@ lpfc_init_link(struct lpfc_hba * phba,
                break;
        }
 
+       /* Enable asynchronous ABTS responses from firmware */
+       mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT;
+
        /* NEW_FEATURE
         * Setting up the link speed
         */
@@ -292,36 +295,6 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb)
        return;
 }
 
-/***********************************************/
-
-/*                  command to write slim      */
-/***********************************************/
-void
-lpfc_set_slim(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint32_t addr,
-             uint32_t value)
-{
-       MAILBOX_t *mb;
-
-       mb = &pmb->mb;
-       memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
-
-       /* addr = 0x090597 is AUTO ABTS disable for ELS commands */
-       /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
-
-       /*
-        * Always turn on DELAYED ABTS for ELS timeouts
-        */
-       if ((addr == 0x052198) && (value == 0))
-               value = 1;
-
-       mb->un.varWords[0] = addr;
-       mb->un.varWords[1] = value;
-
-       mb->mbxCommand = MBX_SET_SLIM;
-       mb->mbxOwner = OWN_HOST;
-       return;
-}
-
 /**********************************************/
 /*  lpfc_read_nv  Issue a READ CONFIG         */
 /*                mailbox command             */
index 3d77bd9..27d60ad 100644 (file)
@@ -465,14 +465,18 @@ lpfc_rcv_padisc(struct lpfc_hba * phba,
 static int
 lpfc_rcv_logo(struct lpfc_hba * phba,
                      struct lpfc_nodelist * ndlp,
-                     struct lpfc_iocbq *cmdiocb)
+                     struct lpfc_iocbq *cmdiocb,
+                     uint32_t els_cmd)
 {
        /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */
        /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
         * PLOGIs during LOGO storms from a device.
         */
        ndlp->nlp_flag |= NLP_LOGO_ACC;
-       lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+       if (els_cmd == ELS_CMD_PRLO)
+               lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+       else
+               lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 
        if (!(ndlp->nlp_type & NLP_FABRIC) ||
                (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
@@ -681,7 +685,7 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba,
        /* software abort outstanding PLOGI */
        lpfc_els_abort(phba, ndlp, 1);
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -788,10 +792,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
        if (lpfc_reg_login
            (phba, irsp->un.elsreq64.remoteID,
             (uint8_t *) sp, mbox, 0) == 0) {
-               /* set_slim mailbox command needs to
-                * execute first, queue this command to
-                * be processed later.
-                */
                switch (ndlp->nlp_DID) {
                case NameServer_DID:
                        mbox->mbox_cmpl =
@@ -832,11 +832,17 @@ static uint32_t
 lpfc_device_rm_plogi_issue(struct lpfc_hba * phba,
                           struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
 {
-       /* software abort outstanding PLOGI */
-       lpfc_els_abort(phba, ndlp, 1);
+       if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+               ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+               return ndlp->nlp_state;
+       }
+       else {
+               /* software abort outstanding PLOGI */
+               lpfc_els_abort(phba, ndlp, 1);
 
-       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-       return NLP_STE_FREED_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
 }
 
 static uint32_t
@@ -851,7 +857,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba,
        ndlp->nlp_state = NLP_STE_NPR_NODE;
        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
        spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        spin_unlock_irq(phba->host->host_lock);
 
        return ndlp->nlp_state;
@@ -905,7 +911,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba,
        /* software abort outstanding ADISC */
        lpfc_els_abort(phba, ndlp, 0);
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -932,7 +938,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba,
        cmdiocb = (struct lpfc_iocbq *) arg;
 
        /* Treat like rcv logo */
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO);
        return ndlp->nlp_state;
 }
 
@@ -987,11 +993,17 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba,
                            struct lpfc_nodelist * ndlp, void *arg,
                            uint32_t evt)
 {
-       /* software abort outstanding ADISC */
-       lpfc_els_abort(phba, ndlp, 1);
+       if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+               ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+               return ndlp->nlp_state;
+       }
+       else {
+               /* software abort outstanding ADISC */
+               lpfc_els_abort(phba, ndlp, 1);
 
-       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-       return NLP_STE_FREED_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
 }
 
 static uint32_t
@@ -1006,7 +1018,7 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba,
        ndlp->nlp_state = NLP_STE_NPR_NODE;
        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
        spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        ndlp->nlp_flag |= NLP_NPR_ADISC;
        spin_unlock_irq(phba->host->host_lock);
 
@@ -1048,7 +1060,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
 
        cmdiocb = (struct lpfc_iocbq *) arg;
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -1073,7 +1085,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba,
        struct lpfc_iocbq *cmdiocb;
 
        cmdiocb = (struct lpfc_iocbq *) arg;
-       lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+       lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
        return ndlp->nlp_state;
 }
 
@@ -1133,8 +1145,14 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba,
                              struct lpfc_nodelist * ndlp, void *arg,
                              uint32_t evt)
 {
-       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-       return NLP_STE_FREED_NODE;
+       if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+               ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+               return ndlp->nlp_state;
+       }
+       else {
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
 }
 
 static uint32_t
@@ -1146,7 +1164,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba,
        ndlp->nlp_state = NLP_STE_NPR_NODE;
        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
        spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        spin_unlock_irq(phba->host->host_lock);
        return ndlp->nlp_state;
 }
@@ -1186,7 +1204,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba,
        /* Software abort outstanding PRLI before sending acc */
        lpfc_els_abort(phba, ndlp, 1);
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -1214,7 +1232,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba,
        struct lpfc_iocbq *cmdiocb;
 
        cmdiocb = (struct lpfc_iocbq *) arg;
-       lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+       lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
        return ndlp->nlp_state;
 }
 
@@ -1278,11 +1296,17 @@ static uint32_t
 lpfc_device_rm_prli_issue(struct lpfc_hba * phba,
                          struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
 {
-       /* software abort outstanding PRLI */
-       lpfc_els_abort(phba, ndlp, 1);
+       if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+               ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+               return ndlp->nlp_state;
+       }
+       else {
+               /* software abort outstanding PLOGI */
+               lpfc_els_abort(phba, ndlp, 1);
 
-       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-       return NLP_STE_FREED_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
 }
 
 
@@ -1313,7 +1337,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba,
        ndlp->nlp_state = NLP_STE_NPR_NODE;
        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
        spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        spin_unlock_irq(phba->host->host_lock);
        return ndlp->nlp_state;
 }
@@ -1351,7 +1375,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba,
 
        cmdiocb = (struct lpfc_iocbq *) arg;
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -1375,7 +1399,7 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba,
 
        cmdiocb = (struct lpfc_iocbq *) arg;
 
-       lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+       lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
        return ndlp->nlp_state;
 }
 
@@ -1386,7 +1410,7 @@ lpfc_device_recov_unmap_node(struct lpfc_hba * phba,
        ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
        ndlp->nlp_state = NLP_STE_NPR_NODE;
        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        lpfc_disc_set_adisc(phba, ndlp);
 
        return ndlp->nlp_state;
@@ -1424,7 +1448,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba,
 
        cmdiocb = (struct lpfc_iocbq *) arg;
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -1456,7 +1480,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba,
        spin_unlock_irq(phba->host->host_lock);
 
        /* Treat like rcv logo */
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO);
        return ndlp->nlp_state;
 }
 
@@ -1469,7 +1493,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba,
        ndlp->nlp_state = NLP_STE_NPR_NODE;
        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
        spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        spin_unlock_irq(phba->host->host_lock);
        lpfc_disc_set_adisc(phba, ndlp);
        return ndlp->nlp_state;
@@ -1551,7 +1575,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba,
 
        cmdiocb = (struct lpfc_iocbq *) arg;
 
-       lpfc_rcv_logo(phba, ndlp, cmdiocb);
+       lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
        return ndlp->nlp_state;
 }
 
@@ -1617,9 +1641,16 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba,
                          struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
 {
        struct lpfc_iocbq *cmdiocb, *rspiocb;
+       IOCB_t *irsp;
 
        cmdiocb = (struct lpfc_iocbq *) arg;
        rspiocb = cmdiocb->context_un.rsp_iocb;
+
+       irsp = &rspiocb->iocb;
+       if (irsp->ulpStatus) {
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
        return ndlp->nlp_state;
 }
 
@@ -1628,9 +1659,16 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba,
                          struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
 {
        struct lpfc_iocbq *cmdiocb, *rspiocb;
+       IOCB_t *irsp;
 
        cmdiocb = (struct lpfc_iocbq *) arg;
        rspiocb = cmdiocb->context_un.rsp_iocb;
+
+       irsp = &rspiocb->iocb;
+       if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
        return ndlp->nlp_state;
 }
 
@@ -1649,9 +1687,16 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba,
                            uint32_t evt)
 {
        struct lpfc_iocbq *cmdiocb, *rspiocb;
+       IOCB_t *irsp;
 
        cmdiocb = (struct lpfc_iocbq *) arg;
        rspiocb = cmdiocb->context_un.rsp_iocb;
+
+       irsp = &rspiocb->iocb;
+       if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+               return NLP_STE_FREED_NODE;
+       }
        return ndlp->nlp_state;
 }
 
@@ -1668,7 +1713,12 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba,
 
        if (!mb->mbxStatus)
                ndlp->nlp_rpi = mb->un.varWords[0];
-
+       else {
+               if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+                       return NLP_STE_FREED_NODE;
+               }
+       }
        return ndlp->nlp_state;
 }
 
@@ -1677,6 +1727,10 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba,
                            struct lpfc_nodelist * ndlp, void *arg,
                            uint32_t evt)
 {
+       if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+               ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+               return ndlp->nlp_state;
+       }
        lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
        return NLP_STE_FREED_NODE;
 }
@@ -1687,7 +1741,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba,
                            uint32_t evt)
 {
        spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
        spin_unlock_irq(phba->host->host_lock);
        if (ndlp->nlp_flag & NLP_DELAY_TMO) {
                lpfc_cancel_retry_delay_tmo(phba, ndlp);
index f937998..7dc4c2e 100644 (file)
@@ -629,8 +629,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
        struct lpfc_iocbq *piocbq;
        IOCB_t *piocb;
        struct fcp_cmnd *fcp_cmnd;
-       struct scsi_device *scsi_dev = lpfc_cmd->pCmd->device;
-       struct lpfc_rport_data *rdata = scsi_dev->hostdata;
+       struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
        struct lpfc_nodelist *ndlp = rdata->pnode;
 
        if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
@@ -665,56 +664,18 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
                piocb->ulpTimeout = lpfc_cmd->timeout;
        }
 
-       lpfc_cmd->rdata = rdata;
-
-       switch (task_mgmt_cmd) {
-       case FCP_LUN_RESET:
-               /* Issue LUN Reset to TGT <num> LUN <num> */
-               lpfc_printf_log(phba,
-                               KERN_INFO,
-                               LOG_FCP,
-                               "%d:0703 Issue LUN Reset to TGT %d LUN %d "
-                               "Data: x%x x%x\n",
-                               phba->brd_no,
-                               scsi_dev->id, scsi_dev->lun,
-                               ndlp->nlp_rpi, ndlp->nlp_flag);
-
-               break;
-       case FCP_ABORT_TASK_SET:
-               /* Issue Abort Task Set to TGT <num> LUN <num> */
-               lpfc_printf_log(phba,
-                               KERN_INFO,
-                               LOG_FCP,
-                               "%d:0701 Issue Abort Task Set to TGT %d LUN %d "
-                               "Data: x%x x%x\n",
-                               phba->brd_no,
-                               scsi_dev->id, scsi_dev->lun,
-                               ndlp->nlp_rpi, ndlp->nlp_flag);
-
-               break;
-       case FCP_TARGET_RESET:
-               /* Issue Target Reset to TGT <num> */
-               lpfc_printf_log(phba,
-                               KERN_INFO,
-                               LOG_FCP,
-                               "%d:0702 Issue Target Reset to TGT %d "
-                               "Data: x%x x%x\n",
-                               phba->brd_no,
-                               scsi_dev->id, ndlp->nlp_rpi,
-                               ndlp->nlp_flag);
-               break;
-       }
-
        return (1);
 }
 
 static int
-lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
+lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
+                   unsigned  tgt_id, struct lpfc_rport_data *rdata)
 {
        struct lpfc_iocbq *iocbq;
        struct lpfc_iocbq *iocbqrsp;
        int ret;
 
+       lpfc_cmd->rdata = rdata;
        ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET);
        if (!ret)
                return FAILED;
@@ -726,6 +687,13 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
        if (!iocbqrsp)
                return FAILED;
 
+       /* Issue Target Reset to TGT <num> */
+       lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+                       "%d:0702 Issue Target Reset to TGT %d "
+                       "Data: x%x x%x\n",
+                       phba->brd_no, tgt_id, rdata->pnode->nlp_rpi,
+                       rdata->pnode->nlp_flag);
+
        ret = lpfc_sli_issue_iocb_wait(phba,
                                       &phba->sli.ring[phba->sli.fcp_ring],
                                       iocbq, iocbqrsp, lpfc_cmd->timeout);
@@ -1021,6 +989,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        lpfc_cmd->pCmd = cmnd;
        lpfc_cmd->timeout = 60;
        lpfc_cmd->scsi_hba = phba;
+       lpfc_cmd->rdata = rdata;
 
        ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET);
        if (!ret)
@@ -1033,6 +1002,11 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        if (iocbqrsp == NULL)
                goto out_free_scsi_buf;
 
+       lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+                       "%d:0703 Issue LUN Reset to TGT %d LUN %d "
+                       "Data: x%x x%x\n", phba->brd_no, cmnd->device->id,
+                       cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag);
+
        ret = lpfc_sli_issue_iocb_wait(phba,
                                       &phba->sli.ring[phba->sli.fcp_ring],
                                       iocbq, iocbqrsp, lpfc_cmd->timeout);
@@ -1104,7 +1078,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
        int match;
        int ret = FAILED, i, err_count = 0;
        int cnt, loopcnt;
-       unsigned int midlayer_id = 0;
        struct lpfc_scsi_buf * lpfc_cmd;
 
        lpfc_block_requests(phba);
@@ -1124,7 +1097,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
         * targets known to the driver.  Should any target reset
         * fail, this routine returns failure to the midlayer.
         */
-       midlayer_id = cmnd->device->id;
        for (i = 0; i < MAX_FCP_TARGET; i++) {
                /* Search the mapped list for this target ID */
                match = 0;
@@ -1137,9 +1109,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
                if (!match)
                        continue;
 
-               lpfc_cmd->pCmd->device->id = i;
-               lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data;
-               ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba);
+               ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba,
+                                         i, ndlp->rport->dd_data);
                if (ret != SUCCESS) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                                "%d:0713 Bus Reset on target %d failed\n",
@@ -1158,7 +1129,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
         * the targets.  Unfortunately, some targets do not abide by
         * this forcing the driver to double check.
         */
-       cmnd->device->id = midlayer_id;
        cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
                                0, 0, LPFC_CTX_HOST);
        if (cnt)
index 4cf1366..6b73756 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.4"
+#define LPFC_DRIVER_VERSION "8.1.6"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
index 80b68a2..de35ffe 100644 (file)
@@ -4471,7 +4471,6 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
 {
        Scsi_Cmnd       *scmd;
        struct  scsi_device *sdev;
-       unsigned long   flags = 0;
        scb_t   *scb;
        int     rval;
 
index c11e5ce..bec1424 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_mbox.c
- * Version     : v2.20.4.7 (Nov 14 2005)
+ * Version     : v2.20.4.8 (Apr 11 2006)
  *
  * Authors:
  *     Atul Mukker             <Atul.Mukker@lsil.com>
@@ -2278,6 +2278,7 @@ megaraid_mbox_dpc(unsigned long devp)
        unsigned long           flags;
        uint8_t                 c;
        int                     status;
+       uioc_t                  *kioc;
 
 
        if (!adapter) return;
@@ -2320,6 +2321,9 @@ megaraid_mbox_dpc(unsigned long devp)
                        // remove from local clist
                        list_del_init(&scb->list);
 
+                       kioc                    = (uioc_t *)scb->gp;
+                       kioc->status            = 0;
+
                        megaraid_mbox_mm_done(adapter, scb);
 
                        continue;
@@ -2636,6 +2640,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp)
        int             recovery_window;
        int             recovering;
        int             i;
+       uioc_t          *kioc;
 
        adapter         = SCP2ADAPTER(scp);
        raid_dev        = ADAP2RAIDDEV(adapter);
@@ -2655,32 +2660,51 @@ megaraid_reset_handler(struct scsi_cmnd *scp)
        // Also, reset all the commands currently owned by the driver
        spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags);
        list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) {
-
                list_del_init(&scb->list);      // from pending list
 
-               con_log(CL_ANN, (KERN_WARNING
-                       "megaraid: %ld:%d[%d:%d], reset from pending list\n",
-                               scp->serial_number, scb->sno,
-                               scb->dev_channel, scb->dev_target));
+               if (scb->sno >= MBOX_MAX_SCSI_CMDS) {
+                       con_log(CL_ANN, (KERN_WARNING
+                       "megaraid: IOCTL packet with %d[%d:%d] being reset\n",
+                       scb->sno, scb->dev_channel, scb->dev_target));
 
-               scp->result = (DID_RESET << 16);
-               scp->scsi_done(scp);
+                       scb->status = -1;
 
-               megaraid_dealloc_scb(adapter, scb);
+                       kioc                    = (uioc_t *)scb->gp;
+                       kioc->status            = -EFAULT;
+
+                       megaraid_mbox_mm_done(adapter, scb);
+               } else {
+                       if (scb->scp == scp) {  // Found command
+                               con_log(CL_ANN, (KERN_WARNING
+                                       "megaraid: %ld:%d[%d:%d], reset from pending list\n",
+                                       scp->serial_number, scb->sno,
+                                       scb->dev_channel, scb->dev_target));
+                       } else {
+                               con_log(CL_ANN, (KERN_WARNING
+                               "megaraid: IO packet with %d[%d:%d] being reset\n",
+                               scb->sno, scb->dev_channel, scb->dev_target));
+                       }
+
+                       scb->scp->result = (DID_RESET << 16);
+                       scb->scp->scsi_done(scb->scp);
+
+                       megaraid_dealloc_scb(adapter, scb);
+               }
        }
        spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags);
 
        if (adapter->outstanding_cmds) {
                con_log(CL_ANN, (KERN_NOTICE
                        "megaraid: %d outstanding commands. Max wait %d sec\n",
-                       adapter->outstanding_cmds, MBOX_RESET_WAIT));
+                       adapter->outstanding_cmds,
+                       (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT)));
        }
 
        recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT;
 
        recovering = adapter->outstanding_cmds;
 
-       for (i = 0; i < recovery_window && adapter->outstanding_cmds; i++) {
+       for (i = 0; i < recovery_window; i++) {
 
                megaraid_ack_sequence(adapter);
 
@@ -2689,12 +2713,11 @@ megaraid_reset_handler(struct scsi_cmnd *scp)
                        con_log(CL_ANN, (
                        "megaraid mbox: Wait for %d commands to complete:%d\n",
                                adapter->outstanding_cmds,
-                               MBOX_RESET_WAIT - i));
+                               (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i));
                }
 
                // bailout if no recovery happended in reset time
-               if ((i == MBOX_RESET_WAIT) &&
-                       (recovering == adapter->outstanding_cmds)) {
+               if (adapter->outstanding_cmds == 0) {
                        break;
                }
 
@@ -2918,12 +2941,13 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[])
        wmb();
        WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);
 
-       for (i = 0; i < 0xFFFFF; i++) {
+       for (i = 0; i < MBOX_SYNC_WAIT_CNT; i++) {
                if (mbox->numstatus != 0xFF) break;
                rmb();
+               udelay(MBOX_SYNC_DELAY_200);
        }
 
-       if (i == 0xFFFFF) {
+       if (i == MBOX_SYNC_WAIT_CNT) {
                // We may need to re-calibrate the counter
                con_log(CL_ANN, (KERN_CRIT
                        "megaraid: fast sync command timed out\n"));
@@ -3475,7 +3499,7 @@ megaraid_cmm_register(adapter_t *adapter)
        adp.drvr_data           = (unsigned long)adapter;
        adp.pdev                = adapter->pdev;
        adp.issue_uioc          = megaraid_mbox_mm_handler;
-       adp.timeout             = 300;
+       adp.timeout             = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT;
        adp.max_kioc            = MBOX_MAX_USER_CMDS;
 
        if ((rval = mraid_mm_register_adp(&adp)) != 0) {
@@ -3702,7 +3726,6 @@ megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb)
        unsigned long           flags;
 
        kioc                    = (uioc_t *)scb->gp;
-       kioc->status            = 0;
        mbox64                  = (mbox64_t *)(unsigned long)kioc->cmdbuf;
        mbox64->mbox32.status   = scb->status;
        raw_mbox                = (uint8_t *)&mbox64->mbox32;
index 882fb1a..868fb0e 100644 (file)
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION       "2.20.4.7"
-#define MEGARAID_EXT_VERSION   "(Release Date: Mon Nov 14 12:27:22 EST 2005)"
+#define MEGARAID_VERSION       "2.20.4.8"
+#define MEGARAID_EXT_VERSION   "(Release Date: Mon Apr 11 12:27:22 EST 2006)"
 
 
 /*
 #define MBOX_BUSY_WAIT         10      // max usec to wait for busy mailbox
 #define MBOX_RESET_WAIT                180     // wait these many seconds in reset
 #define MBOX_RESET_EXT_WAIT    120     // extended wait reset
+#define MBOX_SYNC_WAIT_CNT     0xFFFF  // wait loop index for synchronous mode
+
+#define MBOX_SYNC_DELAY_200    200     // 200 micro-seconds
 
 /*
  * maximum transfer that can happen through the firmware commands issued
index 8f3ce04..e8f534f 100644 (file)
@@ -898,10 +898,8 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp)
 
        adapter = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL);
 
-       if (!adapter) {
-               rval = -ENOMEM;
-               goto memalloc_error;
-       }
+       if (!adapter)
+               return -ENOMEM;
 
        memset(adapter, 0, sizeof(mraid_mmadp_t));
 
index 017729c..584fe5d 100644 (file)
@@ -599,6 +599,7 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
 *    Either SUCCESS or FAILED.
 *
 * Note:
+*    Only return FAILED if command not returned by firmware.
 **************************************************************************/
 int
 qla2xxx_eh_abort(struct scsi_cmnd *cmd)
@@ -609,11 +610,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
        unsigned long flags;
+       int wait = 0;
 
        if (!CMD_SP(cmd))
-               return FAILED;
+               return SUCCESS;
 
-       ret = FAILED;
+       ret = SUCCESS;
 
        id = cmd->device->id;
        lun = cmd->device->lun;
@@ -642,7 +644,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
                } else {
                        DEBUG3(printk("%s(%ld): abort_command "
                            "mbx success.\n", __func__, ha->host_no));
-                       ret = SUCCESS;
+                       wait = 1;
                }
                spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -651,17 +653,18 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        /* Wait for the command to be returned. */
-       if (ret == SUCCESS) {
+       if (wait) {
                if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
                        qla_printk(KERN_ERR, ha,
                            "scsi(%ld:%d:%d): Abort handler timed out -- %lx "
                            "%x.\n", ha->host_no, id, lun, serial, ret);
+                       ret = FAILED;
                }
        }
 
        qla_printk(KERN_INFO, ha,
-           "scsi(%ld:%d:%d): Abort command issued -- %lx %x.\n", ha->host_no,
-           id, lun, serial, ret);
+           "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n",
+           ha->host_no, id, lun, wait, serial, ret);
 
        return ret;
 }
@@ -1700,8 +1703,8 @@ qla2x00_free_device(scsi_qla_host_t *ha)
        ha->flags.online = 0;
 
        /* Detach interrupts */
-       if (ha->pdev->irq)
-               free_irq(ha->pdev->irq, ha);
+       if (ha->host->irq)
+               free_irq(ha->host->irq, ha);
 
        /* release io space registers  */
        if (ha->iobase)
index c750d33..941c1e1 100644 (file)
@@ -56,6 +56,8 @@ static struct {
        {"DENON", "DRD-25X", "V", BLIST_NOLUN},                 /* locks up */
        {"HITACHI", "DK312C", "CM81", BLIST_NOLUN},     /* responds to all lun */
        {"HITACHI", "DK314C", "CR21", BLIST_NOLUN},     /* responds to all lun */
+       {"IBM", "2104-DU3", NULL, BLIST_NOLUN},         /* locks up */
+       {"IBM", "2104-TU3", NULL, BLIST_NOLUN},         /* locks up */
        {"IMS", "CDD521/10", "2.06", BLIST_NOLUN},      /* locks up */
        {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN},     /* locks up */
        {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN},     /* locks up */
index 7b0f9a3..764a8b3 100644 (file)
@@ -1067,16 +1067,29 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
                        break;
                case NOT_READY:
                        /*
-                        * If the device is in the process of becoming ready,
-                        * retry.
+                        * If the device is in the process of becoming
+                        * ready, or has a temporary blockage, retry.
                         */
-                       if (sshdr.asc == 0x04 && sshdr.ascq == 0x01) {
-                               scsi_requeue_command(q, cmd);
-                               return;
+                       if (sshdr.asc == 0x04) {
+                               switch (sshdr.ascq) {
+                               case 0x01: /* becoming ready */
+                               case 0x04: /* format in progress */
+                               case 0x05: /* rebuild in progress */
+                               case 0x06: /* recalculation in progress */
+                               case 0x07: /* operation in progress */
+                               case 0x08: /* Long write in progress */
+                               case 0x09: /* self test in progress */
+                                       scsi_requeue_command(q, cmd);
+                                       return;
+                               default:
+                                       break;
+                               }
                        }
-                       if (!(req->flags & REQ_QUIET))
+                       if (!(req->flags & REQ_QUIET)) {
                                scmd_printk(KERN_INFO, cmd,
-                                          "Device not ready.\n");
+                                          "Device not ready: ");
+                               scsi_print_sense_hdr("", &sshdr);
+                       }
                        scsi_end_request(cmd, 0, this_count, 1);
                        return;
                case VOLUME_OVERFLOW:
index 3274ab7..255886a 100644 (file)
@@ -75,7 +75,7 @@ param_setup(char *str)
                else if(!strncmp(pos, "id:", 3)) {
                        if(slot == -1) {
                                printk(KERN_WARNING "sim710: Must specify slot for id parameter\n");
-                       } else if(slot > MAX_SLOTS) {
+                       } else if(slot >= MAX_SLOTS) {
                                printk(KERN_WARNING "sim710: Illegal slot %d for id %d\n", slot, val);
                        } else {
                                id_array[slot] = val;
index 674b15c..bbf78aa 100644 (file)
@@ -362,6 +362,40 @@ serial_out(struct uart_8250_port *up, int offset, int value)
 #define serial_inp(up, offset)         serial_in(up, offset)
 #define serial_outp(up, offset, value) serial_out(up, offset, value)
 
+/* Uart divisor latch read */
+static inline int _serial_dl_read(struct uart_8250_port *up)
+{
+       return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static inline void _serial_dl_write(struct uart_8250_port *up, int value)
+{
+       serial_outp(up, UART_DLL, value & 0xff);
+       serial_outp(up, UART_DLM, value >> 8 & 0xff);
+}
+
+#ifdef CONFIG_SERIAL_8250_AU1X00
+/* Au1x00 haven't got a standard divisor latch */
+static int serial_dl_read(struct uart_8250_port *up)
+{
+       if (up->port.iotype == UPIO_AU)
+               return __raw_readl(up->port.membase + 0x28);
+       else
+               return _serial_dl_read(up);
+}
+
+static void serial_dl_write(struct uart_8250_port *up, int value)
+{
+       if (up->port.iotype == UPIO_AU)
+               __raw_writel(value, up->port.membase + 0x28);
+       else
+               _serial_dl_write(up, value);
+}
+#else
+#define serial_dl_read(up) _serial_dl_read(up)
+#define serial_dl_write(up, value) _serial_dl_write(up, value)
+#endif
 
 /*
  * For the 16C950
@@ -494,7 +528,8 @@ static void disable_rsa(struct uart_8250_port *up)
  */
 static int size_fifo(struct uart_8250_port *up)
 {
-       unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr;
+       unsigned char old_fcr, old_mcr, old_lcr;
+       unsigned short old_dl;
        int count;
 
        old_lcr = serial_inp(up, UART_LCR);
@@ -505,10 +540,8 @@ static int size_fifo(struct uart_8250_port *up)
                    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
        serial_outp(up, UART_MCR, UART_MCR_LOOP);
        serial_outp(up, UART_LCR, UART_LCR_DLAB);
-       old_dll = serial_inp(up, UART_DLL);
-       old_dlm = serial_inp(up, UART_DLM);
-       serial_outp(up, UART_DLL, 0x01);
-       serial_outp(up, UART_DLM, 0x00);
+       old_dl = serial_dl_read(up);
+       serial_dl_write(up, 0x0001);
        serial_outp(up, UART_LCR, 0x03);
        for (count = 0; count < 256; count++)
                serial_outp(up, UART_TX, count);
@@ -519,8 +552,7 @@ static int size_fifo(struct uart_8250_port *up)
        serial_outp(up, UART_FCR, old_fcr);
        serial_outp(up, UART_MCR, old_mcr);
        serial_outp(up, UART_LCR, UART_LCR_DLAB);
-       serial_outp(up, UART_DLL, old_dll);
-       serial_outp(up, UART_DLM, old_dlm);
+       serial_dl_write(up, old_dl);
        serial_outp(up, UART_LCR, old_lcr);
 
        return count;
@@ -750,8 +782,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
 
                        serial_outp(up, UART_LCR, 0xE0);
 
-                       quot = serial_inp(up, UART_DLM) << 8;
-                       quot += serial_inp(up, UART_DLL);
+                       quot = serial_dl_read(up);
                        quot <<= 3;
 
                        status1 = serial_in(up, 0x04); /* EXCR1 */
@@ -759,8 +790,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
                        status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
                        serial_outp(up, 0x04, status1);
                        
-                       serial_outp(up, UART_DLL, quot & 0xff);
-                       serial_outp(up, UART_DLM, quot >> 8);
+                       serial_dl_write(up, quot);
 
                        serial_outp(up, UART_LCR, 0);
 
@@ -1862,8 +1892,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
                serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
        }
 
-       serial_outp(up, UART_DLL, quot & 0xff);         /* LS of divisor */
-       serial_outp(up, UART_DLM, quot >> 8);           /* MS of divisor */
+       serial_dl_write(up, quot);
 
        /*
         * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
@@ -1906,6 +1935,9 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        int ret = 0;
 
        switch (up->port.iotype) {
+       case UPIO_AU:
+               size = 0x100000;
+               /* fall thru */
        case UPIO_MEM:
                if (!up->port.mapbase)
                        break;
@@ -1938,6 +1970,9 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
        unsigned int size = 8 << up->port.regshift;
 
        switch (up->port.iotype) {
+       case UPIO_AU:
+               size = 0x100000;
+               /* fall thru */
        case UPIO_MEM:
                if (!up->port.mapbase)
                        break;
@@ -2200,10 +2235,17 @@ static void
 serial8250_console_write(struct console *co, const char *s, unsigned int count)
 {
        struct uart_8250_port *up = &serial8250_ports[co->index];
+       unsigned long flags;
        unsigned int ier;
+       int locked = 1;
 
        touch_nmi_watchdog();
 
+       if (oops_in_progress) {
+               locked = spin_trylock_irqsave(&up->port.lock, flags);
+       } else
+               spin_lock_irqsave(&up->port.lock, flags);
+
        /*
         *      First save the IER then disable the interrupts
         */
@@ -2221,8 +2263,10 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
         *      and restore the IER
         */
        wait_for_xmitr(up, BOTH_EMPTY);
-       up->ier |= UART_IER_THRI;
-       serial_out(up, UART_IER, ier | UART_IER_THRI);
+       serial_out(up, UART_IER, ier);
+
+       if (locked)
+               spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
 static int serial8250_console_setup(struct console *co, char *options)
index 3d1bfd0..58015fd 100644 (file)
        {                                               \
                .iobase         = _base,                \
                .membase        = (void __iomem *)_base,\
-               .mapbase        = _base,                \
+               .mapbase        = CPHYSADDR(_base),     \
                .irq            = _irq,                 \
                .uartclk        = 0,    /* filled */    \
                .regshift       = 2,                    \
                .iotype         = UPIO_AU,              \
-               .flags          = UPF_SKIP_TEST |       \
-                                 UPF_IOREMAP,          \
+               .flags          = UPF_SKIP_TEST         \
        }
 
 static struct plat_serial8250_port au1x00_data[] = {
index aa5eb7d..3b35cb7 100644 (file)
@@ -5,6 +5,13 @@
  *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *
+ *  2006 (c) MontaVista Software, Inc.
+ *     Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
  */
 #ifndef CPM_UART_H
 #define CPM_UART_H
@@ -101,12 +108,13 @@ static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo
        int offset;
        u32 val = (u32)addr;
        /* sane check */
-       if ((val >= (u32)pinfo->mem_addr) &&
+       if (likely((val >= (u32)pinfo->mem_addr)) &&
                        (val<((u32)pinfo->mem_addr + pinfo->mem_size))) {
                offset = val - (u32)pinfo->mem_addr;
                return pinfo->dma_addr+offset;
        }
-       printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
+       /* something nasty happened */
+       BUG();
        return 0;
 }
 
@@ -115,12 +123,13 @@ static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo
        int offset;
        u32 val = addr;
        /* sane check */
-       if ((val >= pinfo->dma_addr) &&
-                       (val<(pinfo->dma_addr + pinfo->mem_size))) {
+       if (likely((val >= pinfo->dma_addr) &&
+                       (val<(pinfo->dma_addr + pinfo->mem_size)))) {
                offset = val - (u32)pinfo->dma_addr;
                return (void*)(pinfo->mem_addr+offset);
        }
-       printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
+       /* something nasty happened */
+       BUG();
        return 0;
 }
 
index ced193b..969f949 100644 (file)
@@ -12,7 +12,8 @@
  *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *            (C) 2004 Intracom, S.A.
- *            (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
+ *            (C) 2005-2006 MontaVista Software, Inc.
+ *             Vitaly Bordug <vbordug@ru.mvista.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
@@ -81,7 +82,7 @@ early_uart_get_pdev(int index)
 }
 
 
-void cpm_uart_count(void)
+static void cpm_uart_count(void)
 {
        cpm_uart_nr = 0;
 #ifdef CONFIG_SERIAL_CPM_SMC1
@@ -104,6 +105,21 @@ void cpm_uart_count(void)
 #endif
 }
 
+/* Get UART number by its id */
+static int cpm_uart_id2nr(int id)
+{
+       int i;
+       if (id < UART_NR) {
+               for (i=0; i<UART_NR; i++) {
+                       if (cpm_uart_port_map[i] == id)
+                               return i;
+               }
+       }
+
+       /* not found or invalid argument */
+       return -1;
+}
+
 /*
  * Check, if transmit buffers are processed
 */
@@ -457,7 +473,11 @@ static void cpm_uart_shutdown(struct uart_port *port)
                }
 
                /* Shut them really down and reinit buffer descriptors */
-               cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+               if (IS_SMC(pinfo))
+                       cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+               else
+                       cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX);
+
                cpm_uart_initbd(pinfo);
        }
 }
@@ -1008,7 +1028,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
        int line;
        u32 mem, pram;
 
-       for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++);
+       line = cpm_uart_id2nr(idx);
+       if(line < 0) {
+               printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
+               return -1;
+       }
 
        pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
 
@@ -1241,8 +1265,7 @@ static int cpm_uart_drv_probe(struct device *dev)
        }
 
        pdata = pdev->dev.platform_data;
-       pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n",
-                       cpm_uart_port_map[pdata->fs_no]);
+       pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
 
        if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
                return ret;
@@ -1261,7 +1284,7 @@ static int cpm_uart_drv_remove(struct device *dev)
        struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
 
        pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
-                       cpm_uart_port_map[pdata->fs_no]);
+                       cpm_uart_id2nr(pdata->fs_no));
 
         uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
         return 0;
index a5a3062..17406a0 100644 (file)
@@ -8,6 +8,8 @@
  *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *            (C) 2004 Intracom, S.A.
+ *            (C) 2006 MontaVista Software, Inc.
+ *             Vitaly Bordug <vbordug@ru.mvista.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
index 7c6b07a..4b2de08 100644 (file)
@@ -8,6 +8,8 @@
  * 
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *            (C) 2004 Intracom, S.A.
+ *            (C) 2006 MontaVista Software, Inc.
+ *             Vitaly Bordug <vbordug@ru.mvista.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
index c3b7a66..d202eb4 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hardware.h>
+#include <asm/arch/imx-uart.h>
 
 /* We've been assigned a range on the "Low-density serial ports" major */
 #define SERIAL_IMX_MAJOR       204
@@ -73,7 +74,8 @@ struct imx_port {
        struct uart_port        port;
        struct timer_list       timer;
        unsigned int            old_status;
-       int txirq,rxirq,rtsirq;
+       int                     txirq,rxirq,rtsirq;
+       int                     have_rtscts:1;
 };
 
 /*
@@ -491,8 +493,12 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
                ucr2 = UCR2_SRST | UCR2_IRTS;
 
        if (termios->c_cflag & CRTSCTS) {
-               ucr2 &= ~UCR2_IRTS;
-               ucr2 |= UCR2_CTSC;
+               if( sport->have_rtscts ) {
+                       ucr2 &= ~UCR2_IRTS;
+                       ucr2 |= UCR2_CTSC;
+               } else {
+                       termios->c_cflag &= ~CRTSCTS;
+               }
        }
 
        if (termios->c_cflag & CSTOPB)
@@ -719,27 +725,6 @@ static void __init imx_init_ports(void)
                imx_ports[i].timer.function = imx_timeout;
                imx_ports[i].timer.data     = (unsigned long)&imx_ports[i];
        }
-
-       imx_gpio_mode(PC9_PF_UART1_CTS);
-       imx_gpio_mode(PC10_PF_UART1_RTS);
-       imx_gpio_mode(PC11_PF_UART1_TXD);
-       imx_gpio_mode(PC12_PF_UART1_RXD);
-       imx_gpio_mode(PB28_PF_UART2_CTS);
-       imx_gpio_mode(PB29_PF_UART2_RTS);
-
-       imx_gpio_mode(PB30_PF_UART2_TXD);
-       imx_gpio_mode(PB31_PF_UART2_RXD);
-
-#if 0 /* We don't need these, on the mx1 the _modem_ side of the uart
-       * is implemented.
-       */
-       imx_gpio_mode(PD7_AF_UART2_DTR);
-       imx_gpio_mode(PD8_AF_UART2_DCD);
-       imx_gpio_mode(PD9_AF_UART2_RI);
-       imx_gpio_mode(PD10_AF_UART2_DSR);
-#endif
-
-
 }
 
 #ifdef CONFIG_SERIAL_IMX_CONSOLE
@@ -932,7 +917,14 @@ static int serial_imx_resume(struct platform_device *dev)
 
 static int serial_imx_probe(struct platform_device *dev)
 {
+       struct imxuart_platform_data *pdata;
+
        imx_ports[dev->id].port.dev = &dev->dev;
+
+       pdata = (struct imxuart_platform_data *)dev->dev.platform_data;
+       if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
+               imx_ports[dev->id].have_rtscts = 1;
+
        uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
        platform_set_drvdata(dev, &imx_ports[dev->id]);
        return 0;
index fcd7744..aeb8153 100644 (file)
@@ -1500,20 +1500,18 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
 static struct uart_state *uart_get(struct uart_driver *drv, int line)
 {
        struct uart_state *state;
+       int ret = 0;
 
-       mutex_lock(&port_mutex);
        state = drv->state + line;
        if (mutex_lock_interruptible(&state->mutex)) {
-               state = ERR_PTR(-ERESTARTSYS);
-               goto out;
+               ret = -ERESTARTSYS;
+               goto err;
        }
 
        state->count++;
-       if (!state->port) {
-               state->count--;
-               mutex_unlock(&state->mutex);
-               state = ERR_PTR(-ENXIO);
-               goto out;
+       if (!state->port || state->port->flags & UPF_DEAD) {
+               ret = -ENXIO;
+               goto err_unlock;
        }
 
        if (!state->info) {
@@ -1531,15 +1529,17 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
                        tasklet_init(&state->info->tlet, uart_tasklet_action,
                                     (unsigned long)state);
                } else {
-                       state->count--;
-                       mutex_unlock(&state->mutex);
-                       state = ERR_PTR(-ENOMEM);
+                       ret = -ENOMEM;
+                       goto err_unlock;
                }
        }
-
- out:
-       mutex_unlock(&port_mutex);
        return state;
+
+ err_unlock:
+       state->count--;
+       mutex_unlock(&state->mutex);
+ err:
+       return ERR_PTR(ret);
 }
 
 /*
@@ -2085,45 +2085,6 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
        }
 }
 
-/*
- * This reverses the effects of uart_configure_port, hanging up the
- * port before removal.
- */
-static void
-uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
-{
-       struct uart_port *port = state->port;
-       struct uart_info *info = state->info;
-
-       if (info && info->tty)
-               tty_vhangup(info->tty);
-
-       mutex_lock(&state->mutex);
-
-       state->info = NULL;
-
-       /*
-        * Free the port IO and memory resources, if any.
-        */
-       if (port->type != PORT_UNKNOWN)
-               port->ops->release_port(port);
-
-       /*
-        * Indicate that there isn't a port here anymore.
-        */
-       port->type = PORT_UNKNOWN;
-
-       /*
-        * Kill the tasklet, and free resources.
-        */
-       if (info) {
-               tasklet_kill(&info->tlet);
-               kfree(info);
-       }
-
-       mutex_unlock(&state->mutex);
-}
-
 static struct tty_operations uart_ops = {
        .open           = uart_open,
        .close          = uart_close,
@@ -2270,6 +2231,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
        state = drv->state + port->line;
 
        mutex_lock(&port_mutex);
+       mutex_lock(&state->mutex);
        if (state->port) {
                ret = -EINVAL;
                goto out;
@@ -2304,7 +2266,13 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
            port->cons && !(port->cons->flags & CON_ENABLED))
                register_console(port->cons);
 
+       /*
+        * Ensure UPF_DEAD is not set.
+        */
+       port->flags &= ~UPF_DEAD;
+
  out:
+       mutex_unlock(&state->mutex);
        mutex_unlock(&port_mutex);
 
        return ret;
@@ -2322,6 +2290,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
 int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
 {
        struct uart_state *state = drv->state + port->line;
+       struct uart_info *info;
 
        BUG_ON(in_interrupt());
 
@@ -2332,11 +2301,48 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
        mutex_lock(&port_mutex);
 
        /*
+        * Mark the port "dead" - this prevents any opens from
+        * succeeding while we shut down the port.
+        */
+       mutex_lock(&state->mutex);
+       port->flags |= UPF_DEAD;
+       mutex_unlock(&state->mutex);
+
+       /*
         * Remove the devices from devfs
         */
        tty_unregister_device(drv->tty_driver, port->line);
 
-       uart_unconfigure_port(drv, state);
+       info = state->info;
+       if (info && info->tty)
+               tty_vhangup(info->tty);
+
+       /*
+        * All users of this port should now be disconnected from
+        * this driver, and the port shut down.  We should be the
+        * only thread fiddling with this port from now on.
+        */
+       state->info = NULL;
+
+       /*
+        * Free the port IO and memory resources, if any.
+        */
+       if (port->type != PORT_UNKNOWN)
+               port->ops->release_port(port);
+
+       /*
+        * Indicate that there isn't a port here anymore.
+        */
+       port->type = PORT_UNKNOWN;
+
+       /*
+        * Kill the tasklet, and free resources.
+        */
+       if (info) {
+               tasklet_kill(&info->tlet);
+               kfree(info);
+       }
+
        state->port = NULL;
        mutex_unlock(&port_mutex);
 
index 67140a5..cdeff90 100644 (file)
@@ -310,7 +310,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
        pci_set_drvdata(idd->idd_pdev, idd);
 
        mutex_lock(&ioc4_mutex);
-       list_add(&idd->idd_list, &ioc4_devices);
+       list_add_tail(&idd->idd_list, &ioc4_devices);
 
        /* Add this IOC4 to all submodules */
        list_for_each_entry(is, &ioc4_submodules, is_list) {
index 7860c8a..956b7a1 100644 (file)
@@ -69,7 +69,7 @@ static const char speedtch_driver_name[] = "speedtch";
 #define RESUBMIT_DELAY         1000    /* milliseconds */
 
 #define DEFAULT_BULK_ALTSETTING        1
-#define DEFAULT_ISOC_ALTSETTING        2
+#define DEFAULT_ISOC_ALTSETTING        3
 #define DEFAULT_DL_512_FIRST   0
 #define DEFAULT_ENABLE_ISOC    0
 #define DEFAULT_SW_BUFFERING   0
index c1211fc..5462498 100644 (file)
@@ -99,11 +99,11 @@ static const char usbatm_driver_name[] = "usbatm";
 
 #define UDSL_MAX_RCV_URBS              16
 #define UDSL_MAX_SND_URBS              16
-#define UDSL_MAX_BUF_SIZE              64 * 1024       /* bytes */
+#define UDSL_MAX_BUF_SIZE              65536
 #define UDSL_DEFAULT_RCV_URBS          4
 #define UDSL_DEFAULT_SND_URBS          4
-#define UDSL_DEFAULT_RCV_BUF_SIZE      64 * ATM_CELL_SIZE      /* bytes */
-#define UDSL_DEFAULT_SND_BUF_SIZE      64 * ATM_CELL_SIZE      /* bytes */
+#define UDSL_DEFAULT_RCV_BUF_SIZE      3392    /* 64 * ATM_CELL_SIZE */
+#define UDSL_DEFAULT_SND_BUF_SIZE      3392    /* 64 * ATM_CELL_SIZE */
 
 #define ATM_CELL_HEADER                        (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
 
@@ -135,7 +135,7 @@ MODULE_PARM_DESC(rcv_buf_bytes,
 module_param(snd_buf_bytes, uint, S_IRUGO);
 MODULE_PARM_DESC(snd_buf_bytes,
                 "Size of the buffers used for transmission, in bytes (range: 1-"
-                __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
+                __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: "
                 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
 
 
index fbd938d..e2e00ba 100644 (file)
@@ -1805,6 +1805,12 @@ int usb_add_hcd(struct usb_hcd *hcd,
                        USB_SPEED_FULL;
        hcd->self.root_hub = rhdev;
 
+       /* wakeup flag init defaults to "everything works" for root hubs,
+        * but drivers can override it in reset() if needed, along with
+        * recording the overall controller's system wakeup capability.
+        */
+       device_init_wakeup(&rhdev->dev, 1);
+
        /* "reset" is misnamed; its role is now one-time init. the controller
         * should already have been reset (and boot firmware kicked off etc).
         */
@@ -1813,13 +1819,6 @@ int usb_add_hcd(struct usb_hcd *hcd,
                goto err_hcd_driver_setup;
        }
 
-       /* wakeup flag init is in transition; for now we can't rely on PCI to
-        * initialize these bits properly, so we let reset() override it.
-        * This init should _precede_ the reset() once PCI behaves.
-        */
-       device_init_wakeup(&rhdev->dev,
-                       device_can_wakeup(hcd->self.controller));
-
        /* NOTE: root hub and controller capabilities may not be the same */
        if (device_can_wakeup(hcd->self.controller)
                        && device_can_wakeup(&hcd->self.root_hub->dev))
index 0c87f73..90b8d43 100644 (file)
@@ -1168,19 +1168,9 @@ static inline const char *plural(int n)
 static int choose_configuration(struct usb_device *udev)
 {
        int i;
-       u16 devstatus;
-       int bus_powered;
        int num_configs;
        struct usb_host_config *c, *best;
 
-       /* If this fails, assume the device is bus-powered */
-       devstatus = 0;
-       usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
-       le16_to_cpus(&devstatus);
-       bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0);
-       dev_dbg(&udev->dev, "device is %s-powered\n",
-                       bus_powered ? "bus" : "self");
-
        best = NULL;
        c = udev->config;
        num_configs = udev->descriptor.bNumConfigurations;
@@ -1197,6 +1187,19 @@ static int choose_configuration(struct usb_device *udev)
                 * similar errors in their descriptors.  If the next test
                 * were allowed to execute, such configurations would always
                 * be rejected and the devices would not work as expected.
+                * In the meantime, we run the risk of selecting a config
+                * that requires external power at a time when that power
+                * isn't available.  It seems to be the lesser of two evils.
+                *
+                * Bugzilla #6448 reports a device that appears to crash
+                * when it receives a GET_DEVICE_STATUS request!  We don't
+                * have any other way to tell whether a device is self-powered,
+                * but since we don't use that information anywhere but here,
+                * the call has been removed.
+                *
+                * Maybe the GET_DEVICE_STATUS call and the test below can
+                * be reinstated when device firmwares become more reliable.
+                * Don't hold your breath.
                 */
 #if 0
                /* Rule out self-powered configs for a bus-powered device */
index 544f758..73f5a37 100644 (file)
@@ -863,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
                i = ohci->num_ports;
                while (i--)
                        ohci_writel (ohci, RH_PS_PSS,
-                               &ohci->regs->roothub.portstatus [temp]);
+                               &ohci->regs->roothub.portstatus [i]);
                ohci_dbg (ohci, "restart complete\n");
        }
        return 0;
index f419bd8..435273e 100644 (file)
@@ -1557,6 +1557,9 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_VENDOR_ID_HP               0x03f0
 #define USB_DEVICE_ID_HP_USBHUB_KB     0x020c
 
+#define USB_VENDOR_ID_IBM              0x04b3
+#define USB_DEVICE_ID_IBM_USBHUB_KB    0x3005
+
 #define USB_VENDOR_ID_CREATIVELABS     0x062a
 #define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201
 
@@ -1681,6 +1684,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
        { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_USBHUB_KB, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET },
index 3824df3..1fd9cb8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/delay.h>
 
 #define MAX_INTEL_HEX_RECORD_LENGTH 16
 typedef struct _INTEL_HEX_RECORD
@@ -114,6 +115,7 @@ static int emi26_load_firmware (struct usb_device *dev)
 
        /* De-assert reset (let the CPU run) */
        err = emi26_set_reset(dev,0);
+       msleep(250);    /* let device settle */
 
        /* 2. We upload the FPGA firmware into the EMI
         * Note: collect up to 1023 (yes!) bytes and send them with
@@ -150,6 +152,7 @@ static int emi26_load_firmware (struct usb_device *dev)
                        goto wraperr;
                }
        }
+       msleep(250);    /* let device settle */
 
        /* De-assert reset (let the CPU run) */
        err = emi26_set_reset(dev,0);
@@ -192,6 +195,7 @@ static int emi26_load_firmware (struct usb_device *dev)
                err("%s - error loading firmware: error = %d", __FUNCTION__, err);
                goto wraperr;
        }
+       msleep(250);    /* let device settle */
 
        /* return 1 to fail the driver inialization
         * and give real driver change to load */
index 52fea2e..fe35137 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/delay.h>
 
 #define MAX_INTEL_HEX_RECORD_LENGTH 16
 typedef struct _INTEL_HEX_RECORD
@@ -123,6 +124,7 @@ static int emi62_load_firmware (struct usb_device *dev)
 
        /* De-assert reset (let the CPU run) */
        err = emi62_set_reset(dev,0);
+       msleep(250);    /* let device settle */
 
        /* 2. We upload the FPGA firmware into the EMI
         * Note: collect up to 1023 (yes!) bytes and send them with
@@ -166,6 +168,7 @@ static int emi62_load_firmware (struct usb_device *dev)
                err("%s - error loading firmware: error = %d", __FUNCTION__, err);
                goto wraperr;
        }
+       msleep(250);    /* let device settle */
 
        /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
 
@@ -228,6 +231,7 @@ static int emi62_load_firmware (struct usb_device *dev)
                err("%s - error loading firmware: error = %d", __FUNCTION__, err);
                goto wraperr;
        }
+       msleep(250);    /* let device settle */
 
        kfree(buf);
 
index 2deb4c0..7683926 100644 (file)
@@ -318,6 +318,8 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
        set_register(pegasus, PhyCtrl, (indx | PHY_READ));
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, PhyCtrl, 1, data);
+               if (ret == -ESHUTDOWN)
+                       goto fail;
                if (data[0] & PHY_DONE)
                        break;
        }
@@ -326,6 +328,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
                *regd = le16_to_cpu(regdi);
                return ret;
        }
+fail:
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
 
@@ -354,12 +357,15 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
        set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, PhyCtrl, 1, data);
+               if (ret == -ESHUTDOWN)
+                       goto fail;
                if (data[0] & PHY_DONE)
                        break;
        }
        if (i < REG_TIMEOUT)
                return ret;
 
+fail:
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
        return -ETIMEDOUT;
@@ -387,6 +393,8 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
                ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
                if (tmp & EPROM_DONE)
                        break;
+               if (ret == -ESHUTDOWN)
+                       goto fail;
        }
        if (i < REG_TIMEOUT) {
                ret = get_registers(pegasus, EpromData, 2, &retdatai);
@@ -394,6 +402,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
                return ret;
        }
 
+fail:
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
        return -ETIMEDOUT;
@@ -433,12 +442,15 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
 
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
+               if (ret == -ESHUTDOWN)
+                       goto fail;
                if (tmp & EPROM_DONE)
                        break;
        }
        disable_eprom_write(pegasus);
        if (i < REG_TIMEOUT)
                return ret;
+fail:
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
        return -ETIMEDOUT;
@@ -1378,9 +1390,8 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
        struct pegasus *pegasus = usb_get_intfdata(intf);
        
        netif_device_detach (pegasus->net);
+       cancel_delayed_work(&pegasus->carrier_check);
        if (netif_running(pegasus->net)) {
-               cancel_delayed_work(&pegasus->carrier_check);
-
                usb_kill_urb(pegasus->rx_urb);
                usb_kill_urb(pegasus->intr_urb);
        }
@@ -1400,10 +1411,9 @@ static int pegasus_resume (struct usb_interface *intf)
                pegasus->intr_urb->status = 0;
                pegasus->intr_urb->actual_length = 0;
                intr_callback(pegasus->intr_urb, NULL);
-
-               queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
-                                       CARRIER_CHECK_DELAY);
        }
+       queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
+                               CARRIER_CHECK_DELAY);
        return 0;
 }
 
index f96b73f..5c60be5 100644 (file)
@@ -71,6 +71,16 @@ config USB_SERIAL_ANYDATA
          To compile this driver as a module, choose M here: the
          module will be called anydata.
 
+config USB_SERIAL_ARK3116
+       tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)"
+       depends on USB_SERIAL && EXPERIMENTAL
+       help
+         Say Y here if you want to use a ARK Micro 3116 USB to Serial
+         device.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ark3116
+
 config USB_SERIAL_BELKIN
        tristate "USB Belkin and Peracom Single Port Serial Driver"
        depends on USB_SERIAL
index 93c2124..5a0960f 100644 (file)
@@ -13,6 +13,7 @@ usbserial-objs        := usb-serial.o generic.o bus.o $(usbserial-obj-y)
 
 obj-$(CONFIG_USB_SERIAL_AIRPRIME)              += airprime.o
 obj-$(CONFIG_USB_SERIAL_ANYDATA)               += anydata.o
+obj-$(CONFIG_USB_SERIAL_ARK3116)               += ark3116.o
 obj-$(CONFIG_USB_SERIAL_BELKIN)                        += belkin_sa.o
 obj-$(CONFIG_USB_SERIAL_CP2101)                        += cp2101.o
 obj-$(CONFIG_USB_SERIAL_CYBERJACK)             += cyberjack.o
index dbf1f06..694b205 100644 (file)
@@ -18,6 +18,7 @@
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(0xf3d, 0x0112) },  /* AirPrime CDMA Wireless PC Card */
        { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
+       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
new file mode 100644 (file)
index 0000000..8dec796
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * ark3116
+ * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547,
+ *   productid=0x0232) (used in a datacable called KQ-U8A)
+ *
+ * - based on code by krisfx -> thanks !!
+ *   (see http://www.linuxquestions.org/questions/showthread.php?p=2184457#post2184457)
+ *
+ *  - based on logs created by usbsnoopy
+ *
+ *  Author   : Simon Schulz [ark3116_driver<AT>auctionant.de]
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+
+static int debug;
+
+static struct usb_device_id id_table [] = {
+       { USB_DEVICE(0x6547, 0x0232) },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+struct ark3116_private {
+       spinlock_t lock;
+       u8 termios_initialized;
+};
+
+static inline void ARK3116_SND(struct usb_serial *serial, int seq,
+                              __u8 request, __u8 requesttype,
+                              __u16 value, __u16 index)
+{
+       int result;
+       result = usb_control_msg(serial->dev,
+                                usb_sndctrlpipe(serial->dev,0),
+                                request, requesttype, value, index,
+                                NULL,0x00, 1000);
+       dbg("%03d > ok",seq);
+}
+
+static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
+                              __u8 request, __u8 requesttype,
+                              __u16 value, __u16 index, __u8 expected,
+                              char *buf)
+{
+       int result;
+       result = usb_control_msg(serial->dev,
+                             usb_rcvctrlpipe(serial->dev,0),
+                             request, requesttype, value, index,
+                             buf, 0x0000001, 1000);
+       if (result)
+               dbg("%03d < %d bytes [0x%02X]",seq, result, buf[0]);
+       else
+               dbg("%03d < 0 bytes", seq);
+}
+
+
+static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
+                                    __u8 request, __u8 requesttype,
+                                    __u16 value, __u16 index, char *buf)
+{
+       usb_control_msg(serial->dev,
+                       usb_rcvctrlpipe(serial->dev,0),
+                       request, requesttype, value, index,
+                       buf, 0x0000001, 1000);
+}
+
+
+static int ark3116_attach(struct usb_serial *serial)
+{
+       char *buf;
+       struct ark3116_private *priv;
+       int i;
+
+       for (i = 0; i < serial->num_ports; ++i) {
+               priv = kmalloc (sizeof (struct ark3116_private), GFP_KERNEL);
+               if (!priv)
+                       goto cleanup;
+               memset (priv, 0x00, sizeof (struct ark3116_private));
+               spin_lock_init(&priv->lock);
+
+               usb_set_serial_port_data(serial->port[i], priv);
+       }
+
+       buf = kmalloc(1, GFP_KERNEL);
+       if (!buf) {
+               dbg("error kmalloc -> out of mem ?");
+               goto cleanup;
+       }
+
+       /* 3 */
+       ARK3116_SND(serial, 3,0xFE,0x40,0x0008,0x0002);
+       ARK3116_SND(serial, 4,0xFE,0x40,0x0008,0x0001);
+       ARK3116_SND(serial, 5,0xFE,0x40,0x0000,0x0008);
+       ARK3116_SND(serial, 6,0xFE,0x40,0x0000,0x000B);
+
+       /* <-- seq7 */
+       ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, 0x00, buf);
+       ARK3116_SND(serial, 8,0xFE,0x40,0x0080,0x0003);
+       ARK3116_SND(serial, 9,0xFE,0x40,0x001A,0x0000);
+       ARK3116_SND(serial,10,0xFE,0x40,0x0000,0x0001);
+       ARK3116_SND(serial,11,0xFE,0x40,0x0000,0x0003);
+
+       /* <-- seq12 */
+       ARK3116_RCV(serial,12,0xFE,0xC0,0x0000,0x0004, 0x00, buf);
+       ARK3116_SND(serial,13,0xFE,0x40,0x0000,0x0004);
+
+       /* 14 */
+       ARK3116_RCV(serial,14,0xFE,0xC0,0x0000,0x0004, 0x00, buf);
+       ARK3116_SND(serial,15,0xFE,0x40,0x0000,0x0004);
+
+       /* 16 */
+       ARK3116_RCV(serial,16,0xFE,0xC0,0x0000,0x0004, 0x00, buf);
+       /* --> seq17 */
+       ARK3116_SND(serial,17,0xFE,0x40,0x0001,0x0004);
+
+       /* <-- seq18 */
+       ARK3116_RCV(serial,18,0xFE,0xC0,0x0000,0x0004, 0x01, buf);
+
+       /* --> seq19 */
+       ARK3116_SND(serial,19,0xFE,0x40,0x0003,0x0004);
+
+
+       /* <-- seq20 */
+       /* seems like serial port status info (RTS, CTS,...) */
+       /* returns modem control line status ?! */
+       ARK3116_RCV(serial,20,0xFE,0xC0,0x0000,0x0006, 0xFF, buf);
+
+       /* set 9600 baud & do some init ?! */
+       ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003);
+       ARK3116_SND(serial,148,0xFE,0x40,0x0038,0x0000);
+       ARK3116_SND(serial,149,0xFE,0x40,0x0001,0x0001);
+       ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003);
+       ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf);
+       ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003);
+       ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf);
+       ARK3116_SND(serial,154,0xFE,0x40,0x0003,0x0003);
+
+       kfree(buf);
+       return(0);
+
+cleanup:
+       for (--i; i>=0; --i)
+               usb_set_serial_port_data(serial->port[i], NULL);
+       return -ENOMEM;
+}
+
+static void ark3116_set_termios(struct usb_serial_port *port,
+                               struct termios *old_termios)
+{
+       struct usb_serial *serial = port->serial;
+       struct ark3116_private *priv = usb_get_serial_port_data(port);
+       unsigned int cflag = port->tty->termios->c_cflag;
+       unsigned long flags;
+       int baud;
+       int ark3116_baud;
+       char *buf;
+       char config;
+
+       config = 0;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       if ((!port->tty) || (!port->tty->termios)) {
+               dbg("%s - no tty structures", __FUNCTION__);
+               return;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (!priv->termios_initialized) {
+               *(port->tty->termios) = tty_std_termios;
+               port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+               priv->termios_initialized = 1;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       cflag = port->tty->termios->c_cflag;
+
+       /* check that they really want us to change something: */
+       if (old_termios) {
+               if ((cflag == old_termios->c_cflag) &&
+                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) ==
+                    RELEVANT_IFLAG(old_termios->c_iflag))) {
+                       dbg("%s - nothing to change...", __FUNCTION__);
+                       return;
+               }
+       }
+
+       buf = kmalloc(1, GFP_KERNEL);
+       if (!buf) {
+               dbg("error kmalloc");
+               return;
+       }
+
+       /* set data bit count (8/7/6/5) */
+       if (cflag & CSIZE){
+               switch (cflag & CSIZE){
+               case CS5:
+                       config |= 0x00;
+                       dbg("setting CS5");
+                       break;
+               case CS6:
+                       config |= 0x01;
+                       dbg("setting CS6");
+                       break;
+               case CS7:
+                       config |= 0x02;
+                       dbg("setting CS7");
+                       break;
+               default:
+                       err ("CSIZE was set but not CS5-CS8, using CS8!");
+               case CS8:
+                       config |= 0x03;
+                       dbg("setting CS8");
+                       break;
+               }
+       }
+
+       /* set parity (NONE,EVEN,ODD) */
+       if (cflag & PARENB){
+               if (cflag & PARODD) {
+                       config |= 0x08;
+                       dbg("setting parity to ODD");
+               } else {
+                       config |= 0x18;
+                       dbg("setting parity to EVEN");
+               }
+       } else {
+               dbg("setting parity to NONE");
+       }
+
+       /* SET STOPBIT (1/2) */
+       if (cflag & CSTOPB) {
+               config |= 0x04;
+               dbg ("setting 2 stop bits");
+       } else {
+               dbg ("setting 1 stop bit");
+       }
+
+
+       /* set baudrate: */
+       baud = 0;
+       switch (cflag & CBAUD){
+               case B0:
+                       err("can't set 0baud, using 9600 instead");
+                       break;
+               case B75:       baud = 75;      break;
+               case B150:      baud = 150;     break;
+               case B300:      baud = 300;     break;
+               case B600:      baud = 600;     break;
+               case B1200:     baud = 1200;    break;
+               case B1800:     baud = 1800;    break;
+               case B2400:     baud = 2400;    break;
+               case B4800:     baud = 4800;    break;
+               case B9600:     baud = 9600;    break;
+               case B19200:    baud = 19200;   break;
+               case B38400:    baud = 38400;   break;
+               case B57600:    baud = 57600;   break;
+               case B115200:   baud = 115200;  break;
+               case B230400:   baud = 230400;  break;
+               case B460800:   baud = 460800;  break;
+               default:
+                       dbg("does not support the baudrate requested (fix it)");
+                       break;
+       }
+
+       /* set 9600 as default (if given baudrate is invalid for example) */
+       if (baud == 0)
+               baud = 9600;
+
+       /*
+        * found by try'n'error, be careful, maybe there are other options
+        * for multiplicator etc!
+        */
+       if (baud == 460800)
+               /* strange, for 460800 the formula is wrong
+                * (dont use round(), then 9600baud is wrong) */
+               ark3116_baud = 7;
+       else
+               ark3116_baud = 3000000 / baud;
+
+       /* ? */
+       ARK3116_RCV(serial,0,0xFE,0xC0,0x0000,0x0003, 0x03, buf);
+       /* offset = buf[0]; */
+       /* offset = 0x03; */
+       /* dbg("using 0x%04X as target for 0x0003:",0x0080+offset); */
+
+
+       /* set baudrate */
+       dbg("setting baudrate to %d (->reg=%d)",baud,ark3116_baud);
+       ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003);
+       ARK3116_SND(serial,148,0xFE,0x40,(ark3116_baud & 0x00FF)   ,0x0000);
+       ARK3116_SND(serial,149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001);
+       ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003);
+
+       /* ? */
+       ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf);
+       ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003);
+
+       /* set data bit count, stop bit count & parity: */
+       dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config);
+       ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf);
+       ARK3116_SND(serial,154,0xFE,0x40,config,0x0003);
+
+       if (cflag & CRTSCTS)
+               dbg("CRTSCTS not supported by chipset ?!");
+
+       /* TEST ARK3116_SND(154,0xFE,0x40,0xFFFF, 0x0006); */
+
+       kfree(buf);
+       return;
+}
+
+static int ark3116_open(struct usb_serial_port *port, struct file *filp)
+{
+       struct termios tmp_termios;
+       struct usb_serial *serial = port->serial;
+       char *buf;
+       int result = 0;
+
+       dbg("%s -  port %d", __FUNCTION__, port->number);
+
+       buf = kmalloc(1, GFP_KERNEL);
+       if (!buf) {
+               dbg("error kmalloc -> out of mem ?");
+               return -ENOMEM;
+       }
+
+       result = usb_serial_generic_open(port, filp);
+       if (result)
+               return result;
+
+       /* open */
+       ARK3116_RCV(serial,111,0xFE,0xC0,0x0000,0x0003, 0x02, buf);
+
+       ARK3116_SND(serial,112,0xFE,0x40,0x0082,0x0003);
+       ARK3116_SND(serial,113,0xFE,0x40,0x001A,0x0000);
+       ARK3116_SND(serial,114,0xFE,0x40,0x0000,0x0001);
+       ARK3116_SND(serial,115,0xFE,0x40,0x0002,0x0003);
+
+       ARK3116_RCV(serial,116,0xFE,0xC0,0x0000,0x0004, 0x03, buf);
+       ARK3116_SND(serial,117,0xFE,0x40,0x0002,0x0004);
+
+       ARK3116_RCV(serial,118,0xFE,0xC0,0x0000,0x0004, 0x02, buf);
+       ARK3116_SND(serial,119,0xFE,0x40,0x0000,0x0004);
+
+       ARK3116_RCV(serial,120,0xFE,0xC0,0x0000,0x0004, 0x00, buf);
+
+       ARK3116_SND(serial,121,0xFE,0x40,0x0001,0x0004);
+
+       ARK3116_RCV(serial,122,0xFE,0xC0,0x0000,0x0004, 0x01, buf);
+
+       ARK3116_SND(serial,123,0xFE,0x40,0x0003,0x0004);
+
+       /* returns different values (control lines ?!) */
+       ARK3116_RCV(serial,124,0xFE,0xC0,0x0000,0x0006, 0xFF, buf);
+
+       /* initialise termios: */
+       if (port->tty)
+               ark3116_set_termios(port, &tmp_termios);
+
+       kfree(buf);
+
+       return result;
+
+}
+
+static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+       dbg("ioctl not supported yet...");
+       return -ENOIOCTLCMD;
+}
+
+static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+       struct usb_serial *serial = port->serial;
+       char *buf;
+       char temp;
+
+       /* seems like serial port status info (RTS, CTS,...) is stored
+        * in reg(?) 0x0006
+        * pcb connection point 11 = GND -> sets bit4 of response
+        * pcb connection point  7 = GND -> sets bit6 of response
+        */
+
+       buf = kmalloc(1, GFP_KERNEL);
+       if (!buf) {
+               dbg("error kmalloc");
+               return -ENOMEM;
+       }
+
+       /* read register: */
+       ARK3116_RCV_QUIET(serial,0xFE,0xC0,0x0000,0x0006,buf);
+       temp = buf[0];
+       kfree(buf);
+
+       /* i do not really know if bit4=CTS and bit6=DSR... was just a
+        * quick guess !!
+        */
+       return  (temp & (1<<4) ? TIOCM_CTS : 0) |
+               (temp & (1<<6) ? TIOCM_DSR : 0);
+}
+
+static struct usb_driver ark3116_driver = {
+       .name =         "ark3116",
+       .probe =        usb_serial_probe,
+       .disconnect =   usb_serial_disconnect,
+       .id_table =     id_table,
+};
+
+static struct usb_serial_driver ark3116_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "ark3116",
+       },
+       .id_table =             id_table,
+       .num_interrupt_in =     1,
+       .num_bulk_in =          1,
+       .num_bulk_out =         1,
+       .num_ports =            1,
+       .attach =               ark3116_attach,
+       .set_termios =          ark3116_set_termios,
+       .ioctl =                ark3116_ioctl,
+       .tiocmget =             ark3116_tiocmget,
+       .open =                 ark3116_open,
+};
+
+static int __init ark3116_init(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&ark3116_device);
+       if (retval)
+               return retval;
+       retval = usb_register(&ark3116_driver);
+       if (retval)
+               usb_serial_deregister(&ark3116_device);
+       return retval;
+}
+
+static void __exit ark3116_exit(void)
+{
+       usb_deregister(&ark3116_driver);
+       usb_serial_deregister(&ark3116_device);
+}
+
+module_init(ark3116_init);
+module_exit(ark3116_exit);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
index 8215120..986d762 100644 (file)
@@ -307,6 +307,7 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
 
 
 static struct usb_device_id id_table_combined [] = {
+       { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
@@ -498,6 +499,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) },
        { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) },
        { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 2c55a5e..d69a917 100644 (file)
 #define FTDI_NF_RIC_PID        0x0001  /* Product Id */
 
 
+/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */
+#define FTDI_ACTZWAVE_PID      0xF2D0
+
+
 /* www.irtrans.de device */
 #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
 
 #define PAPOUCH_VID                    0x5050  /* Vendor ID */
 #define PAPOUCH_TMU_PID                        0x0400  /* TMU USB Thermometer */
 
+/*
+ * ACG Identification Technologies GmbH products (http://www.acg.de/).
+ * Submitted by anton -at- goto10 -dot- org.
+ */
+#define FTDI_ACG_HFDUAL_PID            0xDD20  /* HF Dual ISO Reader (RFID) */
 
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
index 476cda1..c62cc28 100644 (file)
@@ -138,6 +138,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
 
        return result;
 }
+EXPORT_SYMBOL_GPL(usb_serial_generic_open);
 
 static void generic_cleanup (struct usb_serial_port *port)
 {
index 4d40704..238033a 100644 (file)
@@ -257,14 +257,14 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
                return (0);
        }
 
-       spin_lock(&port->lock);
-       if (port->write_urb_busy) {
-               spin_unlock(&port->lock);
+       spin_lock(&wport->lock);
+       if (wport->write_urb_busy) {
+               spin_unlock(&wport->lock);
                dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
-       port->write_urb_busy = 1;
-       spin_unlock(&port->lock);
+       wport->write_urb_busy = 1;
+       spin_unlock(&wport->lock);
 
        count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
 
@@ -283,7 +283,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
        wport->write_urb->dev = serial->dev;
        result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
        if (result) {
-               port->write_urb_busy = 0;
+               wport->write_urb_busy = 0;
                err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
        } else
                result = count;
index 071f86a..9c36f0e 100644 (file)
@@ -189,11 +189,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 
        portNumber = tty->index - serial->minor;
        port = serial->port[portNumber];
-       if (!port)
-               return -ENODEV;
+       if (!port) {
+               retval = -ENODEV;
+               goto bailout_kref_put;
+       }
 
-       if (mutex_lock_interruptible(&port->mutex))
-               return -ERESTARTSYS;
+       if (mutex_lock_interruptible(&port->mutex)) {
+               retval = -ERESTARTSYS;
+               goto bailout_kref_put;
+       }
         
        ++port->open_count;
 
@@ -209,7 +213,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
                 * safe because we are called with BKL held */
                if (!try_module_get(serial->type->driver.owner)) {
                        retval = -ENODEV;
-                       goto bailout_kref_put;
+                       goto bailout_mutex_unlock;
                }
 
                /* only call the device specific open if this 
@@ -224,10 +228,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 
 bailout_module_put:
        module_put(serial->type->driver.owner);
-bailout_kref_put:
-       kref_put(&serial->kref, destroy_serial);
+bailout_mutex_unlock:
        port->open_count = 0;
        mutex_unlock(&port->mutex);
+bailout_kref_put:
+       kref_put(&serial->kref, destroy_serial);
        return retval;
 }
 
index 334b1db..27597c5 100644 (file)
@@ -29,12 +29,15 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
 
 static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
 {
-       int rc = -ENXIO, power;
+       int rc = -ENXIO;
        char *endp;
        struct backlight_device *bd = to_backlight_device(cdev);
+       int power = simple_strtoul(buf, &endp, 0);
+       size_t size = endp - buf;
 
-       power = simple_strtoul(buf, &endp, 0);
-       if (*endp && !isspace(*endp))
+       if (*endp && isspace(*endp))
+               size++;
+       if (size != count)
                return -EINVAL;
 
        down(&bd->sem);
@@ -65,12 +68,15 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
 
 static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
 {
-       int rc = -ENXIO, brightness;
+       int rc = -ENXIO;
        char *endp;
        struct backlight_device *bd = to_backlight_device(cdev);
+       int brightness = simple_strtoul(buf, &endp, 0);
+       size_t size = endp - buf;
 
-       brightness = simple_strtoul(buf, &endp, 0);
-       if (*endp && !isspace(*endp))
+       if (*endp && isspace(*endp))
+               size++;
+       if (size != count)
                return -EINVAL;
 
        down(&bd->sem);
index 86908a6..bc8ab00 100644 (file)
@@ -31,12 +31,15 @@ static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
 
 static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count)
 {
-       int rc, power;
+       int rc = -ENXIO;
        char *endp;
        struct lcd_device *ld = to_lcd_device(cdev);
+       int power = simple_strtoul(buf, &endp, 0);
+       size_t size = endp - buf;
 
-       power = simple_strtoul(buf, &endp, 0);
-       if (*endp && !isspace(*endp))
+       if (*endp && isspace(*endp))
+               size++;
+       if (size != count)
                return -EINVAL;
 
        down(&ld->sem);
@@ -44,8 +47,7 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_
                pr_debug("lcd: set power to %d\n", power);
                ld->props->set_power(ld, power);
                rc = count;
-       } else
-               rc = -ENXIO;
+       }
        up(&ld->sem);
 
        return rc;
@@ -53,14 +55,12 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_
 
 static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
 {
-       int rc;
+       int rc = -ENXIO;
        struct lcd_device *ld = to_lcd_device(cdev);
 
        down(&ld->sem);
        if (likely(ld->props && ld->props->get_contrast))
                rc = sprintf(buf, "%d\n", ld->props->get_contrast(ld));
-       else
-               rc = -ENXIO;
        up(&ld->sem);
 
        return rc;
@@ -68,12 +68,15 @@ static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
 
 static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count)
 {
-       int rc, contrast;
+       int rc = -ENXIO;
        char *endp;
        struct lcd_device *ld = to_lcd_device(cdev);
+       int contrast = simple_strtoul(buf, &endp, 0);
+       size_t size = endp - buf;
 
-       contrast = simple_strtoul(buf, &endp, 0);
-       if (*endp && !isspace(*endp))
+       if (*endp && isspace(*endp))
+               size++;
+       if (size != count)
                return -EINVAL;
 
        down(&ld->sem);
@@ -81,8 +84,7 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si
                pr_debug("lcd: set contrast to %d\n", contrast);
                ld->props->set_contrast(ld, contrast);
                rc = count;
-       } else
-               rc = -ENXIO;
+       }
        up(&ld->sem);
 
        return rc;
@@ -90,14 +92,12 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si
 
 static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf)
 {
-       int rc;
+       int rc = -ENXIO;
        struct lcd_device *ld = to_lcd_device(cdev);
 
        down(&ld->sem);
        if (likely(ld->props))
                rc = sprintf(buf, "%d\n", ld->props->max_contrast);
-       else
-               rc = -ENXIO;
        up(&ld->sem);
 
        return rc;
index 4ef5cd1..b985dfa 100644 (file)
@@ -34,7 +34,7 @@ extra-y += $(call logo-cfiles,_clut224,ppm)
 extra-y += $(call logo-cfiles,_gray256,pgm)
 
 # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..."
-quiet_cmd_logo = LOGO  $@
+quiet_cmd_logo = LOGO    $@
        cmd_logo = scripts/pnmtologo \
                        -t $(patsubst $*_%,%,$(notdir $(basename $<))) \
                        -n $(notdir $(basename $<)) -o $@ $<
index 71742ba..6f26178 100644 (file)
@@ -98,23 +98,20 @@ v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
 static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc,
        struct v9fs_fcall *rc, int err)
 {
-       int fid;
+       int fid, id;
        struct v9fs_session_info *v9ses;
 
-       if (err)
-               return;
-
+       id = 0;
        fid = tc->params.tclunk.fid;
-       kfree(tc);
-
-       if (!rc)
-               return;
-
-       v9ses = a;
-       if (rc->id == RCLUNK)
-               v9fs_put_idpool(fid, &v9ses->fidpool);
+       if (rc)
+               id = rc->id;
 
+       kfree(tc);
        kfree(rc);
+       if (id == RCLUNK) {
+               v9ses = a;
+               v9fs_put_idpool(fid, &v9ses->fidpool);
+       }
 }
 
 /**
index 3e5b124..f4407eb 100644 (file)
@@ -50,15 +50,23 @@ enum {
        Wpending = 8,           /* can write */
 };
 
+enum {
+       None,
+       Flushing,
+       Flushed,
+};
+
 struct v9fs_mux_poll_task;
 
 struct v9fs_req {
+       spinlock_t lock;
        int tag;
        struct v9fs_fcall *tcall;
        struct v9fs_fcall *rcall;
        int err;
        v9fs_mux_req_callback cb;
        void *cba;
+       int flush;
        struct list_head req_list;
 };
 
@@ -96,8 +104,8 @@ struct v9fs_mux_poll_task {
 
 struct v9fs_mux_rpc {
        struct v9fs_mux_data *m;
-       struct v9fs_req *req;
        int err;
+       struct v9fs_fcall *tcall;
        struct v9fs_fcall *rcall;
        wait_queue_head_t wqueue;
 };
@@ -524,10 +532,9 @@ again:
 
 static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
 {
-       int ecode, tag;
+       int ecode;
        struct v9fs_str *ename;
 
-       tag = req->tag;
        if (!req->err && req->rcall->id == RERROR) {
                ecode = req->rcall->params.rerror.errno;
                ename = &req->rcall->params.rerror.error;
@@ -553,23 +560,6 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
                if (!req->err)
                        req->err = -EIO;
        }
-
-       if (req->err == ERREQFLUSH)
-               return;
-
-       if (req->cb) {
-               dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n",
-                       req->tcall, req->rcall);
-
-               (*req->cb) (req->cba, req->tcall, req->rcall, req->err);
-               req->cb = NULL;
-       } else
-               kfree(req->rcall);
-
-       v9fs_mux_put_tag(m, tag);
-
-       wake_up(&m->equeue);
-       kfree(req);
 }
 
 /**
@@ -669,17 +659,26 @@ static void v9fs_read_work(void *a)
                list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
                        if (rreq->tag == rcall->tag) {
                                req = rreq;
-                               req->rcall = rcall;
-                               list_del(&req->req_list);
-                               spin_unlock(&m->lock);
-                               process_request(m, req);
+                               if (req->flush != Flushing)
+                                       list_del(&req->req_list);
                                break;
                        }
-
                }
+               spin_unlock(&m->lock);
 
-               if (!req) {
-                       spin_unlock(&m->lock);
+               if (req) {
+                       req->rcall = rcall;
+                       process_request(m, req);
+
+                       if (req->flush != Flushing) {
+                               if (req->cb)
+                                       (*req->cb) (req, req->cba);
+                               else
+                                       kfree(req->rcall);
+
+                               wake_up(&m->equeue);
+                       }
+               } else {
                        if (err >= 0 && rcall->id != RFLUSH)
                                dprintk(DEBUG_ERROR,
                                        "unexpected response mux %p id %d tag %d\n",
@@ -746,7 +745,6 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
                return ERR_PTR(-ENOMEM);
 
        v9fs_set_tag(tc, n);
-
        if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) {
                char buf[150];
 
@@ -754,12 +752,14 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
                printk(KERN_NOTICE "<<< %p %s\n", m, buf);
        }
 
+       spin_lock_init(&req->lock);
        req->tag = n;
        req->tcall = tc;
        req->rcall = NULL;
        req->err = 0;
        req->cb = cb;
        req->cba = cba;
+       req->flush = None;
 
        spin_lock(&m->lock);
        list_add_tail(&req->req_list, &m->unsent_req_list);
@@ -776,72 +776,108 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
        return req;
 }
 
-static void v9fs_mux_flush_cb(void *a, struct v9fs_fcall *tc,
-                             struct v9fs_fcall *rc, int err)
+static void v9fs_mux_free_request(struct v9fs_mux_data *m, struct v9fs_req *req)
+{
+       v9fs_mux_put_tag(m, req->tag);
+       kfree(req);
+}
+
+static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a)
 {
        v9fs_mux_req_callback cb;
        int tag;
        struct v9fs_mux_data *m;
-       struct v9fs_req *req, *rptr;
+       struct v9fs_req *req, *rreq, *rptr;
 
        m = a;
-       dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, tc,
-               rc, err, tc->params.tflush.oldtag);
+       dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m,
+               freq->tcall, freq->rcall, freq->err,
+               freq->tcall->params.tflush.oldtag);
 
        spin_lock(&m->lock);
        cb = NULL;
-       tag = tc->params.tflush.oldtag;
-       list_for_each_entry_safe(req, rptr, &m->req_list, req_list) {
-               if (req->tag == tag) {
+       tag = freq->tcall->params.tflush.oldtag;
+       req = NULL;
+       list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
+               if (rreq->tag == tag) {
+                       req = rreq;
                        list_del(&req->req_list);
-                       if (req->cb) {
-                               cb = req->cb;
-                               req->cb = NULL;
-                               spin_unlock(&m->lock);
-                               (*cb) (req->cba, req->tcall, req->rcall,
-                                      req->err);
-                       }
-                       kfree(req);
-                       wake_up(&m->equeue);
                        break;
                }
        }
+       spin_unlock(&m->lock);
 
-       if (!cb)
-               spin_unlock(&m->lock);
+       if (req) {
+               spin_lock(&req->lock);
+               req->flush = Flushed;
+               spin_unlock(&req->lock);
+
+               if (req->cb)
+                       (*req->cb) (req, req->cba);
+               else
+                       kfree(req->rcall);
+
+               wake_up(&m->equeue);
+       }
 
-       v9fs_mux_put_tag(m, tag);
-       kfree(tc);
-       kfree(rc);
+       kfree(freq->tcall);
+       kfree(freq->rcall);
+       v9fs_mux_free_request(m, freq);
 }
 
-static void
+static int
 v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req)
 {
        struct v9fs_fcall *fc;
+       struct v9fs_req *rreq, *rptr;
 
        dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);
 
+       /* if a response was received for a request, do nothing */
+       spin_lock(&req->lock);
+       if (req->rcall || req->err) {
+               spin_unlock(&req->lock);
+               dprintk(DEBUG_MUX, "mux %p req %p response already received\n", m, req);
+               return 0;
+       }
+
+       req->flush = Flushing;
+       spin_unlock(&req->lock);
+
+       spin_lock(&m->lock);
+       /* if the request is not sent yet, just remove it from the list */
+       list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) {
+               if (rreq->tag == req->tag) {
+                       dprintk(DEBUG_MUX, "mux %p req %p request is not sent yet\n", m, req);
+                       list_del(&rreq->req_list);
+                       req->flush = Flushed;
+                       spin_unlock(&m->lock);
+                       if (req->cb)
+                               (*req->cb) (req, req->cba);
+                       return 0;
+               }
+       }
+       spin_unlock(&m->lock);
+
+       clear_thread_flag(TIF_SIGPENDING);
        fc = v9fs_create_tflush(req->tag);
        v9fs_send_request(m, fc, v9fs_mux_flush_cb, m);
+       return 1;
 }
 
 static void
-v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err)
+v9fs_mux_rpc_cb(struct v9fs_req *req, void *a)
 {
        struct v9fs_mux_rpc *r;
 
-       if (err == ERREQFLUSH) {
-               kfree(rc);
-               dprintk(DEBUG_MUX, "err req flush\n");
-               return;
-       }
-
+       dprintk(DEBUG_MUX, "req %p r %p\n", req, a);
        r = a;
-       dprintk(DEBUG_MUX, "mux %p req %p tc %p rc %p err %d\n", r->m, r->req,
-               tc, rc, err);
-       r->rcall = rc;
-       r->err = err;
+       r->rcall = req->rcall;
+       r->err = req->err;
+
+       if (req->flush!=None && !req->err)
+               r->err = -ERESTARTSYS;
+
        wake_up(&r->wqueue);
 }
 
@@ -856,12 +892,13 @@ int
 v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
             struct v9fs_fcall **rc)
 {
-       int err;
+       int err, sigpending;
        unsigned long flags;
        struct v9fs_req *req;
        struct v9fs_mux_rpc r;
 
        r.err = 0;
+       r.tcall = tc;
        r.rcall = NULL;
        r.m = m;
        init_waitqueue_head(&r.wqueue);
@@ -869,48 +906,50 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
        if (rc)
                *rc = NULL;
 
+       sigpending = 0;
+       if (signal_pending(current)) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+       }
+
        req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
                dprintk(DEBUG_MUX, "error %d\n", err);
-               return PTR_ERR(req);
+               return err;
        }
 
-       r.req = req;
-       dprintk(DEBUG_MUX, "mux %p tc %p tag %d rpc %p req %p\n", m, tc,
-               req->tag, &r, req);
        err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0);
        if (r.err < 0)
                err = r.err;
 
        if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) {
-               spin_lock(&m->lock);
-               req->tcall = NULL;
-               req->err = ERREQFLUSH;
-               spin_unlock(&m->lock);
+               if (v9fs_mux_flush_request(m, req)) {
+                       /* wait until we get response of the flush message */
+                       do {
+                               clear_thread_flag(TIF_SIGPENDING);
+                               err = wait_event_interruptible(r.wqueue,
+                                       r.rcall || r.err);
+                       } while (!r.rcall && !r.err && err==-ERESTARTSYS &&
+                               m->trans->status==Connected && !m->err);
+               }
+               sigpending = 1;
+       }
 
-               clear_thread_flag(TIF_SIGPENDING);
-               v9fs_mux_flush_request(m, req);
+       if (sigpending) {
                spin_lock_irqsave(&current->sighand->siglock, flags);
                recalc_sigpending();
                spin_unlock_irqrestore(&current->sighand->siglock, flags);
        }
 
-       if (!err) {
-               if (r.rcall)
-                       dprintk(DEBUG_MUX, "got response id %d tag %d\n",
-                               r.rcall->id, r.rcall->tag);
-
-               if (rc)
-                       *rc = r.rcall;
-               else
-                       kfree(r.rcall);
-       } else {
+       if (rc)
+               *rc = r.rcall;
+       else
                kfree(r.rcall);
-               dprintk(DEBUG_MUX, "got error %d\n", err);
-               if (err > 0)
-                       err = -EIO;
-       }
+
+       v9fs_mux_free_request(m, req);
+       if (err > 0)
+               err = -EIO;
 
        return err;
 }
@@ -951,12 +990,15 @@ void v9fs_mux_cancel(struct v9fs_mux_data *m, int err)
        struct v9fs_req *req, *rtmp;
        LIST_HEAD(cancel_list);
 
-       dprintk(DEBUG_MUX, "mux %p err %d\n", m, err);
+       dprintk(DEBUG_ERROR, "mux %p err %d\n", m, err);
        m->err = err;
        spin_lock(&m->lock);
        list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
                list_move(&req->req_list, &cancel_list);
        }
+       list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+               list_move(&req->req_list, &cancel_list);
+       }
        spin_unlock(&m->lock);
 
        list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
@@ -965,11 +1007,9 @@ void v9fs_mux_cancel(struct v9fs_mux_data *m, int err)
                        req->err = err;
 
                if (req->cb)
-                       (*req->cb) (req->cba, req->tcall, req->rcall, req->err);
+                       (*req->cb) (req, req->cba);
                else
                        kfree(req->rcall);
-
-               kfree(req);
        }
 
        wake_up(&m->equeue);
index e90bfd3..fb10c50 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 struct v9fs_mux_data;
+struct v9fs_req;
 
 /**
  * v9fs_mux_req_callback - callback function that is called when the
@@ -36,8 +37,7 @@ struct v9fs_mux_data;
  * @rc - response call
  * @err - error code (non-zero if error occured)
  */
-typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc,
-       struct v9fs_fcall *rc, int err);
+typedef void (*v9fs_mux_req_callback)(struct v9fs_req *req, void *a);
 
 int v9fs_mux_global_init(void);
 void v9fs_mux_global_exit(void);
index 083dcfc..1a8e460 100644 (file)
@@ -72,11 +72,17 @@ int v9fs_file_open(struct inode *inode, struct file *file)
                return -ENOSPC;
        }
 
-       err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL);
+       err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall);
        if (err < 0) {
                dprintk(DEBUG_ERROR, "rewalk didn't work\n");
-               goto put_fid;
+               if (fcall && fcall->id == RWALK)
+                       goto clunk_fid;
+               else {
+                       v9fs_put_idpool(fid, &v9ses->fidpool);
+                       goto free_fcall;
+               }
        }
+       kfree(fcall);
 
        /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
        /* translate open mode appropriately */
@@ -109,8 +115,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
 clunk_fid:
        v9fs_t_clunk(v9ses, fid);
 
-put_fid:
-       v9fs_put_idpool(fid, &v9ses->fidpool);
+free_fcall:
        kfree(fcall);
 
        return err;
index 133db36..2cb87ba 100644 (file)
@@ -270,7 +270,10 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm,
        err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall);
        if (err < 0) {
                PRINT_FCALL_ERROR("clone error", fcall);
-               goto put_fid;
+               if (fcall && fcall->id == RWALK)
+                       goto clunk_fid;
+               else
+                       goto put_fid;
        }
        kfree(fcall);
 
@@ -322,6 +325,9 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
                &fcall);
 
        if (err < 0) {
+               if (fcall && fcall->id == RWALK)
+                       goto clunk_fid;
+
                PRINT_FCALL_ERROR("walk error", fcall);
                v9fs_put_idpool(nfid, &v9ses->fidpool);
                goto error;
@@ -640,19 +646,26 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
        }
 
        result = v9fs_t_walk(v9ses, dirfidnum, newfid,
-               (char *)dentry->d_name.name, NULL);
+               (char *)dentry->d_name.name, &fcall);
+
        if (result < 0) {
-               v9fs_put_idpool(newfid, &v9ses->fidpool);
+               if (fcall && fcall->id == RWALK)
+                       v9fs_t_clunk(v9ses, newfid);
+               else
+                       v9fs_put_idpool(newfid, &v9ses->fidpool);
+
                if (result == -ENOENT) {
                        d_add(dentry, NULL);
                        dprintk(DEBUG_VFS,
                                "Return negative dentry %p count %d\n",
                                dentry, atomic_read(&dentry->d_count));
+                       kfree(fcall);
                        return NULL;
                }
                dprintk(DEBUG_ERROR, "walk error:%d\n", result);
                goto FreeFcall;
        }
+       kfree(fcall);
 
        result = v9fs_t_stat(v9ses, newfid, &fcall);
        if (result < 0) {
index 57c4903..d6603d0 100644 (file)
@@ -74,8 +74,8 @@ struct autofs_wait_queue {
        struct autofs_wait_queue *next;
        autofs_wqt_t wait_queue_token;
        /* We use the following to see what we are waiting for */
-       int hash;
-       int len;
+       unsigned int hash;
+       unsigned int len;
        char *name;
        u32 dev;
        u64 ino;
@@ -85,7 +85,6 @@ struct autofs_wait_queue {
        pid_t tgid;
        /* This is for status reporting upon return */
        int status;
-       atomic_t notify;
        atomic_t wait_ctr;
 };
 
index 84e030c..5100f98 100644 (file)
@@ -327,6 +327,7 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
+       struct autofs_info *ino = autofs4_dentry_ino(dentry);
        int oz_mode = autofs4_oz_mode(sbi);
        unsigned int lookup_type;
        int status;
@@ -340,13 +341,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
        if (oz_mode || !lookup_type)
                goto done;
 
-       /*
-        * If a request is pending wait for it.
-        * If it's a mount then it won't be expired till at least
-        * a liitle later and if it's an expire then we might need
-        * to mount it again.
-        */
-       if (autofs4_ispending(dentry)) {
+       /* If an expire request is pending wait for it. */
+       if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
                DPRINTK("waiting for active request %p name=%.*s",
                        dentry, dentry->d_name.len, dentry->d_name.name);
 
index 142ab6a..ce103e7 100644 (file)
@@ -189,14 +189,30 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
        return len;
 }
 
+static struct autofs_wait_queue *
+autofs4_find_wait(struct autofs_sb_info *sbi,
+                 char *name, unsigned int hash, unsigned int len)
+{
+       struct autofs_wait_queue *wq;
+
+       for (wq = sbi->queues; wq; wq = wq->next) {
+               if (wq->hash == hash &&
+                   wq->len == len &&
+                   wq->name && !memcmp(wq->name, name, len))
+                       break;
+       }
+       return wq;
+}
+
 int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                enum autofs_notify notify)
 {
+       struct autofs_info *ino;
        struct autofs_wait_queue *wq;
        char *name;
        unsigned int len = 0;
        unsigned int hash = 0;
-       int status;
+       int status, type;
 
        /* In catatonic mode, we don't wait for nobody */
        if (sbi->catatonic)
@@ -223,21 +239,41 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                return -EINTR;
        }
 
-       for (wq = sbi->queues ; wq ; wq = wq->next) {
-               if (wq->hash == dentry->d_name.hash &&
-                   wq->len == len &&
-                   wq->name && !memcmp(wq->name, name, len))
-                       break;
-       }
+       wq = autofs4_find_wait(sbi, name, hash, len);
+       ino = autofs4_dentry_ino(dentry);
+       if (!wq && ino && notify == NFY_NONE) {
+               /*
+                * Either we've betean the pending expire to post it's
+                * wait or it finished while we waited on the mutex.
+                * So we need to wait till either, the wait appears
+                * or the expire finishes.
+                */
+
+               while (ino->flags & AUTOFS_INF_EXPIRING) {
+                       mutex_unlock(&sbi->wq_mutex);
+                       schedule_timeout_interruptible(HZ/10);
+                       if (mutex_lock_interruptible(&sbi->wq_mutex)) {
+                               kfree(name);
+                               return -EINTR;
+                       }
+                       wq = autofs4_find_wait(sbi, name, hash, len);
+                       if (wq)
+                               break;
+               }
 
-       if (!wq) {
-               /* Can't wait for an expire if there's no mount */
-               if (notify == NFY_NONE && !d_mountpoint(dentry)) {
+               /*
+                * Not ideal but the status has already gone. Of the two
+                * cases where we wait on NFY_NONE neither depend on the
+                * return status of the wait.
+                */
+               if (!wq) {
                        kfree(name);
                        mutex_unlock(&sbi->wq_mutex);
-                       return -ENOENT;
+                       return 0;
                }
+       }
 
+       if (!wq) {
                /* Create a new wait queue */
                wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
                if (!wq) {
@@ -263,20 +299,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                wq->tgid = current->tgid;
                wq->status = -EINTR; /* Status return if interrupted */
                atomic_set(&wq->wait_ctr, 2);
-               atomic_set(&wq->notify, 1);
-               mutex_unlock(&sbi->wq_mutex);
-       } else {
-               atomic_inc(&wq->wait_ctr);
                mutex_unlock(&sbi->wq_mutex);
-               kfree(name);
-               DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
-                       (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
-       }
-
-       if (notify != NFY_NONE && atomic_read(&wq->notify)) {
-               int type;
-
-               atomic_dec(&wq->notify);
 
                if (sbi->version < 5) {
                        if (notify == NFY_MOUNT)
@@ -299,6 +322,12 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
 
                /* autofs4_notify_daemon() may block */
                autofs4_notify_daemon(sbi, wq, type);
+       } else {
+               atomic_inc(&wq->wait_ctr);
+               mutex_unlock(&sbi->wq_mutex);
+               kfree(name);
+               DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
+                       (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
        }
 
        /* wq->name is NULL if and only if the lock is already released */
index 3f3e8f4..01f39f8 100644 (file)
@@ -1323,7 +1323,7 @@ compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
 {
        unsigned i;
        struct iovec *iov;
-       if (nr_segs >= UIO_MAXIOV)
+       if (nr_segs > UIO_MAXIOV)
                return -EINVAL;
        iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
        for (i = 0; i < nr_segs; i++) {
@@ -1913,7 +1913,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
        }
 
        if (sigmask) {
-               if (sigsetsize |= sizeof(compat_sigset_t))
+               if (sigsetsize != sizeof(compat_sigset_t))
                        return -EINVAL;
                if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
                        return -EFAULT;
index 48ae033..2edd7ee 100644 (file)
@@ -711,7 +711,7 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode,
         * direct blocks blocks
         */
        if (num == 0 && blks > 1) {
-               current_block = le32_to_cpu(where->key + 1);
+               current_block = le32_to_cpu(where->key) + 1;
                for (i = 1; i < blks; i++)
                        *(where->p + i ) = cpu_to_le32(current_block++);
        }
@@ -724,7 +724,7 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode,
        if (block_i) {
                block_i->last_alloc_logical_block = block + blks - 1;
                block_i->last_alloc_physical_block =
-                               le32_to_cpu(where[num].key + blks - 1);
+                               le32_to_cpu(where[num].key) + blks - 1;
        }
 
        /* We are done with atomic stuff, now do the rest of housekeeping */
@@ -814,11 +814,13 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
 
        /* Simplest case - block found, no allocation needed */
        if (!partial) {
-               first_block = chain[depth - 1].key;
+               first_block = le32_to_cpu(chain[depth - 1].key);
                clear_buffer_new(bh_result);
                count++;
                /*map more blocks*/
                while (count < maxblocks && count <= blocks_to_boundary) {
+                       unsigned long blk;
+
                        if (!verify_chain(chain, partial)) {
                                /*
                                 * Indirect block might be removed by
@@ -831,8 +833,9 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
                                count = 0;
                                break;
                        }
-                       if (le32_to_cpu(*(chain[depth-1].p+count) ==
-                                       (first_block + count)))
+                       blk = le32_to_cpu(*(chain[depth-1].p + count));
+
+                       if (blk == first_block + count)
                                count++;
                        else
                                break;
index e7944e6..5f45e01 100644 (file)
@@ -412,7 +412,7 @@ void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
                 kfree(comprbuf);
 }
 
-int jffs2_compressors_init(void)
+int __init jffs2_compressors_init(void)
 {
 /* Registering compressors */
 #ifdef CONFIG_JFFS2_ZLIB
@@ -440,7 +440,7 @@ int jffs2_compressors_init(void)
         return 0;
 }
 
-int jffs2_compressors_exit(void)
+int __exit jffs2_compressors_exit(void)
 {
 /* Unregistering compressors */
 #ifdef CONFIG_JFFS2_RUBIN
index 5c63e0c..d43cbac 100644 (file)
@@ -60,7 +60,7 @@ static int __init alloc_workspaces(void)
        return 0;
 }
 
-static void free_workspaces(void)
+static void __exit free_workspaces(void)
 {
        vfree(def_strm.workspace);
        vfree(inf_strm.workspace);
@@ -216,7 +216,7 @@ int __init jffs2_zlib_init(void)
     return ret;
 }
 
-void jffs2_zlib_exit(void)
+void __exit jffs2_zlib_exit(void)
 {
     jffs2_unregister_compressor(&jffs2_zlib_comp);
     free_workspaces();
index e92187f..e18c943 100644 (file)
@@ -220,12 +220,20 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
        D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
                  inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
 
-       if (!start && end == PAGE_CACHE_SIZE) {
-               /* We need to avoid deadlock with page_cache_read() in
-                  jffs2_garbage_collect_pass(). So we have to mark the
-                  page up to date, to prevent page_cache_read() from
-                  trying to re-lock it. */
-               SetPageUptodate(pg);
+       if (end == PAGE_CACHE_SIZE) {
+               if (!start) {
+                       /* We need to avoid deadlock with page_cache_read() in
+                          jffs2_garbage_collect_pass(). So we have to mark the
+                          page up to date, to prevent page_cache_read() from
+                          trying to re-lock it. */
+                       SetPageUptodate(pg);
+               } else {
+                       /* When writing out the end of a page, write out the 
+                          _whole_ page. This helps to reduce the number of
+                          nodes in files which have many short writes, like
+                          syslog files. */
+                       start = aligned_start = 0;
+               }
        }
 
        ri = jffs2_alloc_raw_inode();
index 9c57573..4973cd6 100644 (file)
@@ -438,7 +438,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
        if (c->mtd->point) {
                err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
                if (!err && retlen < tn->csize) {
-                       JFFS2_WARNING("MTD point returned len too short: %u instead of %u.\n", retlen, tn->csize);
+                       JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
                        c->mtd->unpoint(c->mtd, buffer, ofs, len);
                } else if (err)
                        JFFS2_WARNING("MTD point failed: error code %d.\n", err);
@@ -461,7 +461,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
                }
 
                if (retlen != len) {
-                       JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ofs, retlen, len);
+                       JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len);
                        err = -EIO;
                        goto free_out;
                }
index 0a79fc9..5847e76 100644 (file)
@@ -222,9 +222,6 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
                }
        }
 
-       if (jffs2_sum_active() && s)
-               kfree(s);
-
        /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
        if (c->nextblock && (c->nextblock->dirty_size)) {
                c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -266,6 +263,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
        else
                c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
 #endif
+       if (s)
+               kfree(s);
+
        return ret;
 }
 
index 9763d73..439b9f6 100644 (file)
@@ -853,7 +853,7 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
 
 
        if (ret || (retlen != infosize)) {
-               JFFS2_WARNING("Write of %d bytes at 0x%08x failed. returned %d, retlen %zu\n",
+               JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
                        infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen);
 
                c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
index c8b539e..9d05214 100644 (file)
@@ -324,6 +324,18 @@ static int __init init_jffs2_fs(void)
 {
        int ret;
 
+       /* Paranoia checks for on-medium structures. If we ask GCC
+          to pack them with __attribute__((packed)) then it _also_
+          assumes that they're not aligned -- so it emits crappy
+          code on some architectures. Ideally we want an attribute
+          which means just 'no padding', without the alignment
+          thing. But GCC doesn't have that -- we have to just
+          hope the structs are the right sizes, instead. */
+       BUG_ON(sizeof(struct jffs2_unknown_node) != 12);
+       BUG_ON(sizeof(struct jffs2_raw_dirent) != 40);
+       BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
+       BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
+
        printk(KERN_INFO "JFFS2 version 2.2."
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
               " (NAND)"
@@ -331,7 +343,7 @@ static int __init init_jffs2_fs(void)
 #ifdef CONFIG_JFFS2_SUMMARY
               " (SUMMARY) "
 #endif
-              " (C) 2001-2003 Red Hat, Inc.\n");
+              " (C) 2001-2006 Red Hat, Inc.\n");
 
        jffs2_inode_cachep = kmem_cache_create("jffs2_i",
                                             sizeof(struct jffs2_inode_info),
index efad798..6f99c0a 100644 (file)
@@ -446,15 +446,14 @@ static struct lock_manager_operations lease_manager_ops = {
  */
 static int lease_init(struct file *filp, int type, struct file_lock *fl)
  {
+       if (assign_type(fl, type) != 0)
+               return -EINVAL;
+
        fl->fl_owner = current->files;
        fl->fl_pid = current->tgid;
 
        fl->fl_file = filp;
        fl->fl_flags = FL_LEASE;
-       if (assign_type(fl, type) != 0) {
-               locks_free_lock(fl);
-               return -EINVAL;
-       }
        fl->fl_start = 0;
        fl->fl_end = OFFSET_MAX;
        fl->fl_ops = NULL;
@@ -466,16 +465,19 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl)
 static int lease_alloc(struct file *filp, int type, struct file_lock **flp)
 {
        struct file_lock *fl = locks_alloc_lock();
-       int error;
+       int error = -ENOMEM;
 
        if (fl == NULL)
-               return -ENOMEM;
+               goto out;
 
        error = lease_init(filp, type, fl);
-       if (error)
-               return error;
+       if (error) {
+               locks_free_lock(fl);
+               fl = NULL;
+       }
+out:
        *flp = fl;
-       return 0;
+       return error;
 }
 
 /* Check if two locks overlap each other.
@@ -1372,6 +1374,7 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
                goto out;
 
        if (my_before != NULL) {
+               *flp = *my_before;
                error = lease->fl_lmops->fl_change(my_before, arg);
                goto out;
        }
index 2c5f1f8..bf478ad 100644 (file)
@@ -899,13 +899,11 @@ static int do_change_type(struct nameidata *nd, int flag)
 /*
  * do loopback mount.
  */
-static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags, int mnt_flags)
+static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
 {
        struct nameidata old_nd;
        struct vfsmount *mnt = NULL;
-       int recurse = flags & MS_REC;
        int err = mount_is_safe(nd);
-
        if (err)
                return err;
        if (!old_name || !*old_name)
@@ -939,7 +937,6 @@ static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags
                spin_unlock(&vfsmount_lock);
                release_mounts(&umount_list);
        }
-       mnt->mnt_flags = mnt_flags;
 
 out:
        up_write(&namespace_sem);
@@ -1353,7 +1350,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
                                    data_page);
        else if (flags & MS_BIND)
-               retval = do_loopback(&nd, dev_name, flags, mnt_flags);
+               retval = do_loopback(&nd, dev_name, flags & MS_REC);
        else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
                retval = do_change_type(&nd, flags);
        else if (flags & MS_MOVE)
index 53ec28c..317b7c7 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -1124,7 +1124,6 @@ asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
        prevent_tail_call(ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(sys_openat);
 
 #ifndef __alpha__
 
index 45ae7dd..7ef1f09 100644 (file)
@@ -533,6 +533,7 @@ void del_gendisk(struct gendisk *disk)
 
        devfs_remove_disk(disk);
 
+       kobject_uevent(&disk->kobj, KOBJ_REMOVE);
        if (disk->holder_dir)
                kobject_unregister(disk->holder_dir);
        if (disk->slave_dir)
@@ -545,7 +546,7 @@ void del_gendisk(struct gendisk *disk)
                        kfree(disk_name);
                }
                put_device(disk->driverfs_dev);
+               disk->driverfs_dev = NULL;
        }
-       kobject_uevent(&disk->kobj, KOBJ_REMOVE);
        kobject_del(&disk->kobj);
 }
index 34c7a11..70d9c5a 100644 (file)
@@ -434,6 +434,11 @@ smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        if (dentry->d_name.len > SMB_MAXNAMELEN)
                goto out;
 
+       /* Do not allow lookup of names with backslashes in */
+       error = -EINVAL;
+       if (memchr(dentry->d_name.name, '\\', dentry->d_name.len))
+               goto out;
+
        lock_kernel();
        error = smb_proc_getattr(dentry, &finfo);
 #ifdef SMBFS_PARANOIA
index c71c375..c71dd27 100644 (file)
@@ -339,9 +339,11 @@ int smb_add_request(struct smb_request *req)
                /*
                 * On timeout or on interrupt we want to try and remove the
                 * request from the recvq/xmitq.
+                * First check if the request is still part of a queue. (May
+                * have been removed by some error condition)
                 */
                smb_lock_server(server);
-               if (!(req->rq_flags & SMB_REQ_RECEIVED)) {
+               if (!list_empty(&req->rq_queue)) {
                        list_del_init(&req->rq_queue);
                        smb_rput(req);
                }
index 7fb0497..a285fd7 100644 (file)
@@ -51,7 +51,7 @@ struct splice_pipe_desc {
  * addition of remove_mapping(). If success is returned, the caller may
  * attempt to reuse this page for another destination.
  */
-static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
+static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
                                     struct pipe_buffer *buf)
 {
        struct page *page = buf->page;
@@ -78,16 +78,18 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
                return 1;
        }
 
+       buf->flags |= PIPE_BUF_FLAG_LRU;
        return 0;
 }
 
-static void page_cache_pipe_buf_release(struct pipe_inode_info *info,
+static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
                                        struct pipe_buffer *buf)
 {
        page_cache_release(buf->page);
+       buf->flags &= ~PIPE_BUF_FLAG_LRU;
 }
 
-static int page_cache_pipe_buf_pin(struct pipe_inode_info *info,
+static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe,
                                   struct pipe_buffer *buf)
 {
        struct page *page = buf->page;
@@ -141,6 +143,7 @@ static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe,
        if (!(buf->flags & PIPE_BUF_FLAG_GIFT))
                return 1;
 
+       buf->flags |= PIPE_BUF_FLAG_LRU;
        return generic_pipe_buf_steal(pipe, buf);
 }
 
@@ -321,6 +324,8 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                                              mapping_gfp_mask(mapping));
                        if (unlikely(error)) {
                                page_cache_release(page);
+                               if (error == -EEXIST)
+                                       continue;
                                break;
                        }
                        /*
@@ -497,14 +502,14 @@ EXPORT_SYMBOL(generic_file_splice_read);
  * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
  * using sendpage(). Return the number of bytes sent.
  */
-static int pipe_to_sendpage(struct pipe_inode_info *info,
+static int pipe_to_sendpage(struct pipe_inode_info *pipe,
                            struct pipe_buffer *buf, struct splice_desc *sd)
 {
        struct file *file = sd->file;
        loff_t pos = sd->pos;
        int ret, more;
 
-       ret = buf->ops->pin(info, buf);
+       ret = buf->ops->pin(pipe, buf);
        if (!ret) {
                more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
 
@@ -535,7 +540,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
  * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create
  * a new page in the output file page cache and fill/dirty that.
  */
-static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
+static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
                        struct splice_desc *sd)
 {
        struct file *file = sd->file;
@@ -549,7 +554,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
        /*
         * make sure the data in this buffer is uptodate
         */
-       ret = buf->ops->pin(info, buf);
+       ret = buf->ops->pin(pipe, buf);
        if (unlikely(ret))
                return ret;
 
@@ -566,37 +571,23 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
         */
        if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) {
                /*
-                * If steal succeeds, buf->page is now pruned from the vm
-                * side (page cache) and we can reuse it. The page will also
-                * be locked on successful return.
+                * If steal succeeds, buf->page is now pruned from the
+                * pagecache and we can reuse it. The page will also be
+                * locked on successful return.
                 */
-               if (buf->ops->steal(info, buf))
+               if (buf->ops->steal(pipe, buf))
                        goto find_page;
 
                page = buf->page;
-               page_cache_get(page);
-
-               /*
-                * page must be on the LRU for adding to the pagecache.
-                * Check this without grabbing the zone lock, if it isn't
-                * the do grab the zone lock, recheck, and add if necessary.
-                */
-               if (!PageLRU(page)) {
-                       struct zone *zone = page_zone(page);
-
-                       spin_lock_irq(&zone->lru_lock);
-                       if (!PageLRU(page)) {
-                               SetPageLRU(page);
-                               add_page_to_inactive_list(zone, page);
-                       }
-                       spin_unlock_irq(&zone->lru_lock);
-               }
-
                if (add_to_page_cache(page, mapping, index, gfp_mask)) {
-                       page_cache_release(page);
                        unlock_page(page);
                        goto find_page;
                }
+
+               page_cache_get(page);
+
+               if (!(buf->flags & PIPE_BUF_FLAG_LRU))
+                       lru_cache_add(page);
        } else {
 find_page:
                page = find_lock_page(mapping, index);
@@ -647,23 +638,36 @@ find_page:
        }
 
        ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
-       if (ret == AOP_TRUNCATED_PAGE) {
+       if (unlikely(ret)) {
+               loff_t isize = i_size_read(mapping->host);
+
+               if (ret != AOP_TRUNCATED_PAGE)
+                       unlock_page(page);
                page_cache_release(page);
-               goto find_page;
-       } else if (ret)
+               if (ret == AOP_TRUNCATED_PAGE)
+                       goto find_page;
+
+               /*
+                * prepare_write() may have instantiated a few blocks
+                * outside i_size.  Trim these off again.
+                */
+               if (sd->pos + this_len > isize)
+                       vmtruncate(mapping->host, isize);
+
                goto out;
+       }
 
        if (buf->page != page) {
                /*
                 * Careful, ->map() uses KM_USER0!
                 */
-               char *src = buf->ops->map(info, buf, 1);
+               char *src = buf->ops->map(pipe, buf, 1);
                char *dst = kmap_atomic(page, KM_USER1);
 
                memcpy(dst + offset, src + buf->offset, this_len);
                flush_dcache_page(page);
                kunmap_atomic(dst, KM_USER1);
-               buf->ops->unmap(info, buf, src);
+               buf->ops->unmap(pipe, buf, src);
        }
 
        ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len);
index 64ee07d..8558226 100644 (file)
@@ -1942,8 +1942,10 @@ xfs_alloc_fix_freelist(
                /*
                 * Allocate as many blocks as possible at once.
                 */
-               if ((error = xfs_alloc_ag_vextent(&targs)))
+               if ((error = xfs_alloc_ag_vextent(&targs))) {
+                       xfs_trans_brelse(tp, agflbp);
                        return error;
+               }
                /*
                 * Stop if we run out.  Won't happen if callers are obeying
                 * the restrictions correctly.  Can happen for free calls
@@ -1960,6 +1962,7 @@ xfs_alloc_fix_freelist(
                                return error;
                }
        }
+       xfs_trans_brelse(tp, agflbp);
        args->agbp = agbp;
        return 0;
 }
index 81a05cf..1f14876 100644 (file)
@@ -316,6 +316,18 @@ xfs_rename(
                }
        }
 
+       /*
+        * If we are using project inheritance, we only allow renames
+        * into our tree when the project IDs are the same; else the
+        * tree quota mechanism would be circumvented.
+        */
+       if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
+                    (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) {
+               error = XFS_ERROR(EXDEV);
+               xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
+               goto rele_return;
+       }
+
        new_parent = (src_dp != target_dp);
        src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR);
 
index f0e09ca..36ea1b2 100644 (file)
@@ -669,31 +669,22 @@ xfs_mntupdate(
        xfs_mount_t     *mp = XFS_BHVTOM(bdp);
        int             error;
 
-       if (args->flags & XFSMNT_BARRIER)
-               mp->m_flags |= XFS_MOUNT_BARRIER;
-       else
-               mp->m_flags &= ~XFS_MOUNT_BARRIER;
-
-       if ((vfsp->vfs_flag & VFS_RDONLY) &&
-           !(*flags & MS_RDONLY)) {
-               vfsp->vfs_flag &= ~VFS_RDONLY;
-
-               if (args->flags & XFSMNT_BARRIER)
+       if (!(*flags & MS_RDONLY)) {                    /* rw/ro -> rw */
+               if (vfsp->vfs_flag & VFS_RDONLY)
+                       vfsp->vfs_flag &= ~VFS_RDONLY;
+               if (args->flags & XFSMNT_BARRIER) {
+                       mp->m_flags |= XFS_MOUNT_BARRIER;
                        xfs_mountfs_check_barriers(mp);
-       }
-
-       if (!(vfsp->vfs_flag & VFS_RDONLY) &&
-           (*flags & MS_RDONLY)) {
+               } else {
+                       mp->m_flags &= ~XFS_MOUNT_BARRIER;
+               }
+       } else if (!(vfsp->vfs_flag & VFS_RDONLY)) {    /* rw -> ro */
                VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
-
                xfs_quiesce_fs(mp);
-
-               /* Ok now write out an unmount record */
                xfs_log_unmount_write(mp);
                xfs_unmountfs_writesb(mp);
                vfsp->vfs_flag |= VFS_RDONLY;
        }
-
        return 0;
 }
 
index fa71b30..7027ae6 100644 (file)
@@ -2663,7 +2663,7 @@ xfs_link(
         */
        if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
                     (tdp->i_d.di_projid != sip->i_d.di_projid))) {
-               error = XFS_ERROR(EPERM);
+               error = XFS_ERROR(EXDEV);
                goto error_return;
        }
 
index e4f1fa5..7b1fce0 100644 (file)
@@ -9,6 +9,7 @@
  *  published by the Free Software Foundation.
  */
 
+#include "hardware.h"
                .macro  addruart,rx
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
index df31313..1eb3503 100644 (file)
@@ -10,6 +10,7 @@
  *  published by the Free Software Foundation.
  *
  */
+#include <asm/arch/irqs.h>
 
                .macro  disable_fiq
                .endm
index 83f552f..c611871 100644 (file)
@@ -16,7 +16,7 @@
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x00000000        @ physical
                movne   \rx, #0xe0000000        @ virtual
-               orr     \rx, \rx, #0x00200000
+               orreq   \rx, \rx, #0x00200000   @ physical
                orr     \rx, \rx, #0x00006000   @ UART1 offset
                .endm
 
diff --git a/include/asm-arm/arch-imx/imx-uart.h b/include/asm-arm/arch-imx/imx-uart.h
new file mode 100644 (file)
index 0000000..3a685e1
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef ASMARM_ARCH_UART_H
+#define ASMARM_ARCH_UART_H
+
+#define IMXUART_HAVE_RTSCTS (1<<0)
+
+struct imxuart_platform_data {
+       unsigned int flags;
+};
+
+#endif
index 942b622..b59520e 100644 (file)
@@ -260,6 +260,12 @@ out:
 
 #endif
 
+#ifndef CONFIG_PCI
+
+#define        __io(v)         v
+
+#else
+
 /*
  * IXP4xx does not have a transparent cpu -> PCI I/O translation
  * window.  Instead, it has a set of registers that must be tweaked
@@ -578,6 +584,7 @@ __ixp4xx_iowrite32_rep(void __iomem *addr, const void *vaddr, u32 count)
 
 #define        ioport_map(port, nr)            ((void __iomem*)(port + PIO_OFFSET))
 #define        ioport_unmap(addr)
+#endif // !CONFIG_PCI
 
 #endif //  __ASM_ARM_ARCH_IO_H
 
index ee211d2..af9667b 100644 (file)
@@ -14,7 +14,7 @@
  */
 #define PHYS_OFFSET    UL(0x00000000)
 
-#ifndef __ASSEMBLY__
+#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
 
 void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes);
 
index 3e88a2a..a008150 100644 (file)
@@ -24,27 +24,29 @@ typedef struct pxa_dma_desc {
        volatile u32 dcmd;      /* DCMD value for the current transfer */
 } pxa_dma_desc;
 
+typedef enum {
+       DMA_PRIO_HIGH = 0,
+       DMA_PRIO_MEDIUM = 1,
+       DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
 #if defined(CONFIG_PXA27x)
 
 #define PXA_DMA_CHANNELS       32
-#define PXA_DMA_NBCH(prio)     ((prio == DMA_PRIO_LOW) ? 16 : 8)
 
-typedef enum {
-       DMA_PRIO_HIGH = 0,
-       DMA_PRIO_MEDIUM = 8,
-       DMA_PRIO_LOW = 16
-} pxa_dma_prio;
+#define pxa_for_each_dma_prio(ch, prio)                                        \
+for (                                                                  \
+       ch = prio * 4;                                                  \
+       ch != (4 << prio) + 16;                                         \
+       ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1)       \
+)
 
 #elif defined(CONFIG_PXA25x)
 
 #define PXA_DMA_CHANNELS       16
-#define PXA_DMA_NBCH(prio)     ((prio == DMA_PRIO_LOW) ? 8 : 4)
 
-typedef enum {
-       DMA_PRIO_HIGH = 0,
-       DMA_PRIO_MEDIUM = 4,
-       DMA_PRIO_LOW = 8
-} pxa_dma_prio;
+#define pxa_for_each_dma_prio(ch, prio)                                        \
+       for (ch = prio * 4; ch != (4 << prio); ch++)
 
 #endif
 
index 7fb0213..5ab8216 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASMARM_BUG_H
 
 #include <linux/config.h>
+#include <linux/stddef.h>
 
 #ifdef CONFIG_BUG
 #ifdef CONFIG_DEBUG_BUGVERBOSE
index ee8dfea..cbf39a5 100644 (file)
 /*
  * The following syscalls are obsolete and no longer available for EABI.
  */
-#if defined(__ARM_EABI__)
+#if defined(__ARM_EABI__) && !defined(__KERNEL__)
 #undef __NR_time
 #undef __NR_umount
 #undef __NR_stime
@@ -410,7 +410,8 @@ type name(void) {                                                   \
   __asm__ __volatile__ (                                               \
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST() );                                           \
+       : __SYS_REG_LIST()                                              \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
@@ -424,7 +425,8 @@ type name(type1 arg1) {                                             \
   __asm__ __volatile__ (                                               \
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0) ) );                               \
+       : __SYS_REG_LIST( "0" (__r0) )                                  \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
@@ -439,7 +441,8 @@ type name(type1 arg1,type2 arg2) {                                  \
   __asm__ __volatile__ (                                               \
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) );                   \
+       : __SYS_REG_LIST( "0" (__r0), "r" (__r1) )                      \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
@@ -456,7 +459,8 @@ type name(type1 arg1,type2 arg2,type3 arg3) {                               \
   __asm__ __volatile__ (                                               \
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) );       \
+       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) )          \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
@@ -474,7 +478,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {         \
   __asm__ __volatile__ (                                               \
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) ); \
+       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
@@ -494,7 +499,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {     \
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
        : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2),           \
-                         "r" (__r3), "r" (__r4) ) );                   \
+                         "r" (__r3), "r" (__r4) )                      \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
@@ -514,7 +520,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
   __syscall(name)                                                      \
        : "=r" (__res_r0)                                               \
        : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2),           \
-                         "r" (__r3), "r" (__r4), "r" (__r5) ) );       \
+                         "r" (__r3), "r" (__r4), "r" (__r5) )          \
+       : "memory" );                                                   \
   __res = __res_r0;                                                    \
   __syscall_return(type,__res);                                                \
 }
index 51c4e5f..d92e253 100644 (file)
@@ -200,6 +200,7 @@ extern int io_apic_get_unique_id (int ioapic, int apic_id);
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low);
+extern int timer_uses_ioapic_pin_0;
 #endif /* CONFIG_ACPI */
 
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
index 90921e1..6cc517e 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/bitops.h>
 #include <asm/intrinsics.h>
 
 /**
index 3872e92..d83fc29 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <asm/processor.h>
+#include <asm/page.h>
 
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
@@ -179,9 +180,11 @@ do {                                                               \
 #define __put_user_nocheck(x, ptr, size)                       \
 ({                                                             \
        long __pu_err;                                          \
-       might_sleep();                                          \
+       __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
+       if (!is_kernel_addr((unsigned long)__pu_addr))          \
+               might_sleep();                                  \
        __chk_user_ptr(ptr);                                    \
-       __put_user_size((x), (ptr), (size), __pu_err);          \
+       __put_user_size((x), __pu_addr, (size), __pu_err);      \
        __pu_err;                                               \
 })
 
@@ -258,9 +261,11 @@ do {                                                               \
 ({                                                             \
        long __gu_err;                                          \
        unsigned long __gu_val;                                 \
+       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);     \
        __chk_user_ptr(ptr);                                    \
-       might_sleep();                                          \
-       __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
+       if (!is_kernel_addr((unsigned long)__gu_addr))          \
+               might_sleep();                                  \
+       __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__typeof__(*(ptr)))__gu_val;                     \
        __gu_err;                                               \
 })
@@ -270,9 +275,11 @@ do {                                                               \
 ({                                                             \
        long __gu_err;                                          \
        long long __gu_val;                                     \
+       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);     \
        __chk_user_ptr(ptr);                                    \
-       might_sleep();                                          \
-       __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
+       if (!is_kernel_addr((unsigned long)__gu_addr))          \
+               might_sleep();                                  \
+       __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__typeof__(*(ptr)))__gu_val;                     \
        __gu_err;                                               \
 })
index 973e609..31f3629 100644 (file)
@@ -35,6 +35,7 @@
 #define CPM_CR_INIT_TX         ((ushort)0x0002)
 #define CPM_CR_HUNT_MODE       ((ushort)0x0003)
 #define CPM_CR_STOP_TX         ((ushort)0x0004)
+#define CPM_CR_GRA_STOP_TX     ((ushort)0x0005)
 #define CPM_CR_RESTART_TX      ((ushort)0x0006)
 #define CPM_CR_CLOSE_RX_BD     ((ushort)0x0007)
 #define CPM_CR_SET_GADDR       ((ushort)0x0008)
index b638b87..c70344b 100644 (file)
@@ -69,7 +69,7 @@
 #define CPM_CR_INIT_TX         ((ushort)0x0002)
 #define CPM_CR_HUNT_MODE       ((ushort)0x0003)
 #define CPM_CR_STOP_TX         ((ushort)0x0004)
-#define CPM_CR_GRA_STOP_TX      ((ushort)0x0005)
+#define CPM_CR_GRA_STOP_TX     ((ushort)0x0005)
 #define CPM_CR_RESTART_TX      ((ushort)0x0006)
 #define CPM_CR_SET_GADDR       ((ushort)0x0008)
 #define CPM_CR_START_IDMA      ((ushort)0x0009)
index a70ba2e..0fb68a0 100644 (file)
@@ -20,6 +20,7 @@
 /* This must match what is in arch/ppc/Makefile */
 #define PAGE_OFFSET    CONFIG_KERNEL_START
 #define KERNELBASE     PAGE_OFFSET
+#define is_kernel_addr(x)      ((x) >= PAGE_OFFSET)
 
 #ifndef __ASSEMBLY__
 
index 657d582..41c2792 100644 (file)
 #define __NR_pselect6          301
 #define __NR_ppoll             302
 #define __NR_unshare           303
+#define __NR_set_robust_list   304
+#define __NR_get_robust_list   305
+#define __NR_splice            306
+#define __NR_sync_file_range   307
+#define __NR_tee               308
+#define __NR_vmsplice          309
 
-#define NR_syscalls 304
+#define NR_syscalls 310
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 32a48f6..f5611a7 100644 (file)
@@ -41,7 +41,7 @@
 #define __NR_capset             22 /* Linux Specific                              */
 #define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
 #define __NR_getuid              24 /* Common                                      */
-/* #define __NR_time alias      25    ENOSYS under SunOS                          */
+#define __NR_vmsplice           25 /* ENOSYS under SunOS                          */
 #define __NR_ptrace              26 /* Common                                      */
 #define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
 #define __NR_sigaltstack        28 /* Common                                      */
index ca80e8a..6870574 100644 (file)
@@ -41,7 +41,7 @@
 #define __NR_capset             22 /* Linux Specific                              */
 #define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
 #define __NR_getuid              24 /* Common                                      */
-/* #define __NR_time alias      25    ENOSYS under SunOS                          */
+#define __NR_vmsplice           25 /* ENOSYS under SunOS                          */
 #define __NR_ptrace              26 /* Common                                      */
 #define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
 #define __NR_sigaltstack        28 /* Common                                      */
index 93b51df..670a338 100644 (file)
@@ -59,6 +59,8 @@ extern void __init parse_memopt(char *p, char **end);
 extern void __init parse_memmapopt(char *p, char **end);
 
 extern struct e820map e820;
+
+extern unsigned ebda_addr, ebda_size;
 #endif/*!__ASSEMBLY__*/
 
 #endif/*__E820_HEADER*/
index ee1bc69..52484e8 100644 (file)
@@ -205,6 +205,7 @@ extern int skip_ioapic_setup;
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int);
+extern int timer_uses_ioapic_pin_0;
 #endif
 
 extern int sis_apic_bug; /* dummy */ 
index f6e72a6..e8e53b9 100644 (file)
@@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *,
  * @node: for internal use by the driver core only.
  * @kobj: for internal use by the driver core only.
  * @devt_attr: for internal use by the driver core only.
+ * @groups: optional additional groups to be created
  * @dev: if set, a symlink to the struct device is created in the sysfs
  * directory for this struct class device.
  * @class_data: pointer to whatever you want to store here for this struct
@@ -228,6 +229,7 @@ struct class_device {
        struct device           * dev;          /* not necessary, but nice to have */
        void                    * class_data;   /* class-specific data */
        struct class_device     *parent;        /* parent of this child device, if there is one */
+       struct attribute_group  ** groups;      /* optional groups */
 
        void    (*release)(struct class_device *dev);
        int     (*uevent)(struct class_device *dev, char **envp,
index ff61817..635690c 100644 (file)
@@ -14,6 +14,7 @@ enum dma_data_direction {
 };
 
 #define DMA_64BIT_MASK 0xffffffffffffffffULL
+#define DMA_48BIT_MASK 0x0000ffffffffffffULL
 #define DMA_40BIT_MASK 0x000000ffffffffffULL
 #define DMA_39BIT_MASK 0x0000007fffffffffULL
 #define DMA_32BIT_MASK 0x00000000ffffffffULL
diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h
new file mode 100644 (file)
index 0000000..f597512
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Platform information definitions for the CPM Uart driver.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef FS_UART_PD_H
+#define FS_UART_PD_H
+
+#include <linux/version.h>
+#include <asm/types.h>
+
+enum fs_uart_id {
+       fsid_smc1_uart,
+       fsid_smc2_uart,
+       fsid_scc1_uart,
+       fsid_scc2_uart,
+       fsid_scc3_uart,
+       fsid_scc4_uart,
+       fs_uart_nr,
+};
+
+static inline int fs_uart_id_scc2fsid(int id)
+{
+    return fsid_scc1_uart + id - 1;
+}
+
+static inline int fs_uart_id_fsid2scc(int id)
+{
+    return id - fsid_scc1_uart + 1;
+}
+
+static inline int fs_uart_id_smc2fsid(int id)
+{
+    return fsid_smc1_uart + id - 1;
+}
+
+static inline int fs_uart_id_fsid2smc(int id)
+{
+    return id - fsid_smc1_uart + 1;
+}
+
+struct fs_uart_platform_info {
+        void(*init_ioports)(void);
+       /* device specific information */
+       int fs_no;              /* controller index */
+       u32 uart_clk;
+       u8 tx_num_fifo;
+       u8 tx_buf_size;
+       u8 rx_num_fifo;
+       u8 rx_buf_size;
+       u8 brg;
+};
+
+#endif
index 2cac60e..c48f521 100644 (file)
 
 typedef struct {
        uint32_t v32;
-} __attribute__((packed))  jint32_t;
+} __attribute__((packed)) jint32_t;
 
 typedef struct {
        uint32_t m;
-} __attribute__((packed))  jmode_t;
+} __attribute__((packed)) jmode_t;
 
 typedef struct {
        uint16_t v16;
@@ -111,7 +111,7 @@ struct jffs2_unknown_node
        jint16_t nodetype;
        jint32_t totlen; /* So we can skip over nodes we don't grok */
        jint32_t hdr_crc;
-} __attribute__((packed));
+};
 
 struct jffs2_raw_dirent
 {
@@ -129,7 +129,7 @@ struct jffs2_raw_dirent
        jint32_t node_crc;
        jint32_t name_crc;
        uint8_t name[0];
-} __attribute__((packed));
+};
 
 /* The JFFS2 raw inode structure: Used for storage on physical media.  */
 /* The uid, gid, atime, mtime and ctime members could be longer, but
@@ -161,7 +161,7 @@ struct jffs2_raw_inode
        jint32_t data_crc;   /* CRC for the (compressed) data.  */
        jint32_t node_crc;   /* CRC for the raw inode (excluding data)  */
        uint8_t data[0];
-} __attribute__((packed));
+};
 
 struct jffs2_raw_xattr {
        jint16_t magic;
@@ -201,7 +201,7 @@ struct jffs2_raw_summary
        jint32_t sum_crc;       /* summary information crc */
        jint32_t node_crc;      /* node crc */
        jint32_t sum[0];        /* inode summary info */
-} __attribute__((packed));
+};
 
 union jffs2_node_union
 {
index e1bd084..f4fc576 100644 (file)
@@ -124,6 +124,7 @@ extern int get_option(char **str, int *pint);
 extern char *get_options(const char *str, int nints, int *ints);
 extern unsigned long long memparse(char *ptr, char **retptr);
 
+extern int core_kernel_text(unsigned long addr);
 extern int __kernel_text_address(unsigned long addr);
 extern int kernel_text_address(unsigned long addr);
 extern int session_of_pgrp(int pgrp);
index 30dd978..991a373 100644 (file)
@@ -28,6 +28,7 @@ struct mmc_csd {
        unsigned short          cmdclass;
        unsigned short          tacc_clks;
        unsigned int            tacc_ns;
+       unsigned int            r2w_factor;
        unsigned int            max_dtr;
        unsigned int            read_blkbits;
        unsigned int            write_blkbits;
index b6f2fda..73620ef 100644 (file)
@@ -61,7 +61,7 @@ struct mtd_info {
        u_int32_t flags;
        u_int32_t size;  // Total size of the MTD
 
-       /* "Major" erase size for the device. Naïve users may take this
+       /* "Major" erase size for the device. Naïve users may take this
         * to be the only erase size available, or may use the more detailed
         * information below if they desire
         */
index 50f9544..86831e3 100644 (file)
  */
 
 #ifndef __LINUX_MTD_PHYSMAP__
-
-#include <linux/config.h>
-
-#if defined(CONFIG_MTD_PHYSMAP)
+#define __LINUX_MTD_PHYSMAP__
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
@@ -37,7 +34,7 @@ struct physmap_flash_data {
 void physmap_configure(unsigned long addr, unsigned long size,
                int bankwidth, void (*set_vpp)(struct map_info *, int) );
 
-#if defined(CONFIG_MTD_PARTITIONS)
+#ifdef CONFIG_MTD_PARTITIONS
 
 /*
  * Machines that wish to do flash partition may want to call this function in
@@ -51,6 +48,5 @@ void physmap_configure(unsigned long addr, unsigned long size,
 void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
 
 #endif /* defined(CONFIG_MTD_PARTITIONS) */
-#endif /* defined(CONFIG_MTD) */
 
 #endif /* __LINUX_MTD_PHYSMAP__ */
index 01db7b8..f4169bb 100644 (file)
@@ -433,8 +433,7 @@ struct net_device
 
        /* register/unregister state machine */
        enum { NETREG_UNINITIALIZED=0,
-              NETREG_REGISTERING,      /* called register_netdevice */
-              NETREG_REGISTERED,       /* completed register todo */
+              NETREG_REGISTERED,       /* completed register_netdevice */
               NETREG_UNREGISTERING,    /* called unregister_netdevice */
               NETREG_UNREGISTERED,     /* completed unregister todo */
               NETREG_RELEASED,         /* called free_netdev */
@@ -506,6 +505,8 @@ struct net_device
 
        /* class/net/name entry */
        struct class_device     class_dev;
+       /* space for optional statistics and wireless sysfs groups */
+       struct attribute_group  *sysfs_groups[3];
 };
 
 #define        NETDEV_ALIGN            32
@@ -829,21 +830,19 @@ static inline void netif_rx_schedule(struct net_device *dev)
                __netif_rx_schedule(dev);
 }
 
-
-static inline void  __netif_rx_reschedule(struct net_device *dev, int undo)
-{
-       dev->quota += undo;
-       list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
-       __raise_softirq_irqoff(NET_RX_SOFTIRQ);
-}
-
-/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */
+/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete().
+ * Do not inline this?
+ */
 static inline int netif_rx_reschedule(struct net_device *dev, int undo)
 {
        if (netif_rx_schedule_prep(dev)) {
                unsigned long flags;
+
+               dev->quota += undo;
+
                local_irq_save(flags);
-               __netif_rx_reschedule(dev, undo);
+               list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
+               __raise_softirq_irqoff(NET_RX_SOFTIRQ);
                local_irq_restore(flags);
                return 1;
        }
index 0bd8280..c6e9a0b 100644 (file)
@@ -2,7 +2,7 @@
  * ip_conntrack_helper_h323_asn1.h - BER and PER decoding library for H.323
  *                                  conntrack/NAT module.
  *
- * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com>
+ * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
  *
  * This source code is licensed under General Public License version 2.
  *
index ba73108..ea4f7cd 100644 (file)
@@ -5,8 +5,9 @@
 
 #define PIPE_BUFFERS (16)
 
-#define PIPE_BUF_FLAG_ATOMIC   0x01    /* was atomically mapped */
-#define PIPE_BUF_FLAG_GIFT     0x02    /* page is a gift */
+#define PIPE_BUF_FLAG_LRU      0x01    /* page is on the LRU */
+#define PIPE_BUF_FLAG_ATOMIC   0x02    /* was atomically mapped */
+#define PIPE_BUF_FLAG_GIFT     0x04    /* page is a gift */
 
 struct pipe_buffer {
        struct page *page;
index 5673008..970284f 100644 (file)
@@ -132,6 +132,7 @@ static inline void rcu_bh_qsctr_inc(int cpu)
 }
 
 extern int rcu_pending(int cpu);
+extern int rcu_needs_cpu(int cpu);
 
 /**
  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
index c32e60e..bd14858 100644 (file)
@@ -254,6 +254,7 @@ struct uart_port {
 #define UPF_CONS_FLOW          ((__force upf_t) (1 << 23))
 #define UPF_SHARE_IRQ          ((__force upf_t) (1 << 24))
 #define UPF_BOOT_AUTOCONF      ((__force upf_t) (1 << 28))
+#define UPF_DEAD               ((__force upf_t) (1 << 30))
 #define UPF_IOREMAP            ((__force upf_t) (1 << 31))
 
 #define UPF_CHANGE_MASK                ((__force upf_t) (0x17fff))
index 3af03b1..2d985d5 100644 (file)
@@ -150,6 +150,7 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
 
 extern void kfree(const void *);
 extern unsigned int ksize(const void *);
+extern int slab_is_available(void);
 
 #ifdef CONFIG_NUMA
 extern void *kmem_cache_alloc_node(kmem_cache_t *, gfp_t flags, int node);
index 5b1fdf1..f03c247 100644 (file)
@@ -296,7 +296,7 @@ static inline void disable_swap_token(void)
 #define read_swap_cache_async(swp,vma,addr)    NULL
 #define lookup_swap_cache(swp)                 NULL
 #define valid_swaphandles(swp, off)            0
-#define can_share_swap_page(p)                 0
+#define can_share_swap_page(p)                 (page_mapcount(p) == 1)
 #define move_to_swap_cache(p, swp)             1
 #define move_from_swap_cache(p, i, m)          1
 #define __delete_from_swap_cache(p)            /*NOTHING*/
index d052b22..5bd9974 100644 (file)
@@ -145,14 +145,14 @@ enum {
 #define        AX25_DEF_CONMODE        2                       /* Connected mode allowed */
 #define        AX25_DEF_WINDOW         2                       /* Window=2 */
 #define        AX25_DEF_EWINDOW        32                      /* Module-128 Window=32 */
-#define        AX25_DEF_T1             (10 * HZ)               /* T1=10s */
-#define        AX25_DEF_T2             (3 * HZ)                /* T2=3s  */
-#define        AX25_DEF_T3             (300 * HZ)              /* T3=300s */
+#define        AX25_DEF_T1             10000                   /* T1=10s */
+#define        AX25_DEF_T2             3000                    /* T2=3s  */
+#define        AX25_DEF_T3             300000                  /* T3=300s */
 #define        AX25_DEF_N2             10                      /* N2=10 */
-#define AX25_DEF_IDLE          (0 * 60 * HZ)           /* Idle=None */
+#define AX25_DEF_IDLE          0                       /* Idle=None */
 #define AX25_DEF_PACLEN                256                     /* Paclen=256 */
 #define        AX25_DEF_PROTOCOL       AX25_PROTO_STD_SIMPLEX  /* Standard AX.25 */
-#define AX25_DEF_DS_TIMEOUT    (3 * 60 * HZ)           /* DAMA timeout 3 minutes */
+#define AX25_DEF_DS_TIMEOUT    180000                  /* DAMA timeout 3 minutes */
 
 typedef struct ax25_uid_assoc {
        struct hlist_node       uid_node;
index 4725ff8..d5926bf 100644 (file)
@@ -955,11 +955,13 @@ enum ieee80211_state {
 
 #define IEEE80211_24GHZ_MIN_CHANNEL 1
 #define IEEE80211_24GHZ_MAX_CHANNEL 14
-#define IEEE80211_24GHZ_CHANNELS    14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+                                 IEEE80211_24GHZ_MIN_CHANNEL + 1)
 
 #define IEEE80211_52GHZ_MIN_CHANNEL 34
 #define IEEE80211_52GHZ_MAX_CHANNEL 165
-#define IEEE80211_52GHZ_CHANNELS    131
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+                                 IEEE80211_52GHZ_MIN_CHANNEL + 1)
 
 enum {
        IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
index b1ebfba..052ed59 100644 (file)
@@ -204,7 +204,8 @@ struct ieee80211softmac_device {
        
        /* couple of flags */
        u8 scanning:1, /* protects scanning from being done multiple times at once */
-          associated:1;
+          associated:1,
+          running:1;
        
        struct ieee80211softmac_scaninfo *scaninfo;
        struct ieee80211softmac_assoc_info associnfo;
index b0666d6..4901ee4 100644 (file)
@@ -211,6 +211,7 @@ struct neigh_table
 #define NEIGH_UPDATE_F_ADMIN                   0x80000000
 
 extern void                    neigh_table_init(struct neigh_table *tbl);
+extern void                    neigh_table_init_no_netlink(struct neigh_table *tbl);
 extern int                     neigh_table_clear(struct neigh_table *tbl);
 extern struct neighbour *      neigh_lookup(struct neigh_table *tbl,
                                             const void *pkey,
index a5ee53b..e0ca112 100644 (file)
@@ -42,11 +42,11 @@ enum {
 #define        NR_COND_PEER_RX_BUSY            0x04
 #define        NR_COND_OWN_RX_BUSY             0x08
 
-#define NR_DEFAULT_T1                  (120 * HZ)      /* Outstanding frames - 120 seconds */
-#define NR_DEFAULT_T2                  (5   * HZ)      /* Response delay     - 5 seconds */
+#define NR_DEFAULT_T1                  120000          /* Outstanding frames - 120 seconds */
+#define NR_DEFAULT_T2                  5000            /* Response delay     - 5 seconds */
 #define NR_DEFAULT_N2                  3               /* Number of Retries - 3 */
-#define        NR_DEFAULT_T4                   (180 * HZ)      /* Busy Delay - 180 seconds */
-#define        NR_DEFAULT_IDLE                 (0 * 60 * HZ)   /* No Activity Timeout - none */
+#define        NR_DEFAULT_T4                   180000          /* Busy Delay - 180 seconds */
+#define        NR_DEFAULT_IDLE                 0               /* No Activity Timeout - none */
 #define        NR_DEFAULT_WINDOW               4               /* Default Window Size - 4 */
 #define        NR_DEFAULT_OBS                  6               /* Default Obsolescence Count - 6 */
 #define        NR_DEFAULT_QUAL                 10              /* Default Neighbour Quality - 10 */
index 3249b97..012b09e 100644 (file)
@@ -49,14 +49,14 @@ enum {
        ROSE_STATE_5                    /* Deferred Call Acceptance */
 };
 
-#define ROSE_DEFAULT_T0                        (180 * HZ)      /* Default T10 T20 value */
-#define ROSE_DEFAULT_T1                        (200 * HZ)      /* Default T11 T21 value */
-#define ROSE_DEFAULT_T2                        (180 * HZ)      /* Default T12 T22 value */
-#define        ROSE_DEFAULT_T3                 (180 * HZ)      /* Default T13 T23 value */
-#define        ROSE_DEFAULT_HB                 (5 * HZ)        /* Default Holdback value */
-#define        ROSE_DEFAULT_IDLE               (0 * 60 * HZ)   /* No Activity Timeout - none */
+#define ROSE_DEFAULT_T0                        180000          /* Default T10 T20 value */
+#define ROSE_DEFAULT_T1                        200000          /* Default T11 T21 value */
+#define ROSE_DEFAULT_T2                        180000          /* Default T12 T22 value */
+#define        ROSE_DEFAULT_T3                 180000          /* Default T13 T23 value */
+#define        ROSE_DEFAULT_HB                 5000            /* Default Holdback value */
+#define        ROSE_DEFAULT_IDLE               0               /* No Activity Timeout - none */
 #define        ROSE_DEFAULT_ROUTING            1               /* Default routing flag */
-#define        ROSE_DEFAULT_FAIL_TIMEOUT       (120 * HZ)      /* Time until link considered usable */
+#define        ROSE_DEFAULT_FAIL_TIMEOUT       120000          /* Time until link considered usable */
 #define        ROSE_DEFAULT_MAXVC              50              /* Maximum number of VCs per neighbour */
 #define        ROSE_DEFAULT_WINDOW_SIZE        7               /* Default window size */
 
index eba99f3..7f4fea1 100644 (file)
@@ -712,6 +712,7 @@ struct sctp_chunk {
        __u8 tsn_gap_acked;     /* Is this chunk acked by a GAP ACK? */
        __s8 fast_retransmit;    /* Is this chunk fast retransmitted? */
        __u8 tsn_missing_report; /* Data chunk missing counter. */
+       __u8 data_accepted;     /* At least 1 chunk in this packet accepted */
 };
 
 void sctp_chunk_hold(struct sctp_chunk *);
index 6c2681d..637f77e 100644 (file)
@@ -95,14 +95,15 @@ struct srp_direct_buf {
 
 /*
  * We need the packed attribute because the SRP spec puts the list of
- * descriptors at an offset of 20, which is not aligned to the size
- * of struct srp_direct_buf.
+ * descriptors at an offset of 20, which is not aligned to the size of
+ * struct srp_direct_buf.  The whole structure must be packed to avoid
+ * having the 20-byte structure padded to 24 bytes on 64-bit architectures.
  */
 struct srp_indirect_buf {
        struct srp_direct_buf   table_desc;
        __be32                  len;
-       struct srp_direct_buf   desc_list[0] __attribute__((packed));
-};
+       struct srp_direct_buf   desc_list[0];
+} __attribute__((packed));
 
 enum {
        SRP_MULTICHAN_SINGLE = 0,
@@ -122,6 +123,11 @@ struct srp_login_req {
        u8      target_port_id[16];
 };
 
+/*
+ * The SRP spec defines the size of the LOGIN_RSP structure to be 52
+ * bytes, so it needs to be packed to avoid having it padded to 56
+ * bytes on 64-bit architectures.
+ */
 struct srp_login_rsp {
        u8      opcode;
        u8      reserved1[3];
@@ -132,7 +138,7 @@ struct srp_login_rsp {
        __be16  buf_fmt;
        u8      rsp_flags;
        u8      reserved2[25];
-};
+} __attribute__((packed));
 
 struct srp_login_rej {
        u8      opcode;
@@ -207,6 +213,11 @@ enum {
        SRP_RSP_FLAG_DIUNDER  = 1 << 5
 };
 
+/*
+ * The SRP spec defines the size of the RSP structure to be 36 bytes,
+ * so it needs to be packed to avoid having it padded to 40 bytes on
+ * 64-bit architectures.
+ */
 struct srp_rsp {
        u8      opcode;
        u8      sol_not;
@@ -221,6 +232,6 @@ struct srp_rsp {
        __be32  sense_data_len;
        __be32  resp_data_len;
        u8      data[0];
-};
+} __attribute__((packed));
 
 #endif /* SCSI_SRP_H */
index adb7cad..f4b7b9d 100644 (file)
@@ -310,6 +310,11 @@ retry:
 
                panic("VFS: Unable to mount root fs on %s", b);
        }
+
+       printk("No filesystem could mount root, tried: ");
+       for (p = fs_names; *p; p += strlen(p)+1)
+               printk(" %s", p);
+       printk("\n");
        panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
 out:
        putname(fs_names);
index 679d870..f81cfa4 100644 (file)
@@ -26,10 +26,12 @@ static void __init free(void *where)
 
 /* link hash */
 
+#define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
+
 static __initdata struct hash {
        int ino, minor, major;
        struct hash *next;
-       char *name;
+       char name[N_ALIGN(PATH_MAX)];
 } *head[32];
 
 static inline int hash(int major, int minor, int ino)
@@ -57,7 +59,7 @@ static char __init *find_link(int major, int minor, int ino, char *name)
        q->ino = ino;
        q->minor = minor;
        q->major = major;
-       q->name = name;
+       strcpy(q->name, name);
        q->next = NULL;
        *p = q;
        return NULL;
@@ -133,8 +135,6 @@ static inline void eat(unsigned n)
        count -= n;
 }
 
-#define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
-
 static __initdata char *collected;
 static __initdata int remains;
 static __initdata char *collect;
index 7501b53..7fe2628 100644 (file)
@@ -40,7 +40,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr)
        return e;
 }
 
-static int core_kernel_text(unsigned long addr)
+int core_kernel_text(unsigned long addr)
 {
        if (addr >= (unsigned long)_stext &&
            addr <= (unsigned long)_etext)
index d24deb0..bbe0486 100644 (file)
@@ -705,14 +705,14 @@ EXPORT_SYMBOL(__symbol_put);
 
 void symbol_put_addr(void *addr)
 {
-       unsigned long flags;
+       struct module *modaddr;
 
-       spin_lock_irqsave(&modlist_lock, flags);
-       if (!kernel_text_address((unsigned long)addr))
-               BUG();
+       if (core_kernel_text((unsigned long)addr))
+               return;
 
-       module_put(module_text_address((unsigned long)addr));
-       spin_unlock_irqrestore(&modlist_lock, flags);
+       if (!(modaddr = module_text_address((unsigned long)addr)))
+               BUG();
+       module_put(modaddr);
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
index 4e0f0ec..921c22a 100644 (file)
@@ -148,12 +148,34 @@ int ptrace_may_attach(struct task_struct *task)
 int ptrace_attach(struct task_struct *task)
 {
        int retval;
-       task_lock(task);
+
        retval = -EPERM;
        if (task->pid <= 1)
-               goto bad;
+               goto out;
        if (task->tgid == current->tgid)
-               goto bad;
+               goto out;
+
+repeat:
+       /*
+        * Nasty, nasty.
+        *
+        * We want to hold both the task-lock and the
+        * tasklist_lock for writing at the same time.
+        * But that's against the rules (tasklist_lock
+        * is taken for reading by interrupts on other
+        * cpu's that may have task_lock).
+        */
+       task_lock(task);
+       local_irq_disable();
+       if (!write_trylock(&tasklist_lock)) {
+               local_irq_enable();
+               task_unlock(task);
+               do {
+                       cpu_relax();
+               } while (!write_can_lock(&tasklist_lock));
+               goto repeat;
+       }
+
        /* the same process cannot be attached many times */
        if (task->ptrace & PT_PTRACED)
                goto bad;
@@ -166,17 +188,15 @@ int ptrace_attach(struct task_struct *task)
                                      ? PT_ATTACHED : 0);
        if (capable(CAP_SYS_PTRACE))
                task->ptrace |= PT_PTRACE_CAP;
-       task_unlock(task);
 
-       write_lock_irq(&tasklist_lock);
        __ptrace_link(task, current);
-       write_unlock_irq(&tasklist_lock);
 
        force_sig_specific(SIGSTOP, task);
-       return 0;
 
 bad:
+       write_unlock_irq(&tasklist_lock);
        task_unlock(task);
+out:
        return retval;
 }
 
@@ -417,21 +437,22 @@ int ptrace_request(struct task_struct *child, long request,
  */
 int ptrace_traceme(void)
 {
-       int ret;
+       int ret = -EPERM;
 
        /*
         * Are we already being traced?
         */
-       if (current->ptrace & PT_PTRACED)
-               return -EPERM;
-       ret = security_ptrace(current->parent, current);
-       if (ret)
-               return -EPERM;
-       /*
-        * Set the ptrace bit in the process ptrace flags.
-        */
-       current->ptrace |= PT_PTRACED;
-       return 0;
+       task_lock(current);
+       if (!(current->ptrace & PT_PTRACED)) {
+               ret = security_ptrace(current->parent, current);
+               /*
+                * Set the ptrace bit in the process ptrace flags.
+                */
+               if (!ret)
+                       current->ptrace |= PT_PTRACED;
+       }
+       task_unlock(current);
+       return ret;
 }
 
 /**
index 6d32ff2..2058f88 100644 (file)
@@ -479,12 +479,31 @@ static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp)
        return 0;
 }
 
+/*
+ * Check to see if there is any immediate RCU-related work to be done
+ * by the current CPU, returning 1 if so.  This function is part of the
+ * RCU implementation; it is -not- an exported member of the RCU API.
+ */
 int rcu_pending(int cpu)
 {
        return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) ||
                __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
 }
 
+/*
+ * Check to see if any future RCU-related work will need to be done
+ * by the current CPU, even if none need be done immediately, returning
+ * 1 if so.  This function is part of the RCU implementation; it is -not-
+ * an exported member of the RCU API.
+ */
+int rcu_needs_cpu(int cpu)
+{
+       struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+       struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu);
+
+       return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu));
+}
+
 void rcu_check_callbacks(int cpu, int user)
 {
        if (user || 
index 6ecc180..ccb0c1f 100644 (file)
@@ -189,7 +189,7 @@ config FRAME_POINTER
 config UNWIND_INFO
        bool "Compile the kernel with frame unwind information"
        depends on !IA64
-       depends on !MODULES || !(MIPS || PARISC || PPC || SUPERH || SPARC64 || V850)
+       depends on !MODULES || !(MIPS || PARISC || PPC || SUPERH || V850)
        help
          If you say Y here the resulting kernel image will be slightly larger
          but not slower, and it will give very useful debugging information.
index ea77c99..813b4ec 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/mempolicy.h>
 
 #include <asm/tlbflush.h>
+#include <asm/div64.h>
 #include "internal.h"
 
 /*
@@ -2566,9 +2567,11 @@ void setup_per_zone_pages_min(void)
        }
 
        for_each_zone(zone) {
-               unsigned long tmp;
+               u64 tmp;
+
                spin_lock_irqsave(&zone->lru_lock, flags);
-               tmp = (pages_min * zone->present_pages) / lowmem_pages;
+               tmp = (u64)pages_min * zone->present_pages;
+               do_div(tmp, lowmem_pages);
                if (is_highmem(zone)) {
                        /*
                         * __GFP_HIGH and PF_MEMALLOC allocations usually don't
@@ -2595,8 +2598,8 @@ void setup_per_zone_pages_min(void)
                        zone->pages_min = tmp;
                }
 
-               zone->pages_low   = zone->pages_min + tmp / 4;
-               zone->pages_high  = zone->pages_min + tmp / 2;
+               zone->pages_low   = zone->pages_min + (tmp >> 2);
+               zone->pages_high  = zone->pages_min + (tmp >> 1);
                spin_unlock_irqrestore(&zone->lru_lock, flags);
        }
 
index c32af7e..b1d643b 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -700,6 +700,14 @@ static enum {
        FULL
 } g_cpucache_up;
 
+/*
+ * used by boot code to determine if it can use slab based allocator
+ */
+int slab_is_available(void)
+{
+       return g_cpucache_up == FULL;
+}
+
 static DEFINE_PER_CPU(struct work_struct, reap_work);
 
 static void free_block(struct kmem_cache *cachep, void **objpp, int len,
index d7c32de..c5e89eb 100644 (file)
@@ -32,7 +32,7 @@ static struct mem_section *sparse_index_alloc(int nid)
        unsigned long array_size = SECTIONS_PER_ROOT *
                                   sizeof(struct mem_section);
 
-       if (system_state == SYSTEM_RUNNING)
+       if (slab_is_available())
                section = kmalloc_node(array_size, GFP_KERNEL, nid);
        else
                section = alloc_bootmem_node(NODE_DATA(nid), array_size);
index 1a786bf..72d8529 100644 (file)
@@ -963,7 +963,7 @@ static struct file_operations arp_seq_fops = {
 static int __init atm_clip_init(void)
 {
        struct proc_dir_entry *p;
-       neigh_table_init(&clip_tbl);
+       neigh_table_init_no_netlink(&clip_tbl);
 
        clip_tbl_hook = &clip_tbl;
        register_atm_ioctl(&clip_ioctl_ops);
index dbf9b47..a2e0dd0 100644 (file)
@@ -228,6 +228,8 @@ ax25_cb *ax25_find_cb(ax25_address *src_addr, ax25_address *dest_addr,
        return NULL;
 }
 
+EXPORT_SYMBOL(ax25_find_cb);
+
 void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto)
 {
        ax25_cb *s;
@@ -424,6 +426,26 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
        return 0;
 }
 
+static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev)
+{
+       ax25->rtt     = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
+       ax25->t1      = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
+       ax25->t2      = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T2]);
+       ax25->t3      = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T3]);
+       ax25->n2      = ax25_dev->values[AX25_VALUES_N2];
+       ax25->paclen  = ax25_dev->values[AX25_VALUES_PACLEN];
+       ax25->idle    = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_IDLE]);
+       ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF];
+
+       if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) {
+               ax25->modulus = AX25_EMODULUS;
+               ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];
+       } else {
+               ax25->modulus = AX25_MODULUS;
+               ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];
+       }
+}
+
 /*
  *     Fill in a created AX.25 created control block with the default
  *     values for a particular device.
@@ -433,39 +455,28 @@ void ax25_fillin_cb(ax25_cb *ax25, ax25_dev *ax25_dev)
        ax25->ax25_dev = ax25_dev;
 
        if (ax25->ax25_dev != NULL) {
-               ax25->rtt     = ax25_dev->values[AX25_VALUES_T1] / 2;
-               ax25->t1      = ax25_dev->values[AX25_VALUES_T1];
-               ax25->t2      = ax25_dev->values[AX25_VALUES_T2];
-               ax25->t3      = ax25_dev->values[AX25_VALUES_T3];
-               ax25->n2      = ax25_dev->values[AX25_VALUES_N2];
-               ax25->paclen  = ax25_dev->values[AX25_VALUES_PACLEN];
-               ax25->idle    = ax25_dev->values[AX25_VALUES_IDLE];
-               ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF];
-
-               if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) {
-                       ax25->modulus = AX25_EMODULUS;
-                       ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];
-               } else {
-                       ax25->modulus = AX25_MODULUS;
-                       ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];
-               }
+               ax25_fillin_cb_from_dev(ax25, ax25_dev);
+               return;
+       }
+
+       /*
+        * No device, use kernel / AX.25 spec default values
+        */
+       ax25->rtt     = msecs_to_jiffies(AX25_DEF_T1) / 2;
+       ax25->t1      = msecs_to_jiffies(AX25_DEF_T1);
+       ax25->t2      = msecs_to_jiffies(AX25_DEF_T2);
+       ax25->t3      = msecs_to_jiffies(AX25_DEF_T3);
+       ax25->n2      = AX25_DEF_N2;
+       ax25->paclen  = AX25_DEF_PACLEN;
+       ax25->idle    = msecs_to_jiffies(AX25_DEF_IDLE);
+       ax25->backoff = AX25_DEF_BACKOFF;
+
+       if (AX25_DEF_AXDEFMODE) {
+               ax25->modulus = AX25_EMODULUS;
+               ax25->window  = AX25_DEF_EWINDOW;
        } else {
-               ax25->rtt     = AX25_DEF_T1 / 2;
-               ax25->t1      = AX25_DEF_T1;
-               ax25->t2      = AX25_DEF_T2;
-               ax25->t3      = AX25_DEF_T3;
-               ax25->n2      = AX25_DEF_N2;
-               ax25->paclen  = AX25_DEF_PACLEN;
-               ax25->idle    = AX25_DEF_IDLE;
-               ax25->backoff = AX25_DEF_BACKOFF;
-
-               if (AX25_DEF_AXDEFMODE) {
-                       ax25->modulus = AX25_EMODULUS;
-                       ax25->window  = AX25_DEF_EWINDOW;
-               } else {
-                       ax25->modulus = AX25_MODULUS;
-                       ax25->window  = AX25_DEF_WINDOW;
-               }
+               ax25->modulus = AX25_MODULUS;
+               ax25->window  = AX25_DEF_WINDOW;
        }
 }
 
@@ -1979,24 +1990,6 @@ static struct notifier_block ax25_dev_notifier = {
        .notifier_call =ax25_device_event,
 };
 
-EXPORT_SYMBOL(ax25_hard_header);
-EXPORT_SYMBOL(ax25_rebuild_header);
-EXPORT_SYMBOL(ax25_findbyuid);
-EXPORT_SYMBOL(ax25_find_cb);
-EXPORT_SYMBOL(ax25_linkfail_register);
-EXPORT_SYMBOL(ax25_linkfail_release);
-EXPORT_SYMBOL(ax25_listen_register);
-EXPORT_SYMBOL(ax25_listen_release);
-EXPORT_SYMBOL(ax25_protocol_register);
-EXPORT_SYMBOL(ax25_protocol_release);
-EXPORT_SYMBOL(ax25_send_frame);
-EXPORT_SYMBOL(ax25_uid_policy);
-EXPORT_SYMBOL(ax25cmp);
-EXPORT_SYMBOL(ax2asc);
-EXPORT_SYMBOL(asc2ax);
-EXPORT_SYMBOL(null_ax25_address);
-EXPORT_SYMBOL(ax25_display_timer);
-
 static int __init ax25_init(void)
 {
        int rc = proto_register(&ax25_proto, 0);
index 0164a15..5f0896a 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
@@ -33,6 +34,8 @@
  */
 ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}};
 
+EXPORT_SYMBOL(null_ax25_address);
+
 /*
  *     ax25 -> ascii conversion
  */
@@ -64,6 +67,8 @@ char *ax2asc(char *buf, ax25_address *a)
 
 }
 
+EXPORT_SYMBOL(ax2asc);
+
 /*
  *     ascii -> ax25 conversion
  */
@@ -97,6 +102,8 @@ void asc2ax(ax25_address *addr, char *callsign)
        addr->ax25_call[6] &= 0x1E;
 }
 
+EXPORT_SYMBOL(asc2ax);
+
 /*
  *     Compare two ax.25 addresses
  */
@@ -116,6 +123,8 @@ int ax25cmp(ax25_address *a, ax25_address *b)
        return 2;                       /* Partial match */
 }
 
+EXPORT_SYMBOL(ax25cmp);
+
 /*
  *     Compare two AX.25 digipeater paths.
  */
index 061083e..5961459 100644 (file)
@@ -61,7 +61,8 @@ void ax25_ds_set_timer(ax25_dev *ax25_dev)
                return;
 
        del_timer(&ax25_dev->dama.slave_timer);
-       ax25_dev->dama.slave_timeout = ax25_dev->values[AX25_VALUES_DS_TIMEOUT] / 10;
+       ax25_dev->dama.slave_timeout =
+               msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
        ax25_ds_add_timer(ax25_dev);
 }
 
index d68aff1..3bb1527 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
@@ -74,6 +75,8 @@ int ax25_protocol_register(unsigned int pid,
        return 1;
 }
 
+EXPORT_SYMBOL(ax25_protocol_register);
+
 void ax25_protocol_release(unsigned int pid)
 {
        struct protocol_struct *s, *protocol;
@@ -106,6 +109,8 @@ void ax25_protocol_release(unsigned int pid)
        write_unlock(&protocol_list_lock);
 }
 
+EXPORT_SYMBOL(ax25_protocol_release);
+
 int ax25_linkfail_register(void (*func)(ax25_cb *, int))
 {
        struct linkfail_struct *linkfail;
@@ -123,6 +128,8 @@ int ax25_linkfail_register(void (*func)(ax25_cb *, int))
        return 1;
 }
 
+EXPORT_SYMBOL(ax25_linkfail_register);
+
 void ax25_linkfail_release(void (*func)(ax25_cb *, int))
 {
        struct linkfail_struct *s, *linkfail;
@@ -155,6 +162,8 @@ void ax25_linkfail_release(void (*func)(ax25_cb *, int))
        spin_unlock_bh(&linkfail_lock);
 }
 
+EXPORT_SYMBOL(ax25_linkfail_release);
+
 int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
 {
        struct listen_struct *listen;
@@ -176,6 +185,8 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
        return 1;
 }
 
+EXPORT_SYMBOL(ax25_listen_register);
+
 void ax25_listen_release(ax25_address *callsign, struct net_device *dev)
 {
        struct listen_struct *s, *listen;
@@ -208,6 +219,8 @@ void ax25_listen_release(ax25_address *callsign, struct net_device *dev)
        spin_unlock_bh(&listen_lock);
 }
 
+EXPORT_SYMBOL(ax25_listen_release);
+
 int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
 {
        int (*res)(struct sk_buff *, ax25_cb *) = NULL;
index d643dac..a0b534f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
@@ -221,3 +222,5 @@ int ax25_rebuild_header(struct sk_buff *skb)
 
 #endif
 
+EXPORT_SYMBOL(ax25_hard_header);
+EXPORT_SYMBOL(ax25_rebuild_header);
index 5fc048d..5d99852 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
@@ -104,6 +105,8 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax2
        return ax25;                    /* We had to create it */
 }
 
+EXPORT_SYMBOL(ax25_send_frame);
+
 /*
  *     All outgoing AX.25 I frames pass via this routine. Therefore this is
  *     where the fragmentation of frames takes place. If fragment is set to
index f04f863..5ac9825 100644 (file)
@@ -360,7 +360,7 @@ struct file_operations ax25_route_fops = {
 /*
  *     Find AX.25 route
  *
- *     Only routes with a refernce rout of zero can be destroyed.
+ *     Only routes with a reference count of zero can be destroyed.
  */
 static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
 {
index 7a6b50a..ec25405 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
 #include <linux/string.h>
@@ -137,6 +138,8 @@ unsigned long ax25_display_timer(struct timer_list *timer)
        return timer->expires - jiffies;
 }
 
+EXPORT_SYMBOL(ax25_display_timer);
+
 static void ax25_heartbeat_expiry(unsigned long param)
 {
        int proto = AX25_PROTO_STD_SIMPLEX;
index b8b5854..5e9a81e 100644 (file)
@@ -49,6 +49,8 @@ static DEFINE_RWLOCK(ax25_uid_lock);
 
 int ax25_uid_policy = 0;
 
+EXPORT_SYMBOL(ax25_uid_policy);
+
 ax25_uid_assoc *ax25_findbyuid(uid_t uid)
 {
        ax25_uid_assoc *ax25_uid, *res = NULL;
@@ -67,6 +69,8 @@ ax25_uid_assoc *ax25_findbyuid(uid_t uid)
        return res;
 }
 
+EXPORT_SYMBOL(ax25_findbyuid);
+
 int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
 {
        ax25_uid_assoc *ax25_uid;
index 894a225..bdb64c3 100644 (file)
@@ -18,14 +18,14 @@ static int min_backoff[1],          max_backoff[] = {2};
 static int min_conmode[1],             max_conmode[] = {2};
 static int min_window[] = {1},         max_window[] = {7};
 static int min_ewindow[] = {1},                max_ewindow[] = {63};
-static int min_t1[] = {1},             max_t1[] = {30 * HZ};
-static int min_t2[] = {1},             max_t2[] = {20 * HZ};
-static int min_t3[1],                  max_t3[] = {3600 * HZ};
-static int min_idle[1],                max_idle[] = {65535 * HZ};
+static int min_t1[] = {1},             max_t1[] = {30000};
+static int min_t2[] = {1},             max_t2[] = {20000};
+static int min_t3[1],                  max_t3[] = {3600000};
+static int min_idle[1],                        max_idle[] = {65535000};
 static int min_n2[] = {1},             max_n2[] = {31};
 static int min_paclen[] = {1},         max_paclen[] = {512};
 static int min_proto[1],               max_proto[] = { AX25_PROTO_MAX };
-static int min_ds_timeout[1],          max_ds_timeout[] = {65535 * HZ};
+static int min_ds_timeout[1],          max_ds_timeout[] = {65535000};
 
 static struct ctl_table_header *ax25_table_header;
 
index 59eef42..ad1c7af 100644 (file)
@@ -308,26 +308,19 @@ int br_add_bridge(const char *name)
        if (ret)
                goto err2;
 
-       /* network device kobject is not setup until
-        * after rtnl_unlock does it's hotplug magic.
-        * so hold reference to avoid race.
-        */
-       dev_hold(dev);
-       rtnl_unlock();
-
        ret = br_sysfs_addbr(dev);
-       dev_put(dev);
-
-       if (ret) 
-               unregister_netdev(dev);
- out:
-       return ret;
+       if (ret)
+               goto err3;
+       rtnl_unlock();
+       return 0;
 
+ err3:
+       unregister_netdev(dev);
  err2:
        free_netdev(dev);
  err1:
        rtnl_unlock();
-       goto out;
+       return ret;
 }
 
 int br_del_bridge(const char *name)
index b0b7f55..bfa4d8c 100644 (file)
@@ -66,6 +66,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
        }
 
        if (is_multicast_ether_addr(dest)) {
+               br->statistics.multicast++;
                br_flood_forward(br, skb, !passedup);
                if (!passedup)
                        br_pass_frame_up(br, skb);
index 3bad1af..2dce673 100644 (file)
@@ -193,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex)
  *     Our notifier list
  */
 
-static BLOCKING_NOTIFIER_HEAD(netdev_chain);
+static RAW_NOTIFIER_HEAD(netdev_chain);
 
 /*
  *     Device drivers call our routines to queue packets here. We empty the
@@ -736,7 +736,7 @@ int dev_change_name(struct net_device *dev, char *newname)
        if (!err) {
                hlist_del(&dev->name_hlist);
                hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
-               blocking_notifier_call_chain(&netdev_chain,
+               raw_notifier_call_chain(&netdev_chain,
                                NETDEV_CHANGENAME, dev);
        }
 
@@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
  */
 void netdev_features_change(struct net_device *dev)
 {
-       blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
+       raw_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
 }
 EXPORT_SYMBOL(netdev_features_change);
 
@@ -766,7 +766,7 @@ EXPORT_SYMBOL(netdev_features_change);
 void netdev_state_change(struct net_device *dev)
 {
        if (dev->flags & IFF_UP) {
-               blocking_notifier_call_chain(&netdev_chain,
+               raw_notifier_call_chain(&netdev_chain,
                                NETDEV_CHANGE, dev);
                rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
        }
@@ -864,7 +864,7 @@ int dev_open(struct net_device *dev)
                /*
                 *      ... and announce new interface.
                 */
-               blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
+               raw_notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
        }
        return ret;
 }
@@ -887,7 +887,7 @@ int dev_close(struct net_device *dev)
         *      Tell people we are going down, so that they can
         *      prepare to death, when device is still operating.
         */
-       blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
+       raw_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
 
        dev_deactivate(dev);
 
@@ -924,7 +924,7 @@ int dev_close(struct net_device *dev)
        /*
         * Tell people we are down
         */
-       blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
+       raw_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
 
        return 0;
 }
@@ -955,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
        int err;
 
        rtnl_lock();
-       err = blocking_notifier_chain_register(&netdev_chain, nb);
+       err = raw_notifier_chain_register(&netdev_chain, nb);
        if (!err) {
                for (dev = dev_base; dev; dev = dev->next) {
                        nb->notifier_call(nb, NETDEV_REGISTER, dev);
@@ -983,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
        int err;
 
        rtnl_lock();
-       err = blocking_notifier_chain_unregister(&netdev_chain, nb);
+       err = raw_notifier_chain_unregister(&netdev_chain, nb);
        rtnl_unlock();
        return err;
 }
@@ -994,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
  *      @v:   pointer passed unmodified to notifier function
  *
  *     Call all network notifier blocks.  Parameters and return value
- *     are as for blocking_notifier_call_chain().
+ *     are as for raw_notifier_call_chain().
  */
 
 int call_netdevice_notifiers(unsigned long val, void *v)
 {
-       return blocking_notifier_call_chain(&netdev_chain, val, v);
+       return raw_notifier_call_chain(&netdev_chain, val, v);
 }
 
 /* When > 0 there are consumers of rx skb time stamps */
@@ -2308,7 +2308,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
        if (dev->flags & IFF_UP &&
            ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
                                          IFF_VOLATILE)))
-               blocking_notifier_call_chain(&netdev_chain,
+               raw_notifier_call_chain(&netdev_chain,
                                NETDEV_CHANGE, dev);
 
        if ((flags ^ dev->gflags) & IFF_PROMISC) {
@@ -2353,7 +2353,7 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
        else
                dev->mtu = new_mtu;
        if (!err && dev->flags & IFF_UP)
-               blocking_notifier_call_chain(&netdev_chain,
+               raw_notifier_call_chain(&netdev_chain,
                                NETDEV_CHANGEMTU, dev);
        return err;
 }
@@ -2370,7 +2370,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
                return -ENODEV;
        err = dev->set_mac_address(dev, sa);
        if (!err)
-               blocking_notifier_call_chain(&netdev_chain,
+               raw_notifier_call_chain(&netdev_chain,
                                NETDEV_CHANGEADDR, dev);
        return err;
 }
@@ -2427,7 +2427,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
                                return -EINVAL;
                        memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
                               min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-                       blocking_notifier_call_chain(&netdev_chain,
+                       raw_notifier_call_chain(&netdev_chain,
                                            NETDEV_CHANGEADDR, dev);
                        return 0;
 
@@ -2777,6 +2777,8 @@ int register_netdevice(struct net_device *dev)
        BUG_ON(dev_boot_phase);
        ASSERT_RTNL();
 
+       might_sleep();
+
        /* When net_device's are persistent, this will be fatal. */
        BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 
@@ -2863,6 +2865,11 @@ int register_netdevice(struct net_device *dev)
        if (!dev->rebuild_header)
                dev->rebuild_header = default_rebuild_header;
 
+       ret = netdev_register_sysfs(dev);
+       if (ret)
+               goto out_err;
+       dev->reg_state = NETREG_REGISTERED;
+
        /*
         *      Default initial state at registry is that the
         *      device is present.
@@ -2878,14 +2885,11 @@ int register_netdevice(struct net_device *dev)
        hlist_add_head(&dev->name_hlist, head);
        hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
        dev_hold(dev);
-       dev->reg_state = NETREG_REGISTERING;
        write_unlock_bh(&dev_base_lock);
 
        /* Notify protocols, that a new device appeared. */
-       blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
+       raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
 
-       /* Finish registration after unlock */
-       net_set_todo(dev);
        ret = 0;
 
 out:
@@ -2961,7 +2965,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
                        rtnl_lock();
 
                        /* Rebroadcast unregister notification */
-                       blocking_notifier_call_chain(&netdev_chain,
+                       raw_notifier_call_chain(&netdev_chain,
                                            NETDEV_UNREGISTER, dev);
 
                        if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
@@ -3008,7 +3012,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
  *
  * We are invoked by rtnl_unlock() after it drops the semaphore.
  * This allows us to deal with problems:
- * 1) We can create/delete sysfs objects which invoke hotplug
+ * 1) We can delete sysfs objects which invoke hotplug
  *    without deadlocking with linkwatch via keventd.
  * 2) Since we run with the RTNL semaphore not held, we can sleep
  *    safely in order to wait for the netdev refcnt to drop to zero.
@@ -3017,8 +3021,6 @@ static DEFINE_MUTEX(net_todo_run_mutex);
 void netdev_run_todo(void)
 {
        struct list_head list = LIST_HEAD_INIT(list);
-       int err;
-
 
        /* Need to guard against multiple cpu's getting out of order. */
        mutex_lock(&net_todo_run_mutex);
@@ -3041,40 +3043,29 @@ void netdev_run_todo(void)
                        = list_entry(list.next, struct net_device, todo_list);
                list_del(&dev->todo_list);
 
-               switch(dev->reg_state) {
-               case NETREG_REGISTERING:
-                       dev->reg_state = NETREG_REGISTERED;
-                       err = netdev_register_sysfs(dev);
-                       if (err)
-                               printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
-                                      dev->name, err);
-                       break;
-
-               case NETREG_UNREGISTERING:
-                       netdev_unregister_sysfs(dev);
-                       dev->reg_state = NETREG_UNREGISTERED;
-
-                       netdev_wait_allrefs(dev);
+               if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
+                       printk(KERN_ERR "network todo '%s' but state %d\n",
+                              dev->name, dev->reg_state);
+                       dump_stack();
+                       continue;
+               }
 
-                       /* paranoia */
-                       BUG_ON(atomic_read(&dev->refcnt));
-                       BUG_TRAP(!dev->ip_ptr);
-                       BUG_TRAP(!dev->ip6_ptr);
-                       BUG_TRAP(!dev->dn_ptr);
+               netdev_unregister_sysfs(dev);
+               dev->reg_state = NETREG_UNREGISTERED;
 
+               netdev_wait_allrefs(dev);
 
-                       /* It must be the very last action, 
-                        * after this 'dev' may point to freed up memory.
-                        */
-                       if (dev->destructor)
-                               dev->destructor(dev);
-                       break;
+               /* paranoia */
+               BUG_ON(atomic_read(&dev->refcnt));
+               BUG_TRAP(!dev->ip_ptr);
+               BUG_TRAP(!dev->ip6_ptr);
+               BUG_TRAP(!dev->dn_ptr);
 
-               default:
-                       printk(KERN_ERR "network todo '%s' but state %d\n",
-                              dev->name, dev->reg_state);
-                       break;
-               }
+               /* It must be the very last action,
+                * after this 'dev' may point to freed up memory.
+                */
+               if (dev->destructor)
+                       dev->destructor(dev);
        }
 
 out:
@@ -3216,7 +3207,7 @@ int unregister_netdevice(struct net_device *dev)
        /* Notify protocols, that we are about to destroy
           this device. They should clean all the things.
        */
-       blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
+       raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
        
        /*
         *      Flush the multicast chain
index 341de44..646937c 100644 (file)
@@ -170,13 +170,13 @@ void linkwatch_fire_event(struct net_device *dev)
                spin_unlock_irqrestore(&lweventlist_lock, flags);
 
                if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) {
-                       unsigned long thisevent = jiffies;
+                       unsigned long delay = linkwatch_nextevent - jiffies;
 
-                       if (thisevent >= linkwatch_nextevent) {
+                       /* If we wrap around we'll delay it by at most HZ. */
+                       if (!delay || delay > HZ)
                                schedule_work(&linkwatch_work);
-                       } else {
-                               schedule_delayed_work(&linkwatch_work, linkwatch_nextevent - thisevent);
-                       }
+                       else
+                               schedule_delayed_work(&linkwatch_work, delay);
                }
        }
 }
index 4cf878e..50a8c73 100644 (file)
@@ -1326,8 +1326,7 @@ void neigh_parms_destroy(struct neigh_parms *parms)
        kfree(parms);
 }
 
-
-void neigh_table_init(struct neigh_table *tbl)
+void neigh_table_init_no_netlink(struct neigh_table *tbl)
 {
        unsigned long now = jiffies;
        unsigned long phsize;
@@ -1383,10 +1382,27 @@ void neigh_table_init(struct neigh_table *tbl)
 
        tbl->last_flush = now;
        tbl->last_rand  = now + tbl->parms.reachable_time * 20;
+}
+
+void neigh_table_init(struct neigh_table *tbl)
+{
+       struct neigh_table *tmp;
+
+       neigh_table_init_no_netlink(tbl);
        write_lock(&neigh_tbl_lock);
+       for (tmp = neigh_tables; tmp; tmp = tmp->next) {
+               if (tmp->family == tbl->family)
+                       break;
+       }
        tbl->next       = neigh_tables;
        neigh_tables    = tbl;
        write_unlock(&neigh_tbl_lock);
+
+       if (unlikely(tmp)) {
+               printk(KERN_ERR "NEIGH: Registering multiple tables for "
+                      "family %d\n", tbl->family);
+               dump_stack();
+       }
 }
 
 int neigh_table_clear(struct neigh_table *tbl)
@@ -2657,6 +2673,7 @@ EXPORT_SYMBOL(neigh_rand_reach_time);
 EXPORT_SYMBOL(neigh_resolve_output);
 EXPORT_SYMBOL(neigh_table_clear);
 EXPORT_SYMBOL(neigh_table_init);
+EXPORT_SYMBOL(neigh_table_init_no_netlink);
 EXPORT_SYMBOL(neigh_update);
 EXPORT_SYMBOL(neigh_update_hhs);
 EXPORT_SYMBOL(pneigh_enqueue);
index c12990c..47a6fce 100644 (file)
@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n";
 
 static inline int dev_isalive(const struct net_device *dev) 
 {
-       return dev->reg_state == NETREG_REGISTERED;
+       return dev->reg_state <= NETREG_REGISTERED;
 }
 
 /* use same locking rules as GIF* ioctl's */
@@ -445,58 +445,33 @@ static struct class net_class = {
 
 void netdev_unregister_sysfs(struct net_device * net)
 {
-       struct class_device * class_dev = &(net->class_dev);
-
-       if (net->get_stats)
-               sysfs_remove_group(&class_dev->kobj, &netstat_group);
-
-#ifdef WIRELESS_EXT
-       if (net->get_wireless_stats || (net->wireless_handlers &&
-                       net->wireless_handlers->get_wireless_stats))
-               sysfs_remove_group(&class_dev->kobj, &wireless_group);
-#endif
-       class_device_del(class_dev);
-
+       class_device_del(&(net->class_dev));
 }
 
 /* Create sysfs entries for network device. */
 int netdev_register_sysfs(struct net_device *net)
 {
        struct class_device *class_dev = &(net->class_dev);
-       int ret;
+       struct attribute_group **groups = net->sysfs_groups;
 
+       class_device_initialize(class_dev);
        class_dev->class = &net_class;
        class_dev->class_data = net;
+       class_dev->groups = groups;
 
+       BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
        strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
-       if ((ret = class_device_register(class_dev)))
-               goto out;
 
-       if (net->get_stats &&
-           (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
-               goto out_unreg; 
+       if (net->get_stats)
+               *groups++ = &netstat_group;
 
 #ifdef WIRELESS_EXT
-       if (net->get_wireless_stats || (net->wireless_handlers &&
-                       net->wireless_handlers->get_wireless_stats)) {
-               ret = sysfs_create_group(&class_dev->kobj, &wireless_group);
-               if (ret)
-                       goto out_cleanup;
-       }
-       return 0;
-out_cleanup:
-       if (net->get_stats)
-               sysfs_remove_group(&class_dev->kobj, &netstat_group);
-#else
-       return 0;
+       if (net->get_wireless_stats
+           || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
+               *groups++ = &wireless_group;
 #endif
 
-out_unreg:
-       printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
-              net->name, ret);
-       class_device_unregister(class_dev);
-out:
-       return ret;
+       return class_device_add(class_dev);
 }
 
 int netdev_sysfs_init(void)
index 1ff7328..2e0ee83 100644 (file)
@@ -848,6 +848,7 @@ static int dccp_close_state(struct sock *sk)
 void dccp_close(struct sock *sk, long timeout)
 {
        struct sk_buff *skb;
+       int state;
 
        lock_sock(sk);
 
@@ -882,6 +883,11 @@ void dccp_close(struct sock *sk, long timeout)
        sk_stream_wait_close(sk, timeout);
 
 adjudge_to_death:
+       state = sk->sk_state;
+       sock_hold(sk);
+       sock_orphan(sk);
+       atomic_inc(sk->sk_prot->orphan_count);
+
        /*
         * It is the last release_sock in its life. It will remove backlog.
         */
@@ -894,8 +900,9 @@ adjudge_to_death:
        bh_lock_sock(sk);
        BUG_TRAP(!sock_owned_by_user(sk));
 
-       sock_hold(sk);
-       sock_orphan(sk);
+       /* Have we already been destroyed by a softirq or backlog? */
+       if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
+               goto out;
 
        /*
         * The last release_sock may have processed the CLOSE or RESET
@@ -915,12 +922,12 @@ adjudge_to_death:
 #endif
        }
 
-       atomic_inc(sk->sk_prot->orphan_count);
        if (sk->sk_state == DCCP_CLOSED)
                inet_csk_destroy_sock(sk);
 
        /* Otherwise, socket is reprieved until protocol close. */
 
+out:
        bh_unlock_sock(sk);
        local_bh_enable();
        sock_put(sk);
index 7c8692c..66e230c 100644 (file)
@@ -493,7 +493,6 @@ struct elist_cb_state {
 static void neigh_elist_cb(struct neighbour *neigh, void *_info)
 {
        struct elist_cb_state *s = _info;
-       struct dn_dev *dn_db;
        struct dn_neigh *dn;
 
        if (neigh->dev != s->dev)
@@ -503,10 +502,6 @@ static void neigh_elist_cb(struct neighbour *neigh, void *_info)
        if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2)))
                return;
 
-       dn_db = (struct dn_dev *) s->dev->dn_ptr;
-       if (dn_db->parms.forwarding == 1 && (dn->flags & DN_NDFLAG_R2))
-               return;
-
        if (s->t == s->n)
                s->rs = dn_find_slot(s->ptr, s->n, dn->priority);
        else
index fb79ce7..57ea9f6 100644 (file)
@@ -51,11 +51,12 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
        spin_lock_irqsave(&mac->lock, flags);
        mac->associnfo.associating = 1;
        mac->associated = 0; /* just to make sure */
-       spin_unlock_irqrestore(&mac->lock, flags);
 
        /* Set a timer for timeout */
        /* FIXME: make timeout configurable */
-       schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
+       if (likely(mac->running))
+               schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
+       spin_unlock_irqrestore(&mac->lock, flags);
 }
 
 void
@@ -319,6 +320,9 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
        u16 status = le16_to_cpup(&resp->status);
        struct ieee80211softmac_network *network = NULL;
        unsigned long flags;
+
+       if (unlikely(!mac->running))
+               return -ENODEV;
        
        spin_lock_irqsave(&mac->lock, flags);
 
@@ -377,10 +381,16 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
        unsigned long flags;
+
+       if (unlikely(!mac->running))
+               return -ENODEV;
+
        if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))
                return 0;
+
        if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))
                return 0;
+
        dprintk(KERN_INFO PFX "got disassoc frame\n");
        netif_carrier_off(dev);
        spin_lock_irqsave(&mac->lock, flags);
@@ -400,6 +410,9 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev,
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
        struct ieee80211softmac_network *network;
 
+       if (unlikely(!mac->running))
+               return -ENODEV;
+
        network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
        if (!network) {
                dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
index 9a0eac6..06e3326 100644 (file)
@@ -86,6 +86,11 @@ ieee80211softmac_auth_queue(void *data)
                
                /* Lock and set flags */
                spin_lock_irqsave(&mac->lock, flags);
+               if (unlikely(!mac->running)) {
+                       /* Prevent reschedule on workqueue flush */
+                       spin_unlock_irqrestore(&mac->lock, flags);
+                       return;
+               }
                net->authenticated = 0;
                net->authenticating = 1;
                /* add a timeout call so we eventually give up waiting for an auth reply */
@@ -124,6 +129,9 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
        unsigned long flags;
        u8 * data;
        
+       if (unlikely(!mac->running))
+               return -ENODEV;
+
        /* Find correct auth queue item */
        spin_lock_irqsave(&mac->lock, flags);
        list_for_each(list_ptr, &mac->auth_queue) {
@@ -298,8 +306,6 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
        
        /* can't transmit data right now... */
        netif_carrier_off(mac->dev);
-       /* let's try to re-associate */
-       schedule_work(&mac->associnfo.work);
        spin_unlock_irqrestore(&mac->lock, flags);
 }
 
@@ -338,6 +344,9 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
        struct ieee80211softmac_network *net = NULL;
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
        
+       if (unlikely(!mac->running))
+               return -ENODEV;
+
        if (!deauth) {
                dprintk("deauth without deauth packet. eek!\n");
                return 0;
@@ -360,5 +369,8 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
        }
 
        ieee80211softmac_deauth_from_net(mac, net);
+
+       /* let's try to re-associate */
+       schedule_work(&mac->associnfo.work);
        return 0;
 }
index be83bdc..6252be2 100644 (file)
@@ -89,6 +89,8 @@ ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
        ieee80211softmac_wait_for_scan(sm);
        
        spin_lock_irqsave(&sm->lock, flags);
+       sm->running = 0;
+
        /* Free all pending assoc work items */
        cancel_delayed_work(&sm->associnfo.work);
        
@@ -204,6 +206,8 @@ void ieee80211softmac_start(struct net_device *dev)
                assert(0);
        if (mac->txrates_change)
                mac->txrates_change(dev, change, &oldrates);
+
+       mac->running = 1;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_start);
 
index 2b9e7ed..d31cf77 100644 (file)
@@ -115,7 +115,15 @@ void ieee80211softmac_scan(void *d)
                        // TODO: is this if correct, or should we do this only if scanning from assoc request?
                        if (sm->associnfo.req_essid.len)
                                ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);
+
+                       spin_lock_irqsave(&sm->lock, flags);
+                       if (unlikely(!sm->running)) {
+                               /* Prevent reschedule on workqueue flush */
+                               spin_unlock_irqrestore(&sm->lock, flags);
+                               break;
+                       }
                        schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
+                       spin_unlock_irqrestore(&sm->lock, flags);
                        return;
                } else {
                        dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);
index 18d7fad..c9026db 100644 (file)
@@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
         *      Initialise the virtual path cache for the packet. It describes
         *      how the packet travels inside Linux networking.
         */ 
-       if (likely(skb->dst == NULL)) {
+       if (skb->dst == NULL) {
                int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
                                         skb->dev);
                if (unlikely(err)) {
index 9bebad0..cbcae65 100644 (file)
@@ -209,7 +209,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
 
 void ip_options_fragment(struct sk_buff * skb) 
 {
-       unsigned char * optptr = skb->nh.raw;
+       unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr);
        struct ip_options * opt = &(IPCB(skb)->opt);
        int  l = opt->optlen;
        int  optlen;
index 2c2fb70..518f581 100644 (file)
@@ -162,6 +162,8 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct,
 
        /* Validate TPKT length */
        tpktlen = tpkt[2] * 256 + tpkt[3];
+       if (tpktlen < 4)
+               goto clear_out;
        if (tpktlen > tcpdatalen) {
                if (tcpdatalen == 4) {  /* Separate TPKT header */
                        /* Netmeeting sends TPKT header and data separately */
index 4807800..355a53a 100644 (file)
@@ -2,7 +2,7 @@
  * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
  *                                  conntrack/NAT module.
  *
- * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com>
+ * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
  *
  * This source code is licensed under General Public License version 2.
  *
@@ -703,6 +703,10 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
                type = get_bits(bs, f->sz);
        }
 
+       /* Write Type */
+       if (base)
+               *(unsigned *) base = type;
+
        /* Check Range */
        if (type >= f->ub) {    /* Newer version? */
                BYTE_ALIGN(bs);
@@ -712,10 +716,6 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
                return H323_ERROR_NONE;
        }
 
-       /* Write Type */
-       if (base)
-               *(unsigned *) base = type;
-
        /* Transfer to son level */
        son = &f->fields[type];
        if (son->attr & STOP) {
index 8f760b2..67e6767 100644 (file)
@@ -219,8 +219,10 @@ ip_nat_out(unsigned int hooknum,
           const struct net_device *out,
           int (*okfn)(struct sk_buff *))
 {
+#ifdef CONFIG_XFRM
        struct ip_conntrack *ct;
        enum ip_conntrack_info ctinfo;
+#endif
        unsigned int ret;
 
        /* root is playing with raw sockets. */
index 6d1c115..cee3397 100644 (file)
@@ -1441,7 +1441,7 @@ static int compat_copy_entry_to_user(struct ipt_entry *e,
        ret = -EFAULT;
        origsize = *size;
        ce = (struct compat_ipt_entry __user *)*dstptr;
-       if (__copy_to_user(ce, e, sizeof(struct ipt_entry)))
+       if (copy_to_user(ce, e, sizeof(struct ipt_entry)))
                goto out;
 
        *dstptr += sizeof(struct compat_ipt_entry);
@@ -1459,9 +1459,9 @@ static int compat_copy_entry_to_user(struct ipt_entry *e,
                goto out;
        ret = -EFAULT;
        next_offset = e->next_offset - (origsize - *size);
-       if (__put_user(target_offset, &ce->target_offset))
+       if (put_user(target_offset, &ce->target_offset))
                goto out;
-       if (__put_user(next_offset, &ce->next_offset))
+       if (put_user(next_offset, &ce->next_offset))
                goto out;
        return 0;
 out:
index 87f68e7..e2b7b80 100644 (file)
@@ -1468,6 +1468,7 @@ void tcp_close(struct sock *sk, long timeout)
 {
        struct sk_buff *skb;
        int data_was_unread = 0;
+       int state;
 
        lock_sock(sk);
        sk->sk_shutdown = SHUTDOWN_MASK;
@@ -1544,6 +1545,11 @@ void tcp_close(struct sock *sk, long timeout)
        sk_stream_wait_close(sk, timeout);
 
 adjudge_to_death:
+       state = sk->sk_state;
+       sock_hold(sk);
+       sock_orphan(sk);
+       atomic_inc(sk->sk_prot->orphan_count);
+
        /* It is the last release_sock in its life. It will remove backlog. */
        release_sock(sk);
 
@@ -1555,8 +1561,9 @@ adjudge_to_death:
        bh_lock_sock(sk);
        BUG_TRAP(!sock_owned_by_user(sk));
 
-       sock_hold(sk);
-       sock_orphan(sk);
+       /* Have we already been destroyed by a softirq or backlog? */
+       if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE)
+               goto out;
 
        /*      This is a (useful) BSD violating of the RFC. There is a
         *      problem with TCP as specified in that the other end could
@@ -1584,7 +1591,6 @@ adjudge_to_death:
                        if (tmo > TCP_TIMEWAIT_LEN) {
                                inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk));
                        } else {
-                               atomic_inc(sk->sk_prot->orphan_count);
                                tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
                                goto out;
                        }
@@ -1603,7 +1609,6 @@ adjudge_to_death:
                        NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY);
                }
        }
-       atomic_inc(sk->sk_prot->orphan_count);
 
        if (sk->sk_state == TCP_CLOSE)
                inet_csk_destroy_sock(sk);
index e0e9d13..b72fa55 100644 (file)
@@ -137,8 +137,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
                if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
                        tp->snd_cwnd_cnt += ca->ai;
                        if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-                               tp->snd_cwnd++;
                                tp->snd_cwnd_cnt -= tp->snd_cwnd;
+                               tp->snd_cwnd++;
                        }
                }
        }
index f8f3a37..eb2865d 100644 (file)
@@ -173,6 +173,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
 
                if (err) {
                        sk->sk_err_soft = -err;
+                       kfree_skb(skb);
                        return err;
                }
 
@@ -181,6 +182,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
 
                if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
                        sk->sk_route_caps = 0;
+                       kfree_skb(skb);
                        return err;
                }
 
index c6d169f..82e665c 100644 (file)
@@ -257,7 +257,6 @@ struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
        /* Unsafe (locking), attrib might change */
        return attrib;
 }
-EXPORT_SYMBOL(irias_find_attrib);
 
 /*
  * Function irias_add_attribute (obj, attrib)
@@ -484,7 +483,6 @@ struct ias_value *irias_new_string_value(char *string)
 
        return value;
 }
-EXPORT_SYMBOL(irias_new_string_value);
 
 /*
  * Function irias_new_octseq_value (octets, len)
@@ -519,7 +517,6 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
        memcpy(value->t.oct_seq, octseq , len);
        return value;
 }
-EXPORT_SYMBOL(irias_new_octseq_value);
 
 struct ias_value *irias_new_missing_value(void)
 {
index 17abf60..99293c6 100644 (file)
@@ -289,7 +289,7 @@ int xt_compat_match(void *match, void **dstptr, int *size, int convert)
                case COMPAT_TO_USER:
                        pm = (struct xt_entry_match *)match;
                        msize = pm->u.user.match_size;
-                       if (__copy_to_user(*dstptr, pm, msize)) {
+                       if (copy_to_user(*dstptr, pm, msize)) {
                                ret = -EFAULT;
                                break;
                        }
@@ -366,7 +366,7 @@ int xt_compat_target(void *target, void **dstptr, int *size, int convert)
                case COMPAT_TO_USER:
                        pt = (struct xt_entry_target *)target;
                        tsize = pt->u.user.target_size;
-                       if (__copy_to_user(*dstptr, pt, tsize)) {
+                       if (copy_to_user(*dstptr, pt, tsize)) {
                                ret = -EFAULT;
                                break;
                        }
index d44981f..3669cb9 100644 (file)
@@ -425,11 +425,16 @@ static int nr_create(struct socket *sock, int protocol)
 
        nr_init_timers(sk);
 
-       nr->t1     = sysctl_netrom_transport_timeout;
-       nr->t2     = sysctl_netrom_transport_acknowledge_delay;
-       nr->n2     = sysctl_netrom_transport_maximum_tries;
-       nr->t4     = sysctl_netrom_transport_busy_delay;
-       nr->idle   = sysctl_netrom_transport_no_activity_timeout;
+       nr->t1     =
+               msecs_to_jiffies(sysctl_netrom_transport_timeout);
+       nr->t2     =
+               msecs_to_jiffies(sysctl_netrom_transport_acknowledge_delay);
+       nr->n2     =
+               msecs_to_jiffies(sysctl_netrom_transport_maximum_tries);
+       nr->t4     =
+               msecs_to_jiffies(sysctl_netrom_transport_busy_delay);
+       nr->idle   =
+               msecs_to_jiffies(sysctl_netrom_transport_no_activity_timeout);
        nr->window = sysctl_netrom_transport_requested_window_size;
 
        nr->bpqext = 1;
@@ -1365,8 +1370,6 @@ static struct notifier_block nr_dev_notifier = {
 
 static struct net_device **dev_nr;
 
-static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
-
 static int __init nr_proto_init(void)
 {
        int i;
@@ -1414,7 +1417,6 @@ static int __init nr_proto_init(void)
        }
                
        register_netdevice_notifier(&nr_dev_notifier);
-       printk(banner);
 
        ax25_protocol_register(AX25_P_NETROM, nr_route_frame);
        ax25_linkfail_register(nr_link_failed);
index 509afdd..621e558 100644 (file)
@@ -185,7 +185,6 @@ static struct net_device_stats *nr_get_stats(struct net_device *dev)
 
 void nr_setup(struct net_device *dev)
 {
-       SET_MODULE_OWNER(dev);
        dev->mtu                = NR_MAX_PACKET_SIZE;
        dev->hard_start_xmit    = nr_xmit;
        dev->open               = nr_open;
index ea65396..55564ef 100644 (file)
@@ -518,11 +518,11 @@ static int rose_create(struct socket *sock, int protocol)
        init_timer(&rose->timer);
        init_timer(&rose->idletimer);
 
-       rose->t1   = sysctl_rose_call_request_timeout;
-       rose->t2   = sysctl_rose_reset_request_timeout;
-       rose->t3   = sysctl_rose_clear_request_timeout;
-       rose->hb   = sysctl_rose_ack_hold_back_timeout;
-       rose->idle = sysctl_rose_no_activity_timeout;
+       rose->t1   = msecs_to_jiffies(sysctl_rose_call_request_timeout);
+       rose->t2   = msecs_to_jiffies(sysctl_rose_reset_request_timeout);
+       rose->t3   = msecs_to_jiffies(sysctl_rose_clear_request_timeout);
+       rose->hb   = msecs_to_jiffies(sysctl_rose_ack_hold_back_timeout);
+       rose->idle = msecs_to_jiffies(sysctl_rose_no_activity_timeout);
 
        rose->state = ROSE_STATE_0;
 
@@ -1469,8 +1469,6 @@ static struct notifier_block rose_dev_notifier = {
 
 static struct net_device **dev_rose;
 
-static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n";
-
 static int __init rose_proto_init(void)
 {
        int i;
@@ -1519,7 +1517,6 @@ static int __init rose_proto_init(void)
 
        sock_register(&rose_family_ops);
        register_netdevice_notifier(&rose_dev_notifier);
-       printk(banner);
 
        ax25_protocol_register(AX25_P_ROSE, rose_route_frame);
        ax25_linkfail_register(rose_link_failed);
index d297af7..2a1bf8e 100644 (file)
@@ -135,7 +135,6 @@ static struct net_device_stats *rose_get_stats(struct net_device *dev)
 
 void rose_setup(struct net_device *dev)
 {
-       SET_MODULE_OWNER(dev);
        dev->mtu                = ROSE_MAX_PACKET_SIZE - 2;
        dev->hard_start_xmit    = rose_xmit;
        dev->open               = rose_open;
index 09e9e9d..bd86a63 100644 (file)
@@ -40,7 +40,8 @@ void rose_start_ftimer(struct rose_neigh *neigh)
 
        neigh->ftimer.data     = (unsigned long)neigh;
        neigh->ftimer.function = &rose_ftimer_expiry;
-       neigh->ftimer.expires  = jiffies + sysctl_rose_link_fail_timeout;
+       neigh->ftimer.expires  =
+               jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout);
 
        add_timer(&neigh->ftimer);
 }
@@ -51,7 +52,8 @@ static void rose_start_t0timer(struct rose_neigh *neigh)
 
        neigh->t0timer.data     = (unsigned long)neigh;
        neigh->t0timer.function = &rose_t0timer_expiry;
-       neigh->t0timer.expires  = jiffies + sysctl_rose_restart_request_timeout;
+       neigh->t0timer.expires  =
+               jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout);
 
        add_timer(&neigh->t0timer);
 }
index 8631b65..a22542f 100644 (file)
@@ -48,8 +48,6 @@ static DEFINE_SPINLOCK(rose_route_list_lock);
 
 struct rose_neigh *rose_loopback_neigh;
 
-static void rose_remove_neigh(struct rose_neigh *);
-
 /*
  *     Add a new route to a node, and in the process add the node and the
  *     neighbour if it is new.
@@ -235,11 +233,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
 
        skb_queue_purge(&rose_neigh->queue);
 
-       spin_lock_bh(&rose_neigh_list_lock);
-
        if ((s = rose_neigh_list) == rose_neigh) {
                rose_neigh_list = rose_neigh->next;
-               spin_unlock_bh(&rose_neigh_list_lock);
                kfree(rose_neigh->digipeat);
                kfree(rose_neigh);
                return;
@@ -248,7 +243,6 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
        while (s != NULL && s->next != NULL) {
                if (s->next == rose_neigh) {
                        s->next = rose_neigh->next;
-                       spin_unlock_bh(&rose_neigh_list_lock);
                        kfree(rose_neigh->digipeat);
                        kfree(rose_neigh);
                        return;
@@ -256,7 +250,6 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
 
                s = s->next;
        }
-       spin_unlock_bh(&rose_neigh_list_lock);
 }
 
 /*
index 91132f6..f1c7bd2 100644 (file)
@@ -974,10 +974,10 @@ hfsc_adjust_levels(struct hfsc_class *cl)
        do {
                level = 0;
                list_for_each_entry(p, &cl->children, siblings) {
-                       if (p->level > level)
-                               level = p->level;
+                       if (p->level >= level)
+                               level = p->level + 1;
                }
-               cl->level = level + 1;
+               cl->level = level;
        } while ((cl = cl->cl_parent) != NULL);
 }
 
index 297b895..cf0c767 100644 (file)
@@ -149,6 +149,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
                /* This is the first chunk in the packet.  */
                chunk->singleton = 1;
                ch = (sctp_chunkhdr_t *) chunk->skb->data;
+               chunk->data_accepted = 0;
        }
 
         chunk->chunk_hdr = ch;
index 2b9a832..8cdba51 100644 (file)
@@ -636,8 +636,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
         */
         chunk->subh.cookie_hdr =
                (struct sctp_signed_cookie *)chunk->skb->data;
-       skb_pull(chunk->skb,
-                ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
+       if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+                                        sizeof(sctp_chunkhdr_t)))
+               goto nomem;
 
        /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
         * "Z" will reply with a COOKIE ACK chunk after building a TCB
@@ -965,7 +966,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
         */
        chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
        paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
-       skb_pull(chunk->skb, paylen);
+       if (!pskb_pull(chunk->skb, paylen))
+               goto nomem;
 
        reply = sctp_make_heartbeat_ack(asoc, chunk,
                                        chunk->subh.hb_hdr, paylen);
@@ -1860,8 +1862,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
         * are in good shape.
         */
         chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
-       skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
-                sizeof(sctp_chunkhdr_t));
+       if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+                                       sizeof(sctp_chunkhdr_t)))
+               goto nomem;
 
        /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
         * of a duplicate COOKIE ECHO match the Verification Tags of the
@@ -5151,7 +5154,9 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        int tmp;
        __u32 tsn;
        int account_value;
+       struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
        struct sock *sk = asoc->base.sk;
+       int rcvbuf_over = 0;
 
        data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
        skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
@@ -5162,10 +5167,16 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        /* ASSERT:  Now skb->data is really the user data.  */
 
        /*
-        * if we are established, and we have used up our receive
-        * buffer memory, drop the frame
-        */
-       if (asoc->state == SCTP_STATE_ESTABLISHED) {
+        * If we are established, and we have used up our receive buffer
+        * memory, think about droping the frame.
+        * Note that we have an opportunity to improve performance here.
+        * If we accept one chunk from an skbuff, we have to keep all the
+        * memory of that skbuff around until the chunk is read into user
+        * space. Therefore, once we accept 1 chunk we may as well accept all
+        * remaining chunks in the skbuff. The data_accepted flag helps us do
+        * that.
+        */
+       if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) {
                /*
                 * If the receive buffer policy is 1, then each
                 * association can allocate up to sk_rcvbuf bytes
@@ -5176,9 +5187,25 @@ static int sctp_eat_data(const struct sctp_association *asoc,
                        account_value = atomic_read(&asoc->rmem_alloc);
                else
                        account_value = atomic_read(&sk->sk_rmem_alloc);
-
-               if (account_value > sk->sk_rcvbuf)
-                       return SCTP_IERROR_IGNORE_TSN;
+               if (account_value > sk->sk_rcvbuf) {
+                       /*
+                        * We need to make forward progress, even when we are
+                        * under memory pressure, so we always allow the
+                        * next tsn after the ctsn ack point to be accepted.
+                        * This lets us avoid deadlocks in which we have to
+                        * drop frames that would otherwise let us drain the
+                        * receive queue.
+                        */
+                       if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn)
+                               return SCTP_IERROR_IGNORE_TSN;
+
+                       /*
+                        * We're going to accept the frame but we should renege
+                        * to make space for it. This will send us down that
+                        * path later in this function.
+                        */
+                       rcvbuf_over = 1;
+               }
        }
 
        /* Process ECN based congestion.
@@ -5226,6 +5253,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        datalen -= sizeof(sctp_data_chunk_t);
 
        deliver = SCTP_CMD_CHUNK_ULP;
+       chunk->data_accepted = 1;
 
        /* Think about partial delivery. */
        if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
@@ -5242,7 +5270,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
         * large spill over.
         */
        if (!asoc->rwnd || asoc->rwnd_over ||
-           (datalen > asoc->rwnd + asoc->frag_point)) {
+           (datalen > asoc->rwnd + asoc->frag_point) ||
+           rcvbuf_over) {
 
                /* If this is the next TSN, consider reneging to make
                 * room.   Note: Playing nice with a confused sender.  A
@@ -5250,8 +5279,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
                 * space and in the future we may want to detect and
                 * do more drastic reneging.
                 */
-               if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
-                   (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
+               if (sctp_tsnmap_has_gap(map) &&
+                   (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
                        SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
                        deliver = SCTP_CMD_RENEGE;
                } else {
index 75ef104..8bcca56 100644 (file)
@@ -366,9 +366,9 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
        /* SCTP_STATE_EMPTY */ \
        {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
        /* SCTP_STATE_CLOSED */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
        /* SCTP_STATE_COOKIE_WAIT */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
        /* SCTP_STATE_COOKIE_ECHOED */ \
        {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
        /* SCTP_STATE_ESTABLISHED */ \
@@ -380,7 +380,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
        {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_ECN_ECNE */
 
 #define TYPE_SCTP_ECN_CWR { \
@@ -401,7 +401,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
        {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_ECN_CWR */
 
 #define TYPE_SCTP_SHUTDOWN_COMPLETE { \
@@ -647,7 +647,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
        /* SCTP_STATE_EMPTY */ \
        {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
        /* SCTP_STATE_CLOSED */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
        /* SCTP_STATE_COOKIE_WAIT */ \
        {.fn = sctp_sf_do_prm_requestheartbeat,               \
         .name = "sctp_sf_do_prm_requestheartbeat"},          \
index 2080b2d..575e556 100644 (file)
@@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
 static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag)
 {
        struct sk_buff *pos;
+       struct sk_buff *new = NULL;
        struct sctp_ulpevent *event;
        struct sk_buff *pnext, *last;
        struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
@@ -297,11 +298,33 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu
         */
        if (last)
                last->next = pos;
-       else
-               skb_shinfo(f_frag)->frag_list = pos;
+       else {
+               if (skb_cloned(f_frag)) {
+                       /* This is a cloned skb, we can't just modify
+                        * the frag_list.  We need a new skb to do that.
+                        * Instead of calling skb_unshare(), we'll do it
+                        * ourselves since we need to delay the free.
+                        */
+                       new = skb_copy(f_frag, GFP_ATOMIC);
+                       if (!new)
+                               return NULL;    /* try again later */
+
+                       new->sk = f_frag->sk;
+
+                       skb_shinfo(new)->frag_list = pos;
+               } else
+                       skb_shinfo(f_frag)->frag_list = pos;
+       }
 
        /* Remove the first fragment from the reassembly queue.  */
        __skb_unlink(f_frag, queue);
+
+       /* if we did unshare, then free the old skb and re-assign */
+       if (new) {
+               kfree_skb(f_frag);
+               f_frag = new;
+       }
+
        while (pos) {
 
                pnext = pos->next;
index 56b3bed..331c079 100644 (file)
@@ -200,7 +200,11 @@ input_file() {
                        print_mtime "$1" >> ${output}
                        cat "$1"         >> ${output}
                else
-                       grep ^file "$1" | cut -d ' ' -f 3
+                       cat "$1" | while read type dir file perm ; do
+                               if [ "$type" == "file" ]; then
+                                       echo "$file \\";
+                               fi
+                       done
                fi
        elif [ -d "$1" ]; then
                dir_filelist "$1"
index a22cbed..7f9d544 100644 (file)
 # $4 - patchlevel
 
 
-cat << EOF
+test ! -r $2/Makefile -o -O $2/Makefile || exit 0
+echo "  GEN     $2/Makefile"
+
+cat << EOF > $2/Makefile
 # Automatically generated by $0: don't edit
 
 VERSION = $3
index cd00e9f..6d04504 100644 (file)
@@ -487,14 +487,14 @@ static int strrcmp(const char *s, const char *sub)
  *   atsym   =__param*
  *
  * Pattern 2:
- *   Many drivers utilise a *_driver container with references to
+ *   Many drivers utilise a *driver container with references to
  *   add, remove, probe functions etc.
  *   These functions may often be marked __init and we do not want to
  *   warn here.
  *   the pattern is identified by:
  *   tosec   = .init.text | .exit.text | .init.data
  *   fromsec = .data
- *   atsym = *_driver, *_template, *_sht, *_ops, *_probe, *probe_one
+ *   atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
  **/
 static int secref_whitelist(const char *tosec, const char *fromsec,
                            const char *atsym)
@@ -502,7 +502,7 @@ static int secref_whitelist(const char *tosec, const char *fromsec,
        int f1 = 1, f2 = 1;
        const char **s;
        const char *pat2sym[] = {
-               "_driver",
+               "driver",
                "_template", /* scsi uses *_template a lot */
                "_sht",      /* scsi also used *_sht to some extent */
                "_ops",
index 3cf368a..d987048 100644 (file)
@@ -101,6 +101,8 @@ static int __init selinux_enabled_setup(char *str)
        return 1;
 }
 __setup("selinux=", selinux_enabled_setup);
+#else
+int selinux_enabled = 1;
 #endif
 
 /* Original (dummy) security module. */
@@ -4535,6 +4537,7 @@ int selinux_disable(void)
        printk(KERN_INFO "SELinux:  Disabled at runtime.\n");
 
        selinux_disabled = 1;
+       selinux_enabled = 0;
 
        /* Reset security_ops to the secondary module, dummy or capability. */
        security_ops = secondary_ops;
index 5f016c9..063af47 100644 (file)
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #define POLICYDB_VERSION_MAX   POLICYDB_VERSION_AVTAB
 
-#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
 extern int selinux_enabled;
-#else
-#define selinux_enabled 1
-#endif
-
 extern int selinux_mls_enabled;
 
 int security_load_policy(void * data, size_t len);
index 7177e98..c284dbb 100644 (file)
@@ -594,6 +594,10 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
 
                        *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
                        scontextp = kmalloc(*scontext_len,GFP_ATOMIC);
+                       if (!scontextp) {
+                               rc = -ENOMEM;
+                               goto out;
+                       }
                        strcpy(scontextp, initial_sid_to_string[sid]);
                        *scontext = scontextp;
                        goto out;